summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Käfer <github@kkaefer.com>2014-01-09 11:04:56 +0100
committerKonstantin Käfer <github@kkaefer.com>2014-01-09 11:04:56 +0100
commit16d0c83df2b1a882eae1c4d988a84bca5fe84e9a (patch)
treef896dd74b8e2a6b75d6999f102003717fa0aa9f0
parenta7205b339e8d1c8dee54eaaa38b3efba2df3820e (diff)
downloadqtlocation-mapboxgl-16d0c83df2b1a882eae1c4d988a84bca5fe84e9a.tar.gz
copy rotation behavior from js version
-rw-r--r--include/llmr/map/map.hpp2
-rw-r--r--include/llmr/map/transform.hpp2
-rw-r--r--include/llmr/util/math.hpp16
-rw-r--r--macosx/main.mm17
-rw-r--r--src/map/map.cpp4
-rw-r--r--src/map/transform.cpp30
6 files changed, 55 insertions, 16 deletions
diff --git a/include/llmr/map/map.hpp b/include/llmr/map/map.hpp
index bb3b288aa0..7f2903a261 100644
--- a/include/llmr/map/map.hpp
+++ b/include/llmr/map/map.hpp
@@ -21,7 +21,7 @@ public:
bool render();
void moveBy(double dx, double dy);
void scaleBy(double ds, double cx, double cy);
- void rotateBy(double cx, double cy, double dx, double dy);
+ void rotateBy(double cx, double cy, double sx, double sy, double ex, double ey);
void tileLoaded(tile *tile);
void tileFailed(tile *tile);
diff --git a/include/llmr/map/transform.hpp b/include/llmr/map/transform.hpp
index 3f5f8dc3a6..4ff3cc0076 100644
--- a/include/llmr/map/transform.hpp
+++ b/include/llmr/map/transform.hpp
@@ -14,7 +14,7 @@ public:
// Relative changes
void moveBy(double dx, double dy);
void scaleBy(double ds, double cx, double cy);
- void rotateBy(double cx, double cy, double dx, double dy);
+ void rotateBy(double cx, double cy, double sx, double sy, double ex, double ey);
// Absolute changes
void setScale(double scale);
diff --git a/include/llmr/util/math.hpp b/include/llmr/util/math.hpp
new file mode 100644
index 0000000000..744a9d9473
--- /dev/null
+++ b/include/llmr/util/math.hpp
@@ -0,0 +1,16 @@
+#ifndef LLMR_UTIL_MATH
+#define LLMR_UTIL_MATH
+
+#include <cmath>
+
+namespace llmr {
+namespace util {
+
+inline double angle_between(double ax, double ay, double bx, double by) {
+ return atan2((ax * by - ay * bx), ax * bx + ay * by);
+}
+
+}
+}
+
+#endif
diff --git a/macosx/main.mm b/macosx/main.mm
index ac3fcdb31f..3119d2b869 100644
--- a/macosx/main.mm
+++ b/macosx/main.mm
@@ -75,7 +75,13 @@ public:
static void mouseclick(GLFWwindow *window, int button, int action, int modifiers) {
MapView *view = (MapView *)glfwGetWindowUserPointer(window);
- if (button == GLFW_MOUSE_BUTTON_LEFT) {
+ if (button == GLFW_MOUSE_BUTTON_RIGHT || (button == GLFW_MOUSE_BUTTON_LEFT && modifiers & GLFW_MOD_CONTROL)) {
+ view->rotating = action == GLFW_PRESS;
+ if (view->rotating) {
+ view->start_x = view->last_x;
+ view->start_y = view->last_y;
+ }
+ } else if (button == GLFW_MOUSE_BUTTON_LEFT) {
view->tracking = action == GLFW_PRESS;
if (action == GLFW_RELEASE) {
@@ -85,14 +91,7 @@ public:
}
view->last_click = now;
}
- } else if (button == GLFW_MOUSE_BUTTON_RIGHT) {
- view->rotating = action == GLFW_PRESS;
- if (view->rotating) {
- view->start_x = view->last_x;
- view->start_y = view->last_y;
- }
}
-
}
static void mousemove(GLFWwindow *window, double x, double y) {
@@ -100,7 +99,7 @@ public:
if (view->tracking) {
view->map->moveBy(x - view->last_x, y - view->last_y);
} else if (view->rotating) {
- view->map->rotateBy(view->start_x, view->start_y, x - view->last_x, y - view->last_y);
+ view->map->rotateBy(view->start_x, view->start_y, view->last_x, view->last_y, x, y);
}
view->last_x = x;
view->last_y = y;
diff --git a/src/map/map.cpp b/src/map/map.cpp
index 5e8b17f60e..f010fa95af 100644
--- a/src/map/map.cpp
+++ b/src/map/map.cpp
@@ -52,8 +52,8 @@ void map::scaleBy(double ds, double cx, double cy) {
platform->restart();
}
-void map::rotateBy(double cx, double cy, double dx, double dy) {
- transform->rotateBy(cx, cy, dx, dy);
+void map::rotateBy(double cx, double cy, double sx, double sy, double ex, double ey) {
+ transform->rotateBy(cx, cy, sx, sy, ex, ey);
platform->restart();
}
diff --git a/src/map/transform.cpp b/src/map/transform.cpp
index b1a0018e29..e458d663b4 100644
--- a/src/map/transform.cpp
+++ b/src/map/transform.cpp
@@ -1,6 +1,7 @@
#include <llmr/map/transform.hpp>
#include <llmr/util/mat4.h>
+#include <llmr/util/math.hpp>
#include <cmath>
#include <cstdio>
@@ -42,9 +43,32 @@ void transform::scaleBy(double ds, double cx, double cy) {
y = (y * ds) + fy;
}
-void transform::rotateBy(double cx, double cy, double dx, double dy) {
- const double distance = copysign(sqrt(dx * dx + dy * dy), dx);
- setAngle(angle + D2R * distance);
+
+void transform::rotateBy(double anchor_x, double anchor_y, double start_x, double start_y, double end_x, double end_y) {
+ double center_x = width / 2, center_y = height / 2;
+
+ const double begin_center_x = start_x - center_x;
+ const double begin_center_y = start_y - center_y;
+
+ const double beginning_center_dist = sqrt(begin_center_x * begin_center_x + begin_center_y * begin_center_y);
+
+ // If the first click was too close to the center, move the center of rotation by 200 pixels
+ // in the direction of the click.
+ if (beginning_center_dist < 200) {
+ const double offset_x = -200, offset_y = 0;
+ const double rotate_angle = atan2(begin_center_y, begin_center_x);
+ const double rotate_angle_sin = sin(rotate_angle);
+ const double rotate_angle_cos = cos(rotate_angle);
+ center_x = start_x + rotate_angle_cos * offset_x - rotate_angle_sin * offset_y;
+ center_y = start_y + rotate_angle_sin * offset_x + rotate_angle_cos * offset_y;
+ }
+
+ const double first_x = start_x - center_x, first_y = start_y - center_y;
+ const double second_x = end_x - center_x, second_y = end_y - center_y;
+
+ const double ang = angle + util::angle_between(first_x, first_y, second_x, second_y);
+
+ setAngle(ang);
}
void transform::setAngle(double new_angle) {