diff options
Diffstat (limited to 'src/math/func.h')
-rw-r--r-- | src/math/func.h | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/src/math/func.h b/src/math/func.h new file mode 100644 index 0000000..2e43d24 --- /dev/null +++ b/src/math/func.h @@ -0,0 +1,238 @@ +// math/func.h + +/* Common math functions */ + +#pragma once + +#include "const.h" + +#include <cmath> +#include <cstdlib> + +namespace Math +{ + +//! Compares a and b within TOLERANCE +bool IsEqual(float a, float b) +{ + return Abs(a - b) < TOLERANCE; +} + +//! Minimum +inline float Min(float a, float b) +{ + if ( a <= b ) return a; + else return b; +} + +inline float Min(float a, float b, float c) +{ + return Min( Min(a, b), c ); +} + +inline float Min(float a, float b, float c, float d) +{ + return Min( Min(a, b), Min(c, d) ); +} + +inline float Min(float a, float b, float c, float d, float e) +{ + return Min( Min(a, b), Min(c, d), e ); +} + +//! Maximum +inline float Max(float a, float b) +{ + if ( a >= b ) return a; + else return b; +} + +inline float Max(float a, float b, float c) +{ + return Max( Max(a, b), c ); +} + +inline float Max(float a, float b, float c, float d) +{ + return Max( Max(a, b), Max(c, d) ); +} + +inline float Max(float a, float b, float c, float d, float e) +{ + return Max( Max(a, b), Max(c, d), e ); +} + +//! Returns the normalized value (0 .. 1) +inline float Norm(float a) +{ + if ( a < 0.0f ) return 0.0f; + if ( a > 1.0f ) return 1.0f; + return a; +} + +//! Returns the absolute value +inline float Abs(float a) +{ + return (float)fabs(a); +} + +//! Swaps two integers +inline void Swap(int &a, int &b) +{ + int c; + + c = a; + a = b; + b = c; +} + +//! Swaps two real numbers +inline void Swap(float &a, float &b) +{ + float c; + + c = a; + a = b; + b = c; +} + +//! Permutes two points +inline void Swap(Point &a, Point &b) +{ + Point c; + + c = a; + a = b; + b = c; +} + +//! Returns the modulo of a floating point number +/** Mod(8.1, 4) = 0.1 + Mod(n, 1) = fractional part of n */ +inline float Mod(float a, float m) +{ + return a - ((int)(a/m))*m; +} + +//! Returns a normalized angle, that is in other words between 0 and 2 * PI +inline float NormAngle(float angle) +{ + angle = Mod(angle, PI_MUL_2); + if ( angle < 0.0f ) + return PI_MUL_2 + angle; + + return angle; +} + +//! Test if a angle is between two terminals +inline bool TestAngle(float angle, float min, float max) +{ + angle = NormAngle(angle); + min = NormAngle(min); + max = NormAngle(max); + + if ( min > max ) + return ( angle <= max || angle >= min ); + + return ( angle >= min && angle <= max ); +} + +//! Calculates the angle to rotate the angle \a a to the angle \a g +/** A positive angle is counterclockwise (CCW). */ +inline float Direction(float a, float g) +{ + a = NormAngle(a); + g = NormAngle(g); + + if ( a < g ) + { + if ( a+PI*2.0f-g < g-a ) a += PI*2.0f; + } + else + { + if ( g+PI*2.0f-a < a-g ) g += PI*2.0f; + } + + return g-a; +} + +//! Returns a random value between 0 and 1. +inline float Rand() +{ + return (float)rand()/RAND_MAX; +} + + +//! Managing the dead zone of a joystick. +/** + in: -1 0 1 + --|-------|----o----|-------|--> + <----> + dead + out: -1 0 0 1 */ +float Neutral(float value, float dead) +{ + if ( Abs(value) <= dead ) + { + return 0.0f; + } + else + { + if ( value > 0.0f ) return (value-dead)/(1.0f-dead); + else return (value+dead)/(1.0f-dead); + } +} + + +//! Calculates a value (radians) proportional between a and b (degrees) +float Prop(int a, int b, float p) +{ + float aa = (float)a * DEG_TO_RAD; + float bb = (float)b * DEG_TO_RAD; + + return aa+p*(bb-aa); +} + +//! Gently advances a desired value from its current value +/** Over time, the progression is more rapid. */ +float Smooth(float actual, float hope, float time) +{ + float future = actual + (hope-actual)*time; + + if ( hope > actual ) + { + if ( future > hope ) future = hope; + } + if ( hope < actual ) + { + if ( future < hope ) future = hope; + } + + return future; +} + + +//! Bounces any movement +/** out + | + 1+------o-------o--- + | o | o o | | bounce + | o | o---|--- + | o | | + | o | | + -o------|-------+----> progress + 0| | 1 + |<---->|middle */ +inline float Bounce(float progress, float middle, float bounce) +{ + if ( progress < middle ) + { + progress = progress/middle; // 0..1 + return 0.5f+sinf(progress*PI-PI/2.0f)/2.0f; + } + else + { + progress = (progress-middle)/(1.0f-middle); // 0..1 + return (1.0f-bounce/2.0f)+sinf((0.5f+progress*2.0f)*PI)*(bounce/2.0f); + } +} |