diff options
author | Paolo Angelelli <paolo.angelelli@qt.io> | 2017-07-06 09:53:21 +0200 |
---|---|---|
committer | Paolo Angelelli <paolo.angelelli@qt.io> | 2017-07-17 12:40:30 +0000 |
commit | b02916a5568d57eda767ca930dcdb366179250bc (patch) | |
tree | a5cf227e6f70faf5b931a4a122b53f37a8a6b8cc | |
parent | d4cb4961ed0a15d0746d96da38228787658d87bd (diff) | |
download | qtlocation-b02916a5568d57eda767ca930dcdb366179250bc.tar.gz |
Fix Map.toCoordinate always clamping y values to 0
This patch allows to call toCoordinate also on negative y values, given
that the y value is still below the horizon. If not, the y value
will be clamped to the "minimum unprojectable y value", a value that
is clamped to 0.
Task-number: QTBUG-61813
Change-Id: I177d3b459b6eaf827daf860b7d4011511a7e76ee
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Reviewed-by: Paolo Angelelli <paolo.angelelli@qt.io>
-rw-r--r-- | src/location/maps/qgeoprojection.cpp | 37 | ||||
-rw-r--r-- | src/location/maps/qgeoprojection_p.h | 3 |
2 files changed, 32 insertions, 8 deletions
diff --git a/src/location/maps/qgeoprojection.cpp b/src/location/maps/qgeoprojection.cpp index 783193ed..07747a31 100644 --- a/src/location/maps/qgeoprojection.cpp +++ b/src/location/maps/qgeoprojection.cpp @@ -201,14 +201,25 @@ QDoubleVector2D QGeoProjectionWebMercator::wrappedMapProjectionToItemPosition(co QDoubleVector2D QGeoProjectionWebMercator::itemPositionToWrappedMapProjection(const QDoubleVector2D &itemPosition) const { QDoubleVector2D pos = itemPosition; - // when the camera is tilted, picking a point above the horizon returns a coordinate behind the camera - if (pos.y() < m_minimumUnprojectableY) - pos.setY(m_minimumUnprojectableY); pos *= QDoubleVector2D(m_1_viewportWidth, m_1_viewportHeight); pos *= 2.0; pos -= QDoubleVector2D(1.0,1.0); - return viewportToWrappedMapProjection(pos); + double s; + QDoubleVector2D res = viewportToWrappedMapProjection(pos, s); + + // a positive s means a point behind the camera. So do it again, after clamping Y. See QTBUG-61813 + if (s > 0.0) { + pos = itemPosition; + // when the camera is tilted, picking a point above the horizon returns a coordinate behind the camera + pos.setY(m_minimumUnprojectableY); + pos *= QDoubleVector2D(m_1_viewportWidth, m_1_viewportHeight); + pos *= 2.0; + pos -= QDoubleVector2D(1.0,1.0); + res = viewportToWrappedMapProjection(pos, s); + } + + return res; } /* Default implementations */ @@ -306,10 +317,16 @@ QList<QDoubleVector2D> QGeoProjectionWebMercator::visibleRegion() const return m_visibleRegion; } +QDoubleVector2D QGeoProjectionWebMercator::viewportToWrappedMapProjection(const QDoubleVector2D &itemPosition) const +{ + double s; + return viewportToWrappedMapProjection(itemPosition, s); +} + /* actual implementation of itemPositionToWrappedMapProjection */ -QDoubleVector2D QGeoProjectionWebMercator::viewportToWrappedMapProjection(const QDoubleVector2D &itemPosition) const +QDoubleVector2D QGeoProjectionWebMercator::viewportToWrappedMapProjection(const QDoubleVector2D &itemPosition, double &s) const { QDoubleVector2D pos = itemPosition; pos *= QDoubleVector2D(m_halfWidth, m_halfHeight); @@ -321,7 +338,7 @@ QDoubleVector2D QGeoProjectionWebMercator::viewportToWrappedMapProjection(const QDoubleVector3D ray = p - m_eye; ray.normalize(); - return (xyPlane.lineIntersection(m_eye, ray) / m_sideLength).toVector2D(); + return (xyPlane.lineIntersection(m_eye, ray, s) / m_sideLength).toVector2D(); } void QGeoProjectionWebMercator::setupCamera() @@ -528,9 +545,15 @@ QGeoProjectionWebMercator::Plane::Plane(const QDoubleVector3D &planePoint, const QDoubleVector3D QGeoProjectionWebMercator::Plane::lineIntersection(const QDoubleVector3D &linePoint, const QDoubleVector3D &lineDirection) const { + double s; + return lineIntersection(linePoint, lineDirection, s); +} + +QDoubleVector3D QGeoProjectionWebMercator::Plane::lineIntersection(const QDoubleVector3D &linePoint, const QDoubleVector3D &lineDirection, double &s) const +{ QDoubleVector3D w = linePoint - m_point; // s = -n.dot(w) / n.dot(u). p = p0 + su; u is lineDirection - double s = QDoubleVector3D::dotProduct(-m_normal, w) / QDoubleVector3D::dotProduct(m_normal, lineDirection); + s = QDoubleVector3D::dotProduct(-m_normal, w) / QDoubleVector3D::dotProduct(m_normal, lineDirection); return linePoint + lineDirection * s; } diff --git a/src/location/maps/qgeoprojection_p.h b/src/location/maps/qgeoprojection_p.h index 3a0dec1d..7d306eea 100644 --- a/src/location/maps/qgeoprojection_p.h +++ b/src/location/maps/qgeoprojection_p.h @@ -128,7 +128,7 @@ public: QList<QDoubleVector2D> visibleRegion() const Q_DECL_OVERRIDE; inline QDoubleVector2D viewportToWrappedMapProjection(const QDoubleVector2D &itemPosition) const; - + inline QDoubleVector2D viewportToWrappedMapProjection(const QDoubleVector2D &itemPosition, double &s) const; private: void setupCamera(); void updateVisibleRegion(); @@ -151,6 +151,7 @@ public: Plane(const QDoubleVector3D &planePoint, const QDoubleVector3D &planeNormal); QDoubleVector3D lineIntersection(const QDoubleVector3D &linePoint, const QDoubleVector3D &lineDirection) const; + inline QDoubleVector3D lineIntersection(const QDoubleVector3D &linePoint, const QDoubleVector3D &lineDirection, double &s) const; Line2D planeXYIntersection() const; bool isValid() const; |