Fixed SceneCoordinate::azimuthTo() angle calculation
authorSami Rämö <sami.ramo@ixonos.com>
Tue, 3 Aug 2010 07:39:25 +0000 (10:39 +0300)
committerSami Rämö <sami.ramo@ixonos.com>
Tue, 3 Aug 2010 07:39:25 +0000 (10:39 +0300)
 - Implemented also a unit test for the method

src/coordinates/scenecoordinate.cpp
src/coordinates/scenecoordinate.h
tests/coordinates/scenecoordinate/testscenecoordinate.cpp

index c4b555e..9b423cb 100644 (file)
@@ -54,8 +54,28 @@ SceneCoordinate::SceneCoordinate(const GeoCoordinate &coordinate)
 
 qreal SceneCoordinate::azimuthTo(const SceneCoordinate &to) const
 {
+    qDebug() << __PRETTY_FUNCTION__;
+
+    // construct a line from this coordinate to target coordinate
     QLineF line = QLineF(this->toPointF(), to.toPointF());
-    return -line.angle() + 90.0;
+
+    // get the angle from the line. Because QLineF::angle() returns positive value for a
+    // counter-clockwise direction, and we want the positive value to be in clockwise direction,
+    // the value is negated
+    qreal angle = -line.angle();
+
+    // QLineF::angle() returns value which has zero at the 3 o'clock position, and we want to have
+    // the zero pointing to the north, so we have to add 90 degrees
+    angle += 90;
+
+    // QLineF::angle() returns values from -180 to 180, an we want only positive values from 0 to
+    // 360 degrees, so full 360 degrees is added if the result would otherwise be negative
+    if (angle < 0)
+        angle += 360;
+
+    Q_ASSERT_X(angle >= 0.0 && angle <= 360, "return value", "value is out of range");
+
+    return angle;
 }
 
 void SceneCoordinate::convertFrom(const GeoCoordinate &coordinate)
index e1679d1..7b92159 100644 (file)
@@ -65,6 +65,8 @@ public:
     /**
     * @brief Returns the azimuth from this coordinate to other coordinate
     *
+    * Zero is pointing to north. Returned value is from 0 to 360.
+    *
     * @param to Target coordinate
     * @returns Azimuth in degrees
     */
index 2a261f8..d0e18d2 100644 (file)
 const double X = 12.345678;
 const double Y = -89.765432;
 
+const double ORIGIN = 1000;
+const double DELTA = 500;
+
 class TestSceneCoordinate : public QObject
 {
     Q_OBJECT
 
 private Q_SLOTS:
+    void azimuthTo();
+    void azimuthTo_data();
     void constructors();
     void conversion();
     void conversion_data();
@@ -53,6 +58,31 @@ namespace QTest {
     }
 }
 
+void TestSceneCoordinate::azimuthTo()
+{
+    QFETCH(SceneCoordinate, to);
+    QFETCH(qreal, expectedAzimuth);
+
+    SceneCoordinate from(ORIGIN, ORIGIN);
+
+    QCOMPARE(from.azimuthTo(to), expectedAzimuth);
+}
+
+void TestSceneCoordinate::azimuthTo_data()
+{
+    QTest::addColumn<SceneCoordinate>("to");
+    QTest::addColumn<qreal>("expectedAzimuth");
+
+    QTest::newRow("N") <<  SceneCoordinate(ORIGIN, ORIGIN - DELTA) << 0.0;
+    QTest::newRow("NE") <<  SceneCoordinate(ORIGIN + DELTA, ORIGIN - DELTA) << 45.0;
+    QTest::newRow("E") <<  SceneCoordinate(ORIGIN + DELTA, ORIGIN) << 90.0;
+    QTest::newRow("SE") <<  SceneCoordinate(ORIGIN + DELTA, ORIGIN + DELTA) << 135.0;
+    QTest::newRow("S") <<  SceneCoordinate(ORIGIN, ORIGIN + DELTA) << 180.0;
+    QTest::newRow("SW") <<  SceneCoordinate(ORIGIN - DELTA, ORIGIN + DELTA) << 225.0;
+    QTest::newRow("W") <<  SceneCoordinate(ORIGIN - DELTA, ORIGIN) << 270.0;
+    QTest::newRow("NW") <<  SceneCoordinate(ORIGIN - DELTA, ORIGIN - DELTA) << 315.0;
+}
+
 void TestSceneCoordinate::constructors()
 {
     SceneCoordinate coordinate;