3#include <CesiumUtility/Library.h>
5#include <glm/gtc/epsilon.hpp>
12class 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;
95 static constexpr double PiOverFour = OnePi / 4.0;
110 template <glm::length_t L,
typename T, glm::qualifier Q>
112 const glm::vec<L, T, Q>& a,
113 const glm::vec<L, T, Q>& b,
114 double relativeEpsilon)
noexcept {
115 return relativeEpsilon * glm::max(glm::abs(a), glm::abs(b));
130 double relativeEpsilon)
noexcept {
131 return relativeEpsilon * glm::max(glm::abs(a), glm::abs(b));
146 template <glm::length_t L,
typename T, glm::qualifier Q>
148 const glm::vec<L, T, Q>& left,
149 const glm::vec<L, T, Q>& right,
150 double relativeEpsilon)
noexcept {
151 return Math::equalsEpsilon(left, right, relativeEpsilon, relativeEpsilon);
162 static constexpr bool
164 return equalsEpsilon(left, right, relativeEpsilon, relativeEpsilon);
191 double relativeEpsilon,
192 double absoluteEpsilon)
noexcept {
193 const double diff = glm::abs(left - right);
194 return diff <= absoluteEpsilon ||
195 diff <= relativeEpsilonToAbsolute(left, right, relativeEpsilon);
221 template <glm::length_t L,
typename T, glm::qualifier Q>
223 const glm::vec<L, T, Q>& left,
224 const glm::vec<L, T, Q>& right,
225 double relativeEpsilon,
226 double absoluteEpsilon)
noexcept {
227 const glm::vec<L, T, Q> diff = glm::abs(left - right);
228 return glm::lessThanEqual(diff, glm::vec<L, T, Q>(absoluteEpsilon)) ==
229 glm::vec<L, bool, Q>(
true) ||
232 relativeEpsilonToAbsolute(left, right, relativeEpsilon)) ==
233 glm::vec<L, bool, Q>(
true);
245 static constexpr double sign(
double value)
noexcept {
246 if (value == 0.0 || value != value) {
250 return value > 0 ? 1 : -1;
264 return value < 0.0 ? -1.0 : 1.0;
275 if (angle >= -Math::OnePi && angle <= Math::OnePi) {
280 return Math::zeroToTwoPi(angle + Math::OnePi) - Math::OnePi;
291 if (angle >= 0 && angle <= Math::TwoPi) {
296 const double mod = Math::mod(angle, Math::TwoPi);
297 if (glm::abs(mod) < Math::Epsilon14 && glm::abs(angle) > Math::Epsilon14) {
310 static double mod(
double m,
double n)
noexcept {
311 if (Math::sign(m) == Math::sign(n) && glm::abs(m) < glm::abs(n)) {
316 return fmod(fmod(m, n) + n, n);
326 return angleDegrees * Math::OnePi / 180.0;
336 return angleRadians * 180.0 / Math::OnePi;
349 static double lerp(
double p,
double q,
double time)
noexcept {
350 return glm::mix(p, q, time);
361 static constexpr double clamp(
double value,
double min,
double max)
noexcept {
362 return glm::clamp(value, min, max);
375 static double toSNorm(
double value,
double rangeMaximum = 255.0) noexcept {
377 (Math::clamp(value, -1.0, 1.0) * 0.5 + 0.5) * rangeMaximum);
389 static constexpr double
390 fromSNorm(
double value,
double rangeMaximum = 255.0) noexcept {
391 return (Math::clamp(value, 0.0, rangeMaximum) / rangeMaximum) * 2.0 - 1.0;
406 constexpr double twoPi = Math::TwoPi;
408 const double simplified = angle - glm::floor(angle / twoPi) * twoPi;
410 if (simplified < -Math::OnePi) {
411 return simplified + twoPi;
413 if (simplified >= Math::OnePi) {
414 return simplified - twoPi;
430 static double roundUp(
double value,
double tolerance)
noexcept {
431 const double up = glm::ceil(value);
432 const double down = glm::floor(value);
433 if (value - down < tolerance) {
450 static double roundDown(
double value,
double tolerance)
noexcept {
451 const double up = glm::ceil(value);
452 const double down = glm::floor(value);
453 if (up - value < tolerance) {
Mathematical constants and functions.
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 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 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 bool constexpr 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 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 double negativePiToPi(double angle) noexcept
Produces an angle in the range -Pi <= angle <= Pi which is equivalent to the provided angle.
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 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 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.