1 /** 2 Useful functions 3 4 Copyright: (c) Enalye 2017 5 License: Zlib 6 Authors: Enalye 7 */ 8 9 module atelier.core.util; 10 11 public import std.math; 12 public import std.algorithm.comparison : clamp, min, max; 13 14 import atelier.core.vec2; 15 16 /// The square root of 2, then divided by 2. 17 enum sqrt2_2 = std.math.sqrt(2.0) / 2.0; 18 /// 2 times PI. 19 enum pi2 = PI * 2f; 20 21 /// Interpolation, returns a value between a and b. \ 22 /// If t = 0, returns a. \ 23 /// If t = 1, returns b. 24 T lerp(T)(T a, T b, float t) { 25 return t * b + (1f - t) * a; 26 } 27 28 /// Reverse lerp, returns a value between 0 and 1. \ 29 /// 0 if v = a. \ 30 /// 1 if v = b. 31 float rlerp(float a, float b, float v) { 32 return (v - a) / (b - a); 33 } 34 35 /// The minimal angle (in degrees) between 2 other angles. 36 float angleBetween(float a, float b) { 37 const float delta = (b - a) % 360f; 38 return ((2f * delta) % 360f) - delta; 39 } 40 41 /// Interpolation between an angle a and b. \ 42 /// If t = 0, returns a. \ 43 /// If t = 1, returns b. 44 float angleLerp(float a, float b, float t) { 45 return a + angleBetween(a, b) * t; 46 } 47 48 /// Scale a vector to fit the specified vector while keeping its ratio. 49 Vec2f scaleToFit(Vec2f src, Vec2f dst) { 50 float scale; 51 if (dst.x / dst.y > src.x / src.y) 52 scale = dst.y / src.y; 53 else 54 scale = dst.x / src.x; 55 return src * scale; 56 } 57 58 /// Linear interpolation to approach a target 59 float approach(float value, float target, float step) { 60 return value > target ? max(value - step, target) : min(value + step, target); 61 }