From b9a044da9cdc96b5a441d780f15ac16de3526303 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Sami=20R=C3=A4m=C3=B6?= Date: Tue, 3 Aug 2010 10:39:25 +0300 Subject: [PATCH] Fixed SceneCoordinate::azimuthTo() angle calculation - Implemented also a unit test for the method --- src/coordinates/scenecoordinate.cpp | 22 +++++++++++++- src/coordinates/scenecoordinate.h | 2 ++ .../scenecoordinate/testscenecoordinate.cpp | 30 ++++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/coordinates/scenecoordinate.cpp b/src/coordinates/scenecoordinate.cpp index c4b555e..9b423cb 100644 --- a/src/coordinates/scenecoordinate.cpp +++ b/src/coordinates/scenecoordinate.cpp @@ -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) diff --git a/src/coordinates/scenecoordinate.h b/src/coordinates/scenecoordinate.h index e1679d1..7b92159 100644 --- a/src/coordinates/scenecoordinate.h +++ b/src/coordinates/scenecoordinate.h @@ -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 */ diff --git a/tests/coordinates/scenecoordinate/testscenecoordinate.cpp b/tests/coordinates/scenecoordinate/testscenecoordinate.cpp index 2a261f8..d0e18d2 100644 --- a/tests/coordinates/scenecoordinate/testscenecoordinate.cpp +++ b/tests/coordinates/scenecoordinate/testscenecoordinate.cpp @@ -30,11 +30,16 @@ 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("to"); + QTest::addColumn("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; -- 1.7.9.5