1 /** 2 Some auxiliar math funtions 3 */ 4 module zmath.aux; 5 6 import std.math; 7 8 enum M_1_180 = 1 / 180.0L; /// Inverse of 180 9 10 /** 11 * Clamps a float point between -1.0 and +1.0 12 * Params: 13 * x = Float point number to clamp 14 * Returns A flot point number clamped between -1.0 and 1.0 15 */ 16 @safe @nogc T clamp(T = float)(in T x) pure nothrow if (__traits(isFloating, T)) { 17 if (x > 1.0L) 18 return 1.0L; 19 if (x < -1.0L) 20 return -1.0L; 21 return x; 22 } 23 24 unittest { 25 const double d = 25; 26 assert(clamp(d) == 1.0); 27 const real r = -25; 28 assert(clamp(r) == -1.0); 29 const float f = -0.5; 30 assert(clamp(f) == -0.5); 31 } 32 33 /** 34 * Converts angles in degrees to radians 35 * Params: 36 * x = Angle in grades 37 * Returns angle in radians 38 */ 39 @safe @nogc T toRadians(T = float)(in T x) pure nothrow if (__traits(isFloating, T)) { 40 return x * PI * M_1_180; 41 } 42 43 unittest { 44 assert(approxEqual(toRadians(180.0), PI)); 45 assert(approxEqual(toRadians(360.0), PI * 2.0)); 46 } 47 48 /** 49 * Converts angles in radians to degrees 50 * Params: 51 * x = Angle in radians 52 * REturns angle in grades 53 */ 54 @safe @nogc T toDegrees(T = float)(in T x) pure nothrow if (__traits(isFloating, T)) { 55 return x * 180.0L * M_1_PI; // x * 180 / PI 56 } 57 58 unittest { 59 assert(approxEqual(toDegrees(PI), 180.0)); 60 } 61 62 /** 63 * Compare two float point numbers with assuming that are equal if are in range 64 * of maxAbsDiff 65 * Params: 66 * a = A float point number 67 * b = Other float point 68 * maxRelDiff = Max relative difference 69 * maxAbsDiff = Max absoulte difference 70 * Returns If _a are aproximated equal that _b, returns 0. Otherwise, if _a > _b, 71 * returns 1 and if _a < _b , returns -1; 72 */ 73 int cmpFloat(T = float, U = float)(in T a, in U b, T maxRelDiff = 1e-2, T maxAbsDiff = 1e-5) { 74 static assert(__traits(isFloating, T), "'a' must be a float point number"); 75 static assert(__traits(isScalar, U), "'b' must be a number type"); 76 77 if (approxEqual(a, b, maxRelDiff, maxAbsDiff)) 78 return 0; 79 if (a < b) 80 return -1; 81 return 1; 82 } 83 84 unittest { 85 assert(cmpFloat(3.0, 0.0) == 1); 86 assert(cmpFloat(0.0, 3) == -1); 87 assert(cmpFloat(0.0, 0.00001) == 0); 88 }