diff options
author | Konstantin Käfer <github@kkaefer.com> | 2014-01-09 11:04:56 +0100 |
---|---|---|
committer | Konstantin Käfer <github@kkaefer.com> | 2014-01-09 11:04:56 +0100 |
commit | 16d0c83df2b1a882eae1c4d988a84bca5fe84e9a (patch) | |
tree | f896dd74b8e2a6b75d6999f102003717fa0aa9f0 | |
parent | a7205b339e8d1c8dee54eaaa38b3efba2df3820e (diff) | |
download | qtlocation-mapboxgl-16d0c83df2b1a882eae1c4d988a84bca5fe84e9a.tar.gz |
copy rotation behavior from js version
-rw-r--r-- | include/llmr/map/map.hpp | 2 | ||||
-rw-r--r-- | include/llmr/map/transform.hpp | 2 | ||||
-rw-r--r-- | include/llmr/util/math.hpp | 16 | ||||
-rw-r--r-- | macosx/main.mm | 17 | ||||
-rw-r--r-- | src/map/map.cpp | 4 | ||||
-rw-r--r-- | src/map/transform.cpp | 30 |
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) { |