A C++17 custom math library that includes vector calculations, length, random numbers, etc.
Add to include directories path to the include/QuickMaffs
directory,
and include the Everything.hpp file:
#include <QuickMaffs/Everything.hpp>
This is header only library, until QUICKMAFFS_HEADER_ONLY
is removed from definitions
from the Everything.hpp file. If you
rely on this library, you should create a guard, as described here:
Example:
#include <QuickMaffs/Everything.hpp>
#ifndef QUICKMAFFS_HEADER_ONLY
#error "QuickMaffs needs to be compiled separately! When QuickMaffs is properly linked, remove this error."
#endif
namespace math = quickmaffs; // alias the namespace not to use the long one.
For your comfort, use alias to quickmaffs
namespace. This is very handy if you
use it as your main math library:
namespace math = quickmaffs;
Use generate
method in namespace random
:
auto randomInteger = math::random::generate(100, 200);
auto randomFloat = math::random::generate(0.f, 1.f);
auto randomDouble = math::random::generate(0.0, 10.0);
Vectors are commonly used to describe points, size, displacement or force in space. QuickMaffs' implementation of vectors provides you a lot of popular operations, such as:
- normalization
- computing length and length2
- computing distance and distance2
- addition, subtraction, multiplication and division
vector
operatorvector
vector
operatorscalar
scalar
operator (only*
and+
)vector
- computing dot product
- computing cross product
QuickMaffs defines following vector templates:
Vector2
Vector3
There are also following aliases created:
Vector2f
equalsVector2<float>
Vector2d
equalsVector2<double>
Vector2ld
equalsVector2<long double>
Vector2i8
equalsVector2<std::int8_t>
Vector2i16
equalsVector2<std::int16_t>
Vector2i32
equalsVector2<std::int32_t>
Vector2i64
equalsVector2<std::int64_t>
Vector2u8
equalsVector2<std::uint8_t>
Vector2u16
equalsVector2<std::uint16_t>
Vector2u32
equalsVector2<std::uint32_t>
Vector2u64
equalsVector2<std::uint64_t>
Vector2size
equalsVector2<std::size_t>
This also applies to Vector3
template.
Vector2
has x
, y
components and Vector3
adds another one - z
.
Default constructor initializes these components to zero. You can also set it
by yourself.
// Two following lines are equal:
math::Vector2f vec2_a;
math::Vector2f vec2_b{ 0.f, 0.f };
// Two following lines are equal:
math::Vector3f vec3_a;
math::Vector3f vec3_b{ 0.f, 0.f, 0.f };
// Later, you can set value, either by assigning new vector:
vec2_a = { 30.f, 20.5f };
// ... or by using `set` method:
vec2_a.set( 30.f, 20.5f );
// Same for Vector3, but with third parameter.
Vectors do not like to change its components' type without you knowing about that.
You cannot multiply Vector3i32
with float
scalar. You need to explicitly convert
it, using convert
template method:
Vector3i32 vec3 = { 200, 50, 10 };
// Vector3f vec3f = 5.f * vec3; // error! multiplication: float with Vector3i32
Vector3f vec3f = 5.f * vec3.convert<float>(); // Ok
Vector
N
::toString
Vector
N
::nearlyEqual
Vector
N
::absolute
Vector
N
::normalize
Vector
N
::normalizeSelf
(modifies self)Vector
N
::reflect
Vector
N
::reflectSelf
(modifies self)Vector
N
::length
Vector
N
::lengthSquared
Vector
N
::distance
Vector
N
::distanceSquared
Vector
N
::dot
Vector
N
::cross
static
Vector
N
::lowerBounds
static
Vector
N
::upperBounds
static
Vector
N
::bounds
Method that look like this:
// Only as example:
struct Car {
float getTopSpeed() const {
return 220.f; // mph? kmph? per hour? per second?
}
};
does not really express programmer's intention. It should look like this:
Kilometers getTopSpeed() const {
return 220.f; // per hour? per second?
}
or more perfectly, like this:
Kilometers getTopSpeedPerHour() const {
return 220.f;
}
You can easily manipulate length units using Length<Type, Ratio>
template:
src: Length.hpp
There are aliases defined for:
Nanometers
equal toLength<double, std::nano>
equal to0.000'000'001m
Micrometers
equal toLength<double, std::micro>
equal to0.000'001m
Millimeters
equal toLength<double, std::milli>
equal to0.001m
Centimeters
equal toLength<double, std::centi>
equal to0.01m
Decimeters
equal toLength<double, std::deci>
equal to0.1m
Meters
equal toLength<double>
equal to1m
Decameters
equal toLength<double, std::deca>
equal to10m
Hectometers
equal toLength<double, std::hecto>
equal to100m
Kilometers
equal toLength<double, std::kilo>
equal to1'000m
Megameters
equal toLength<double, std::mega>
equal to1'000'000m
Gigameters
equal toLength<double, std::giga>
equal to1'000'000'000m
Miles
equal toLength<double, std::ratio<1609, 1>>;
equal to1609m
Yards
equal toLength<double, std::ratio<9144, 10000>>
equal to0.9144m
LightYears
equal toLength<double, std::ratio<9460730472580800>>
equal to9460730472580800m
Example usage:
math::Yards yards = 500;
math::Meters meters = yards; // unlike in vectors, here conversion is implicit
std::cout << std::fixed << yards.value << " yards is equal to " << meters.value << " meters." << std::endl;