#pragma once #include #include #include #include namespace mbgl { namespace util { // TODO: split this file up into individual headers, following mbgl/math/*.hpp. // Find the angle of the two vectors, solving the formula for the cross product // a x b = |a||b|sin(θ) for θ. template T angle_between(const Point& a, const Point& b) { return std::atan2((a.x * b.y - a.y * b.x), a.x * b.x + a.y * b.y); } template T angle_to(const Point& a, const Point& b) { return std::atan2(a.y - b.y, a.x - b.x); } // Reflect an angle around 0 degrees template std::array flip(const std::array& c) { return {{ static_cast(2 * M_PI - c[0]), static_cast(2 * M_PI - c[1]) }}; } template Point 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 T perp(const T& a) { return T(-a.y, a.x); } template 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 T distSqr(const S1& a, const S2& b) { T dx = b.x - a.x; T dy = b.y - a.y; T c = dx * dx + dy * dy; return c; } template T round(const T& a) { return T(::round(a.x), ::round(a.y)); } template T length(T a, T b) { return std::sqrt(a * a + b * b); } // Take the magnitude of vector a. template T mag(const S& a) { return std::sqrt(a.x * a.x + a.y * a.y); } template S unit(const S& a) { auto magnitude = mag(a); if (magnitude == 0) { return a; } return a * (1 / magnitude); } template T rotate(const T& a, S angle) { S cos = std::cos(angle); S sin = std::sin(angle); S x = cos * a.x - sin * a.y; S y = sin * a.x + cos * a.y; return T(x, y); } template Point matrixMultiply(const std::array& m, const Point& p) { return Point(m[0] * p.x + m[1] * p.y, m[2] * p.x + m[3] * p.y); } 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); } template inline T division(const T dividend, const T divisor, const T nan) { if (divisor == 0) { if (dividend == 0) { return nan; } else { return ::copysign(std::numeric_limits::infinity(), dividend); } } else { return dividend / divisor; } } } // namespace util } // namespace mbgl