cesium-native 0.44.2
Loading...
Searching...
No Matches
Math.h
1#pragma once
2
3#include <CesiumUtility/Library.h>
4
5#include <glm/gtc/epsilon.hpp>
6
7namespace CesiumUtility {
8
12class CESIUMUTILITY_API Math final {
13public:
15 static constexpr double Epsilon1 = 1e-1;
16
18 static constexpr double Epsilon2 = 1e-2;
19
21 static constexpr double Epsilon3 = 1e-3;
22
24 static constexpr double Epsilon4 = 1e-4;
25
27 static constexpr double Epsilon5 = 1e-5;
28
30 static constexpr double Epsilon6 = 1e-6;
31
33 static constexpr double Epsilon7 = 1e-7;
34
36 static constexpr double Epsilon8 = 1e-8;
37
39 static constexpr double Epsilon9 = 1e-9;
40
42 static constexpr double Epsilon10 = 1e-10;
43
45 static constexpr double Epsilon11 = 1e-11;
46
48 static constexpr double Epsilon12 = 1e-12;
49
51 static constexpr double Epsilon13 = 1e-13;
52
54 static constexpr double Epsilon14 = 1e-14;
55
57 static constexpr double Epsilon15 = 1e-15;
58
60 static constexpr double Epsilon16 = 1e-16;
61
63 static constexpr double Epsilon17 = 1e-17;
64
66 static constexpr double Epsilon18 = 1e-18;
67
69 static constexpr double Epsilon19 = 1e-19;
70
72 static constexpr double Epsilon20 = 1e-20;
73
75 static constexpr double Epsilon21 = 1e-21;
76
80 static constexpr double OnePi = 3.14159265358979323846;
81
85 static constexpr double TwoPi = OnePi * 2.0;
86
90 static constexpr double PiOverTwo = OnePi / 2.0;
91
95 static constexpr double PiOverFour = OnePi / 4.0;
96
110 template <glm::length_t L, typename T, glm::qualifier Q>
111 static constexpr glm::vec<L, T, Q> relativeEpsilonToAbsolute(
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));
116 }
117
127 static constexpr double relativeEpsilonToAbsolute(
128 double a,
129 double b,
130 double relativeEpsilon) noexcept {
131 return relativeEpsilon * glm::max(glm::abs(a), glm::abs(b));
132 }
133
146 template <glm::length_t L, typename T, glm::qualifier Q>
147 static bool constexpr equalsEpsilon(
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);
152 }
153
162 static constexpr bool
163 equalsEpsilon(double left, double right, double relativeEpsilon) noexcept {
164 return equalsEpsilon(left, right, relativeEpsilon, relativeEpsilon);
165 }
166
188 static constexpr bool equalsEpsilon(
189 double left,
190 double right,
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);
196 }
197
221 template <glm::length_t L, typename T, glm::qualifier Q>
222 static constexpr bool equalsEpsilon(
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) ||
230 glm::lessThanEqual(
231 diff,
232 relativeEpsilonToAbsolute(left, right, relativeEpsilon)) ==
233 glm::vec<L, bool, Q>(true);
234 }
235
245 static constexpr double sign(double value) noexcept {
246 if (value == 0.0 || value != value) {
247 // zero or NaN
248 return value;
249 }
250 return value > 0 ? 1 : -1;
251 }
252
263 static constexpr double signNotZero(double value) noexcept {
264 return value < 0.0 ? -1.0 : 1.0;
265 }
266
274 static double negativePiToPi(double angle) noexcept {
275 if (angle >= -Math::OnePi && angle <= Math::OnePi) {
276 // Early exit if the input is already inside the range. This avoids
277 // unnecessary math which could introduce floating point error.
278 return angle;
279 }
280 return Math::zeroToTwoPi(angle + Math::OnePi) - Math::OnePi;
281 }
282
290 static double zeroToTwoPi(double angle) noexcept {
291 if (angle >= 0 && angle <= Math::TwoPi) {
292 // Early exit if the input is already inside the range. This avoids
293 // unnecessary math which could introduce floating point error.
294 return angle;
295 }
296 const double mod = Math::mod(angle, Math::TwoPi);
297 if (glm::abs(mod) < Math::Epsilon14 && glm::abs(angle) > Math::Epsilon14) {
298 return Math::TwoPi;
299 }
300 return mod;
301 }
302
310 static double mod(double m, double n) noexcept {
311 if (Math::sign(m) == Math::sign(n) && glm::abs(m) < glm::abs(n)) {
312 // Early exit if the input does not need to be modded. This avoids
313 // unnecessary math which could introduce floating point error.
314 return m;
315 }
316 return fmod(fmod(m, n) + n, n);
317 }
318
325 static constexpr double degreesToRadians(double angleDegrees) noexcept {
326 return angleDegrees * Math::OnePi / 180.0;
327 }
328
335 static constexpr double radiansToDegrees(double angleRadians) noexcept {
336 return angleRadians * 180.0 / Math::OnePi;
337 }
338
349 static double lerp(double p, double q, double time) noexcept {
350 return glm::mix(p, q, time);
351 }
352
361 static constexpr double clamp(double value, double min, double max) noexcept {
362 return glm::clamp(value, min, max);
363 };
364
375 static double toSNorm(double value, double rangeMaximum = 255.0) noexcept {
376 return glm::round(
377 (Math::clamp(value, -1.0, 1.0) * 0.5 + 0.5) * rangeMaximum);
378 };
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;
392 }
393
405 static double convertLongitudeRange(double angle) noexcept {
406 constexpr double twoPi = Math::TwoPi;
407
408 const double simplified = angle - glm::floor(angle / twoPi) * twoPi;
409
410 if (simplified < -Math::OnePi) {
411 return simplified + twoPi;
412 }
413 if (simplified >= Math::OnePi) {
414 return simplified - twoPi;
415 }
416
417 return simplified;
418 };
419
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) {
434 return down;
435 } else {
436 return up;
437 }
438 }
439
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) {
454 return up;
455 } else {
456 return down;
457 }
458 }
459};
460
461} // namespace CesiumUtility
Mathematical constants and functions.
Definition Math.h:12
static double mod(double m, double n) noexcept
The modulo operation that also works for negative dividends.
Definition Math.h:310
static constexpr double radiansToDegrees(double angleRadians) noexcept
Converts radians to degrees.
Definition Math.h:335
static constexpr double degreesToRadians(double angleDegrees) noexcept
Converts degrees to radians.
Definition Math.h:325
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.
Definition Math.h:222
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.
Definition Math.h:111
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.
Definition Math.h:188
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].
Definition Math.h:375
static constexpr double sign(double value) noexcept
Returns the sign of the value.
Definition Math.h:245
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.
Definition Math.h:147
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...
Definition Math.h:430
static double negativePiToPi(double angle) noexcept
Produces an angle in the range -Pi <= angle <= Pi which is equivalent to the provided angle.
Definition Math.h:274
static double zeroToTwoPi(double angle) noexcept
Produces an angle in the range 0 <= angle <= 2Pi which is equivalent to the provided angle.
Definition Math.h:290
static constexpr bool equalsEpsilon(double left, double right, double relativeEpsilon) noexcept
Checks whether two values are equal up to a given relative epsilon.
Definition Math.h:163
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...
Definition Math.h:450
static constexpr double clamp(double value, double min, double max) noexcept
Constrain a value to lie between two values.
Definition Math.h:361
static double lerp(double p, double q, double time) noexcept
Computes the linear interpolation of two values.
Definition Math.h:349
static double convertLongitudeRange(double angle) noexcept
Definition Math.h:405
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.
Definition Math.h:263
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.
Definition Math.h:127
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....
Definition Math.h:390
Utility classes for Cesium.