#ifndef MBGL_UTIL_MATH #define MBGL_UTIL_MATH #include #include #include namespace mbgl { namespace util { template inline T max(T a, T b) { return b > a ? b : a; } template inline T max(T a, T b, T c) { return max(max(a, b), c); } template inline T max(T a, T b, T c, T d) { return max(max(a, b), max(c, d)); } template inline T min(T a, T b) { return b < a ? b : a; } template inline T min(T a, T b, T c) { return min(min(a, b), c); } template inline T min(T a, T b, T c, T d) { return min(min(a, b), min(c, d)); } // Find the angle of the two vectors, solving the formula for the cross product // a x b = |a||b|sin(θ) for θ. template inline T angle_between(S ax, S ay, S bx, S by) { return std::atan2((ax * by - ay * bx), ax * bx + ay * by); } template inline T angle_between(const vec2& a, const vec2& b) { return angle_between(a.x, a.y, b.x, b.y); } template inline T angle_to(const vec2& a, const vec2& b) { return std::atan2(a.y - b.y, a.x - b.x); } // Reflect an angle around 0 degrees template inline std::array flip(const std::array& c) { return {{ static_cast(2 * M_PI - c[0]), static_cast(2 * M_PI - c[1]) }}; } template inline vec2 normal(const S1& a, const S2& b) { T dx = b.x - a.x; T dy = b.y - a.y; T c = std::sqrt(dx * dx + dy * dy); return { dx / c, dy / c }; } template inline T perp(const T& a) { return T(-a.y, a.x); } template inline T dist(const S1& a, const S2& b) { T dx = b.x - a.x; T dy = b.y - a.y; T c = std::sqrt(dx * dx + dy * dy); return c; } template inline T length(T a, T b) { return std::sqrt(a * a + b * b); } // Take the magnitude of vector a. template inline T mag(const S& a) { return std::sqrt(a.x * a.x + a.y * a.y); } template inline S unit(const S& a) { auto magnitude = mag(a); if (magnitude == 0) { return a; } return a * (1 / magnitude); } template T clamp(T value, T min, T max) { return value < min ? min : (value > max ? max : value); } // Constrains n to the given range (including min, excluding max) via modular // arithmetic. template T wrap(T value, T min, T max) { T d = max - min; return std::fmod((std::fmod((value - min), d) + d), d) + min; } template T smoothstep(T edge0, T edge1, T x) { T t = clamp((x - edge0) / (edge1 - edge0), T(0), T(1)); return t * t * (T(3) - T(2) * t); } // Computes the log2(x) rounded up to the next integer. // (== number of bits required to store x) uint32_t ceil_log2(uint64_t x); } } #endif