/** * @file math.h * * Math utility functions */ #pragma once namespace devilution { namespace math { /** * @brief Compute sign of t * @tparam T Any arithmetic type * @param t Value to compute sign of * @return -1 if t < 0, 1 if t > 0, 0 if t == 0 */ template int Sign(T t) { return (t > T(0)) - (t < T(0)); } /** * @brief Linearly interpolate from a towards b using mixing value t * @tparam V Any arithmetic type, used for interpolants and return value * @tparam T Any arithmetic type, used for interpolator * @param a Low interpolation value (returned when t == 0) * @param b High interpolation value (returned when t == 1) * @param t Interpolator, commonly in range [0..1], values outside this range will extrapolate * @return a + (b - a) * t */ template V Lerp(V a, V b, T t) { return a + (b - a) * t; } /** * @brief Inverse lerp, given two key values a and b, and a free value v, determine mixing factor t so that v = Lerp(a, b, t) * @tparam T Any arithmetic type * @param a Low key value (function returns 0 if v == a) * @param b High key value (function returns 1 if v == b) * @param v Mixing factor, commonly in range [a..b] to get a return [0..1] * @return Value t so that v = Lerp(a, b, t); or 0 if b == a */ template T InvLerp(T a, T b, T v) { if (b == a) return T(0); return (v - a) / (b - a); } /** * @brief Remaps value v from range [inMin, inMax] to [outMin, outMax] * @tparam T Any arithmetic type * @param inMin First bound of input range * @param inMax Second bound of input range * @param outMin First bound of output range * @param outMax Second bound of output range * @param v Value to remap * @return Transformed value so that InvLerp(inMin, inMax, v) == InvLerp(outMin, outMax, return) */ template T Remap(T inMin, T inMax, T outMin, T outMax, T v) { auto t = InvLerp(inMin, inMax, v); return Lerp(outMin, outMax, t); } } // namespace math } // namespace devilution