summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorKonstantin Käfer <mail@kkaefer.com>2014-03-14 18:23:38 +0100
committerKonstantin Käfer <mail@kkaefer.com>2014-03-14 18:23:38 +0100
commit10c72f811d783823020d39ac2e6ca9a412cdc4a1 (patch)
tree45fe0dc1eaf09f450b085f27bd1662b6ade667b3 /include
parent56e06f527c77d9d1191c21b92c2bfa65e5cbc70e (diff)
downloadqtlocation-mapboxgl-10c72f811d783823020d39ac2e6ca9a412cdc4a1.tar.gz
port rotationrange.js (still missing tests)
Diffstat (limited to 'include')
-rw-r--r--include/llmr/text/rotation_range.hpp83
-rw-r--r--include/llmr/util/math.hpp29
-rw-r--r--include/llmr/util/vec.hpp1
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;