5 #include <glm/gtc/epsilon.hpp>
12 class CESIUMUTILITY_API
Math final {
15 static constexpr
double Epsilon1 = 1e-1;
18 static constexpr
double Epsilon2 = 1e-2;
21 static constexpr
double Epsilon3 = 1e-3;
24 static constexpr
double Epsilon4 = 1e-4;
27 static constexpr
double Epsilon5 = 1e-5;
30 static constexpr
double Epsilon6 = 1e-6;
33 static constexpr
double Epsilon7 = 1e-7;
36 static constexpr
double Epsilon8 = 1e-8;
39 static constexpr
double Epsilon9 = 1e-9;
42 static constexpr
double Epsilon10 = 1e-10;
45 static constexpr
double Epsilon11 = 1e-11;
48 static constexpr
double Epsilon12 = 1e-12;
51 static constexpr
double Epsilon13 = 1e-13;
54 static constexpr
double Epsilon14 = 1e-14;
57 static constexpr
double Epsilon15 = 1e-15;
60 static constexpr
double Epsilon16 = 1e-16;
63 static constexpr
double Epsilon17 = 1e-17;
66 static constexpr
double Epsilon18 = 1e-18;
69 static constexpr
double Epsilon19 = 1e-19;
72 static constexpr
double Epsilon20 = 1e-20;
75 static constexpr
double Epsilon21 = 1e-21;
80 static constexpr
double OnePi = 3.14159265358979323846;
85 static constexpr
double TwoPi = OnePi * 2.0;
90 static constexpr
double PiOverTwo = OnePi / 2.0;
105 template <glm::length_t L,
typename T, glm::qualifier Q>
107 const glm::vec<L, T, Q>& a,
108 const glm::vec<L, T, Q>& b,
109 double relativeEpsilon) noexcept {
110 return relativeEpsilon * glm::max(glm::abs(a), glm::abs(b));
125 double relativeEpsilon) noexcept {
126 return relativeEpsilon * glm::max(glm::abs(a), glm::abs(b));
141 template <glm::length_t L,
typename T, glm::qualifier Q>
143 const glm::vec<L, T, Q>& left,
144 const glm::vec<L, T, Q>& right,
145 double relativeEpsilon) noexcept {
157 static constexpr
bool
159 return equalsEpsilon(left, right, relativeEpsilon, relativeEpsilon);
186 double relativeEpsilon,
187 double absoluteEpsilon) noexcept {
188 const double diff = glm::abs(left - right);
189 return diff <= absoluteEpsilon ||
190 diff <= relativeEpsilonToAbsolute(left, right, relativeEpsilon);
216 template <glm::length_t L,
typename T, glm::qualifier Q>
218 const glm::vec<L, T, Q>& left,
219 const glm::vec<L, T, Q>& right,
220 double relativeEpsilon,
221 double absoluteEpsilon) noexcept {
222 const glm::vec<L, T, Q> diff = glm::abs(left - right);
223 return glm::lessThanEqual(diff, glm::vec<L, T, Q>(absoluteEpsilon)) ==
224 glm::vec<L, bool, Q>(
true) ||
227 relativeEpsilonToAbsolute(left, right, relativeEpsilon)) ==
228 glm::vec<L, bool, Q>(
true);
240 static constexpr
double sign(
double value) noexcept {
241 if (value == 0.0 || value != value) {
245 return value > 0 ? 1 : -1;
259 return value < 0.0 ? -1.0 : 1.0;
305 static double mod(
double m,
double n) noexcept {
311 return fmod(fmod(m, n) + n, n);
344 static double lerp(
double p,
double q,
double time) noexcept {
345 return glm::mix(p, q, time);
356 static constexpr
double clamp(
double value,
double min,
double max) noexcept {
357 return glm::clamp(value, min, max);
370 static double toSNorm(
double value,
double rangeMaximum = 255.0) noexcept {
372 (
Math::clamp(value, -1.0, 1.0) * 0.5 + 0.5) * rangeMaximum);
384 static constexpr
double
385 fromSNorm(
double value,
double rangeMaximum = 255.0) noexcept {
386 return (
Math::clamp(value, 0.0, rangeMaximum) / rangeMaximum) * 2.0 - 1.0;
403 const double simplified = angle - glm::floor(angle / twoPi) * twoPi;
406 return simplified + twoPi;
409 return simplified - twoPi;
425 static double roundUp(
double value,
double tolerance) noexcept {
426 const double up = glm::ceil(value);
427 const double down = glm::floor(value);
428 if (value - down < tolerance) {
445 static double roundDown(
double value,
double tolerance) noexcept {
446 const double up = glm::ceil(value);
447 const double down = glm::floor(value);
448 if (up - value < tolerance) {
460 template <
typename T, glm::qualifier Q>
461 static glm::vec<3, T, Q>
perpVec(
const glm::vec<3, T, Q>& v) {
464 if (std::abs(v.x) > std::abs(v.y)) {
465 return glm::vec<3, T, Q>(-v.z, 0, v.x) / std::sqrt(v.x * v.x + v.z * v.z);
467 return glm::vec<3, T, Q>(0, v.z, -v.y) / std::sqrt(v.y * v.y + v.z * v.z);
475 template <
typename T, glm::qualifier Q>
476 static glm::qua<T, Q>
477 rotation(
const glm::vec<3, T, Q>& vec1,
const glm::vec<3, T, Q>& vec2) {
483 auto cosRot = dot(vec1, vec2);
484 auto rotAxis = cross(vec1, vec2);
485 auto rotAxisLen2 = dot(rotAxis, rotAxis);
488 if (cosRot >= 1 || (rotAxisLen2 == 0 && cosRot > 0)) {
490 return glm::qua<T, Q>(1, 0, 0, 0);
492 if (cosRot <= -1 || (rotAxisLen2 == 0 && cosRot < 0)) {
495 return glm::qua<T, Q>(0, perpAxis);
498 glm::qua<T, Q> sumQuat(cosRot + 1, rotAxis);
499 return normalize(sumQuat);
Mathematical constants and functions.
static constexpr double Epsilon14
0.00000000000001
static double mod(double m, double n) noexcept
The modulo operation that also works for negative dividends.
static constexpr double radiansToDegrees(double angleRadians) noexcept
Converts radians to degrees.
static constexpr double degreesToRadians(double angleDegrees) noexcept
Converts degrees to radians.
static constexpr bool equalsEpsilon(const glm::vec< L, T, Q > &left, const glm::vec< L, T, Q > &right, double relativeEpsilon, double absoluteEpsilon) noexcept
Determines if two values are equal using an absolute or relative tolerance test.
static constexpr bool equalsEpsilon(double left, double right, double relativeEpsilon, double absoluteEpsilon) noexcept
Determines if two values are equal using an absolute or relative tolerance test.
static double toSNorm(double value, double rangeMaximum=255.0) noexcept
Converts a scalar value in the range [-1.0, 1.0] to a SNORM in the range [0, rangeMaximum].
static constexpr double sign(double value) noexcept
Returns the sign of the value.
static constexpr double TwoPi
two times pi
static constexpr double OnePi
pi
static double roundUp(double value, double tolerance) noexcept
Rounds a value up to the nearest integer, like ceil, except that if the value is very close to the lo...
static glm::qua< T, Q > rotation(const glm::vec< 3, T, Q > &vec1, const glm::vec< 3, T, Q > &vec2)
Compute the rotation between two unit vectors.
static double negativePiToPi(double angle) noexcept
Produces an angle in the range -Pi <= angle <= Pi which is equivalent to the provided angle.
static constexpr bool equalsEpsilon(const glm::vec< L, T, Q > &left, const glm::vec< L, T, Q > &right, double relativeEpsilon) noexcept
Checks whether two values are equal up to a given relative epsilon.
static double zeroToTwoPi(double angle) noexcept
Produces an angle in the range 0 <= angle <= 2Pi which is equivalent to the provided angle.
static constexpr bool equalsEpsilon(double left, double right, double relativeEpsilon) noexcept
Checks whether two values are equal up to a given relative epsilon.
static constexpr glm::vec< L, T, Q > relativeEpsilonToAbsolute(const glm::vec< L, T, Q > &a, const glm::vec< L, T, Q > &b, double relativeEpsilon) noexcept
Converts a relative to an absolute epsilon, for the epsilon-equality check between two values.
static double roundDown(double value, double tolerance) noexcept
Rounds a value down to the nearest integer, like floor, except that if the value is very close to the...
static constexpr double clamp(double value, double min, double max) noexcept
Constrain a value to lie between two values.
static double lerp(double p, double q, double time) noexcept
Computes the linear interpolation of two values.
static double convertLongitudeRange(double angle) noexcept
static constexpr double signNotZero(double value) noexcept
Returns 1.0 if the given value is positive or zero, and -1.0 if it is negative.
static constexpr double relativeEpsilonToAbsolute(double a, double b, double relativeEpsilon) noexcept
Converts a relative to an absolute epsilon, for the epsilon-equality check between two values.
static glm::vec< 3, T, Q > perpVec(const glm::vec< 3, T, Q > &v)
Construct a vector perpendicular to the argument.
static constexpr double fromSNorm(double value, double rangeMaximum=255.0) noexcept
Converts a SNORM value in the range [0, rangeMaximum] to a scalar in the range [-1....
Utility classes for Cesium.