[core] Use PrecisionPoint in zoom and angle functions
This commit is contained in:
@@ -107,8 +107,8 @@ public:
|
||||
void resetPosition();
|
||||
|
||||
// Scale
|
||||
void scaleBy(double ds, double cx = -1, double cy = -1, const Duration& = Duration::zero());
|
||||
void setScale(double scale, double cx = -1, double cy = -1, const Duration& = Duration::zero());
|
||||
void scaleBy(double ds, const PrecisionPoint& = { 0, 0 }, const Duration& = Duration::zero());
|
||||
void setScale(double scale, const PrecisionPoint& = { 0, 0 }, const Duration& = Duration::zero());
|
||||
double getScale() const;
|
||||
void setZoom(double zoom, const Duration& = Duration::zero());
|
||||
double getZoom() const;
|
||||
@@ -120,9 +120,9 @@ public:
|
||||
double getMaxZoom() const;
|
||||
|
||||
// Rotation
|
||||
void rotateBy(double sx, double sy, double ex, double ey, const Duration& = Duration::zero());
|
||||
void rotateBy(const PrecisionPoint& first, const PrecisionPoint& second, const Duration& = Duration::zero());
|
||||
void setBearing(double degrees, const Duration& = Duration::zero());
|
||||
void setBearing(double degrees, double cx, double cy);
|
||||
void setBearing(double degrees, const PrecisionPoint&);
|
||||
double getBearing() const;
|
||||
void resetNorth();
|
||||
|
||||
@@ -135,9 +135,10 @@ public:
|
||||
uint16_t getHeight() const;
|
||||
|
||||
// Projection
|
||||
void getWorldBoundsMeters(ProjectedMeters &sw, ProjectedMeters &ne) const;
|
||||
void getWorldBoundsLatLng(LatLng &sw, LatLng &ne) const;
|
||||
double getMetersPerPixelAtLatitude(const double lat, const double zoom) const;
|
||||
void getWorldBoundsMeters(ProjectedMeters& sw, ProjectedMeters& ne) const;
|
||||
void getWorldBoundsLatLng(LatLng& sw, LatLng& ne) const;
|
||||
|
||||
double getMetersPerPixelAtLatitude(double lat, double zoom) const;
|
||||
ProjectedMeters projectedMetersForLatLng(const LatLng&) const;
|
||||
LatLng latLngForProjectedMeters(const ProjectedMeters&) const;
|
||||
PrecisionPoint pixelForLatLng(const LatLng&) const;
|
||||
|
||||
@@ -279,7 +279,7 @@ void GLFWView::onScroll(GLFWwindow *window, double /*xOffset*/, double yOffset)
|
||||
scale = 1.0 / scale;
|
||||
}
|
||||
|
||||
view->map->scaleBy(scale, view->lastX, view->lastY);
|
||||
view->map->scaleBy(scale, { view->lastX, view->lastY });
|
||||
}
|
||||
|
||||
void GLFWView::onWindowResize(GLFWwindow *window, int width, int height) {
|
||||
@@ -313,9 +313,9 @@ void GLFWView::onMouseClick(GLFWwindow *window, int button, int action, int modi
|
||||
double now = glfwGetTime();
|
||||
if (now - view->lastClick < 0.4 /* ms */) {
|
||||
if (modifiers & GLFW_MOD_SHIFT) {
|
||||
view->map->scaleBy(0.5, view->lastX, view->lastY, std::chrono::milliseconds(500));
|
||||
view->map->scaleBy(0.5, { view->lastX, view->lastY }, std::chrono::milliseconds(500));
|
||||
} else {
|
||||
view->map->scaleBy(2.0, view->lastX, view->lastY, std::chrono::milliseconds(500));
|
||||
view->map->scaleBy(2.0, { view->lastX, view->lastY }, std::chrono::milliseconds(500));
|
||||
}
|
||||
}
|
||||
view->lastClick = now;
|
||||
@@ -335,7 +335,7 @@ void GLFWView::onMouseMove(GLFWwindow *window, double x, double y) {
|
||||
mbgl::PrecisionPoint(x, flippedY));
|
||||
}
|
||||
} else if (view->rotating) {
|
||||
view->map->rotateBy(view->lastX, view->lastY, x, y);
|
||||
view->map->rotateBy({ view->lastX, view->lastY }, { x, y });
|
||||
}
|
||||
view->lastX = x;
|
||||
view->lastY = y;
|
||||
|
||||
@@ -187,13 +187,13 @@ void Map::resetPosition() {
|
||||
|
||||
#pragma mark - Scale
|
||||
|
||||
void Map::scaleBy(double ds, double cx, double cy, const Duration& duration) {
|
||||
transform->scaleBy(ds, cx, cy, duration);
|
||||
void Map::scaleBy(double ds, const PrecisionPoint& point, const Duration& duration) {
|
||||
transform->scaleBy(ds, point, duration);
|
||||
update(Update::Zoom);
|
||||
}
|
||||
|
||||
void Map::setScale(double scale, double cx, double cy, const Duration& duration) {
|
||||
transform->setScale(scale, cx, cy, duration);
|
||||
void Map::setScale(double scale, const PrecisionPoint& point, const Duration& duration) {
|
||||
transform->setScale(scale, point, duration);
|
||||
update(Update::Zoom);
|
||||
}
|
||||
|
||||
@@ -296,8 +296,8 @@ uint16_t Map::getHeight() const {
|
||||
|
||||
#pragma mark - Rotation
|
||||
|
||||
void Map::rotateBy(double sx, double sy, double ex, double ey, const Duration& duration) {
|
||||
transform->rotateBy(sx, sy, ex, ey, duration);
|
||||
void Map::rotateBy(const PrecisionPoint& first, const PrecisionPoint& second, const Duration& duration) {
|
||||
transform->rotateBy(first, second, duration);
|
||||
update(Update::Repaint);
|
||||
}
|
||||
|
||||
@@ -306,8 +306,8 @@ void Map::setBearing(double degrees, const Duration& duration) {
|
||||
update(Update::Repaint);
|
||||
}
|
||||
|
||||
void Map::setBearing(double degrees, double cx, double cy) {
|
||||
transform->setAngle(-degrees * M_PI / 180, cx, cy);
|
||||
void Map::setBearing(double degrees, const PrecisionPoint& center) {
|
||||
transform->setAngle(-degrees * M_PI / 180, center);
|
||||
update(Update::Repaint);
|
||||
}
|
||||
|
||||
@@ -343,7 +343,7 @@ void Map::getWorldBoundsLatLng(LatLng& sw, LatLng& ne) const {
|
||||
Projection::getWorldBoundsLatLng(sw, ne);
|
||||
}
|
||||
|
||||
double Map::getMetersPerPixelAtLatitude(const double lat, const double zoom) const {
|
||||
double Map::getMetersPerPixelAtLatitude(double lat, double zoom) const {
|
||||
return Projection::getMetersPerPixelAtLatitude(lat, zoom);
|
||||
}
|
||||
|
||||
|
||||
@@ -150,8 +150,8 @@ void Transform::setLatLngZoom(const LatLng& latLng, const double zoom, const Dur
|
||||
|
||||
#pragma mark - Zoom
|
||||
|
||||
void Transform::scaleBy(const double ds, const double cx, const double cy, const Duration& duration) {
|
||||
if (std::isnan(ds) || std::isnan(cx) || std::isnan(cy)) {
|
||||
void Transform::scaleBy(const double ds, const PrecisionPoint& center, const Duration& duration) {
|
||||
if (std::isnan(ds) || !center.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -163,16 +163,15 @@ void Transform::scaleBy(const double ds, const double cx, const double cy, const
|
||||
new_scale = state.max_scale;
|
||||
}
|
||||
|
||||
_setScale(new_scale, cx, cy, duration);
|
||||
_setScale(new_scale, center, duration);
|
||||
}
|
||||
|
||||
void Transform::setScale(const double scale, const double cx, const double cy,
|
||||
const Duration& duration) {
|
||||
if (std::isnan(scale) || std::isnan(cx) || std::isnan(cy)) {
|
||||
void Transform::setScale(const double scale, const PrecisionPoint& center, const Duration& duration) {
|
||||
if (std::isnan(scale) || !center.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
_setScale(scale, cx, cy, duration);
|
||||
_setScale(scale, center, duration);
|
||||
}
|
||||
|
||||
void Transform::setZoom(const double zoom, const Duration& duration) {
|
||||
@@ -180,7 +179,7 @@ void Transform::setZoom(const double zoom, const Duration& duration) {
|
||||
return;
|
||||
}
|
||||
|
||||
_setScale(std::pow(2.0, zoom), -1, -1, duration);
|
||||
_setScale(std::pow(2.0, zoom), { 0, 0 }, duration);
|
||||
}
|
||||
|
||||
double Transform::getZoom() const {
|
||||
@@ -191,7 +190,7 @@ double Transform::getScale() const {
|
||||
return state.scale;
|
||||
}
|
||||
|
||||
void Transform::_setScale(double new_scale, double cx, double cy, const Duration& duration) {
|
||||
void Transform::_setScale(double new_scale, const PrecisionPoint& center, const Duration& duration) {
|
||||
// Ensure that we don't zoom in further than the maximum allowed.
|
||||
if (new_scale < state.min_scale) {
|
||||
new_scale = state.min_scale;
|
||||
@@ -203,8 +202,8 @@ void Transform::_setScale(double new_scale, double cx, double cy, const Duration
|
||||
double dx = 0;
|
||||
double dy = 0;
|
||||
|
||||
if (cx > 0 || cy > 0) {
|
||||
auto coord = state.pointToCoordinate({ cx, state.getHeight() - cy }).zoomTo(state.getZoom());
|
||||
if (center.x > 0 || center.y > 0) {
|
||||
auto coord = state.pointToCoordinate({ center.x, state.getHeight() - center.y }).zoomTo(state.getZoom());
|
||||
auto centerCoord = state.pointToCoordinate({ state.width / 2.0f, state.height / 2.0f }).zoomTo(state.getZoom());
|
||||
auto coordDiff = centerCoord - coord;
|
||||
dx = coordDiff.column * util::tileSize * (1.0 - factor);
|
||||
@@ -297,34 +296,30 @@ void Transform::_easeTo(const CameraOptions& options, double new_scale, double n
|
||||
|
||||
#pragma mark - Angle
|
||||
|
||||
void Transform::rotateBy(const double start_x, const double start_y, const double end_x,
|
||||
const double end_y, const Duration& duration) {
|
||||
if (std::isnan(start_x) || std::isnan(start_y) || std::isnan(end_x) || std::isnan(end_y)) {
|
||||
void Transform::rotateBy(const PrecisionPoint& first, const PrecisionPoint& second, const Duration& duration) {
|
||||
if (!first.isValid() || !second.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
double center_x = static_cast<double>(state.width) / 2.0, center_y = static_cast<double>(state.height) / 2.0;
|
||||
|
||||
const double begin_center_x = start_x - center_x;
|
||||
const double begin_center_y = start_y - center_y;
|
||||
|
||||
const double beginning_center_dist =
|
||||
std::sqrt(begin_center_x * begin_center_x + begin_center_y * begin_center_y);
|
||||
double center_x = static_cast<double>(state.width) / 2.0;
|
||||
double center_y = static_cast<double>(state.height) / 2.0;
|
||||
const double first_x = first.x - center_x;
|
||||
const double first_y = first.y - center_y;
|
||||
const double second_x = second.x - center_x;
|
||||
const double second_y = second.y - center_y;
|
||||
const double beginning_center_dist = std::sqrt(first_x * first_x + first_y * first_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 = std::atan2(begin_center_y, begin_center_x);
|
||||
const double rotate_angle = std::atan2(first_y, first_x);
|
||||
const double rotate_angle_sin = std::sin(rotate_angle);
|
||||
const double rotate_angle_cos = std::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;
|
||||
center_x = first.x + rotate_angle_cos * offset_x - rotate_angle_sin * offset_y;
|
||||
center_y = first.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 = state.angle + util::angle_between(first_x, first_y, second_x, second_y);
|
||||
|
||||
_setAngle(ang, duration);
|
||||
@@ -338,22 +333,22 @@ void Transform::setAngle(const double new_angle, const Duration& duration) {
|
||||
_setAngle(new_angle, duration);
|
||||
}
|
||||
|
||||
void Transform::setAngle(const double new_angle, const double cx, const double cy) {
|
||||
if (std::isnan(new_angle) || std::isnan(cx) || std::isnan(cy)) {
|
||||
void Transform::setAngle(const double new_angle, const PrecisionPoint& center) {
|
||||
if (std::isnan(new_angle) || !center.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LatLng rotationCenter;
|
||||
|
||||
if (cx >= 0 && cy >= 0) {
|
||||
rotationCenter = state.pointToLatLng({ cx, cy });
|
||||
if (center.x > 0 || center.y > 0) {
|
||||
rotationCenter = state.pointToLatLng(center);
|
||||
setLatLng(rotationCenter, Duration::zero());
|
||||
}
|
||||
|
||||
_setAngle(new_angle);
|
||||
|
||||
if (cx >= 0 && cy >= 0) {
|
||||
setLatLng(rotationCenter, { cx, cy }, Duration::zero());
|
||||
if (center.x > 0 && center.y > 0) {
|
||||
setLatLng(rotationCenter, center, Duration::zero());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,16 +34,16 @@ public:
|
||||
LatLng getLatLng() const { return state.getLatLng(); }
|
||||
|
||||
// Zoom
|
||||
void scaleBy(double ds, double cx = -1, double cy = -1, const Duration& = Duration::zero());
|
||||
void setScale(double scale, double cx = -1, double cy = -1, const Duration& = Duration::zero());
|
||||
void scaleBy(double ds, const PrecisionPoint& center = { 0, 0 }, const Duration& = Duration::zero());
|
||||
void setScale(double scale, const PrecisionPoint& center = { 0, 0 }, const Duration& = Duration::zero());
|
||||
void setZoom(double zoom, const Duration& = Duration::zero());
|
||||
double getZoom() const;
|
||||
double getScale() const;
|
||||
|
||||
// Angle
|
||||
void rotateBy(double sx, double sy, double ex, double ey, const Duration& = Duration::zero());
|
||||
void rotateBy(const PrecisionPoint& first, const PrecisionPoint& second, const Duration& = Duration::zero());
|
||||
void setAngle(double angle, const Duration& = Duration::zero());
|
||||
void setAngle(double angle, double cx, double cy);
|
||||
void setAngle(double angle, const PrecisionPoint& center);
|
||||
double getAngle() const;
|
||||
|
||||
// Pitch
|
||||
@@ -67,7 +67,7 @@ public:
|
||||
|
||||
private:
|
||||
void _moveBy(const PrecisionPoint&, const Duration& = Duration::zero());
|
||||
void _setScale(double scale, double cx, double cy, const Duration& = Duration::zero());
|
||||
void _setScale(double scale, const PrecisionPoint& center, const Duration& = Duration::zero());
|
||||
void _setScaleXY(double new_scale, double xn, double yn, const Duration& = Duration::zero());
|
||||
void _easeTo(const CameraOptions&, double new_scale, double new_angle, double xn, double yn);
|
||||
void _setAngle(double angle, const Duration& = Duration::zero());
|
||||
|
||||
Reference in New Issue
Block a user