diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2014-03-14 18:23:38 +0100 |
---|---|---|
committer | Konstantin Käfer <mail@kkaefer.com> | 2014-03-14 18:23:38 +0100 |
commit | 10c72f811d783823020d39ac2e6ca9a412cdc4a1 (patch) | |
tree | 45fe0dc1eaf09f450b085f27bd1662b6ade667b3 /include | |
parent | 56e06f527c77d9d1191c21b92c2bfa65e5cbc70e (diff) | |
download | qtlocation-mapboxgl-10c72f811d783823020d39ac2e6ca9a412cdc4a1.tar.gz |
port rotationrange.js (still missing tests)
Diffstat (limited to 'include')
-rw-r--r-- | include/llmr/text/rotation_range.hpp | 83 | ||||
-rw-r--r-- | include/llmr/util/math.hpp | 29 | ||||
-rw-r--r-- | include/llmr/util/vec.hpp | 1 |
3 files changed, 113 insertions, 0 deletions
diff --git a/include/llmr/text/rotation_range.hpp b/include/llmr/text/rotation_range.hpp new file mode 100644 index 0000000000..6cc67f323b --- /dev/null +++ b/include/llmr/text/rotation_range.hpp @@ -0,0 +1,83 @@ +#ifndef LLMR_TEXT_ROTATION_RANGE +#define LLMR_TEXT_ROTATION_RANGE + +#include <llmr/util/vec.hpp> +#include <llmr/util/math.hpp> + +#include <array> +#include <vector> +#include <cassert> + +namespace llmr { + +typedef vec2<int16_t> CollisionPoint; +typedef vec2<float> CollisionAnchor; + +typedef std::array<float, 2> PlacementRange; +typedef float CollisionAngle; +typedef std::vector<CollisionAngle> CollisionAngles; +typedef std::array<CollisionAngle, 2> CollisionRange; +typedef std::vector<CollisionRange> CollisionList; +typedef std::array<CollisionPoint, 4> CollisionCorners; + +struct CollisionRect { + CollisionPoint tl; + CollisionPoint br; + inline CollisionRect() {} + inline CollisionRect(CollisionPoint::Type ax, CollisionPoint::Type ay, + CollisionPoint::Type bx, CollisionPoint::Type by) + : tl(ax, ay), br(bx, by) {} + inline CollisionRect(const CollisionPoint &tl, const CollisionPoint &br) + : tl(tl), br(br) {} +}; + +struct CollisionBox { + CollisionRect box; + CollisionPoint anchor; + bool rotate = false; + PlacementRange placementRange; +}; + +/* + * Combine an array of collision ranges to form a continuous + * range that includes 0. Collisions within the ignoreRange are ignored + */ +CollisionRange mergeCollisions(const CollisionList &collisions, + PlacementRange ignoreRange); + +/* + * Calculate collision ranges for two rotating boxes.e + */ +CollisionList rotatingRotatingCollisions(const CollisionRect &a, + const CollisionRect &b, + const CollisionAnchor &anchorToAnchor); + +/* + * Return the intersection points of a circle and a line segment; + */ +void circleEdgeCollisions(std::back_insert_iterator<CollisionAngles> angles, + const CollisionPoint &corner, float radius, + const CollisionPoint &p1, const CollisionPoint &p2); + +/* + * Calculate the ranges for which the corner, + * rotatated around the anchor, is within the box; + */ +void cornerBoxCollisions(std::back_insert_iterator<CollisionList> collisions, + const CollisionPoint &corner, + const CollisionCorners &boxCorners, bool flip = false); + +/* + * Calculate collision ranges for a rotating box and a fixed box; + */ +CollisionList rotatingFixedCollisions(const CollisionRect &rotating, + const CollisionRect &fixed); + +/* + * Calculate the range a box conflicts with a second box + */ +CollisionRange rotationRange(const CollisionBox &inserting, + const CollisionBox &blocker, double scale); +} + +#endif diff --git a/include/llmr/util/math.hpp b/include/llmr/util/math.hpp index 4666401349..bf47a3d073 100644 --- a/include/llmr/util/math.hpp +++ b/include/llmr/util/math.hpp @@ -2,12 +2,14 @@ #define LLMR_UTIL_MATH #include <cmath> +#include <array> #include "vec.hpp" namespace llmr { namespace util { + template <typename T> inline T max(T a, T b) { return b > a ? b : a; @@ -18,10 +20,31 @@ inline T min(T a, T b) { return b < a ? b : a; } +// Find the angle of the two vectors, solving the formula for the cross product +// a x b = |a||b|sin(θ) for θ. inline double angle_between(double ax, double ay, double bx, double by) { return atan2((ax * by - ay * bx), ax * bx + ay * by); } +template <typename T = double, typename S> +inline double angle_between(const vec2<S>& a, const vec2<S>& b) { + return angle_between(a.x, a.y, b.x, b.y); +} + +template <typename T, typename S1, typename S2> +inline T interp(S1 a, S2 b, T t) { + return (a * ((T)1 - t)) + (b * t); +} + +// Reflect an angle around 0 degrees +template <typename T> +inline std::array<T, 2> flip(const std::array<T, 2>& c) { + return {{ + static_cast<T>(2 * M_PI - c[0]), + static_cast<T>(2 * M_PI - c[1]) + }}; +} + template <typename T, typename S1, typename S2> inline vec2<T> normal(const S1& a, const S2& b) { T dx = b.x - a.x; @@ -38,6 +61,12 @@ inline T dist(const S1& a, const S2& b) { return c; } +// Take the magnitude of vector a. +template <typename T = double, typename S> +inline T mag(const S& a) { + return sqrt(a.x * a.x + a.y * a.y); +} + } } diff --git a/include/llmr/util/vec.hpp b/include/llmr/util/vec.hpp index dbc31187bc..445160f15d 100644 --- a/include/llmr/util/vec.hpp +++ b/include/llmr/util/vec.hpp @@ -10,6 +10,7 @@ namespace llmr { template <typename T = double> struct vec2 { struct null {}; + typedef T Type; T x, y; |