summaryrefslogtreecommitdiffstats
path: root/src/math/func.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/math/func.h')
-rw-r--r--src/math/func.h238
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);
+ }
+}