From: Daniel Karbach Date: Sun, 12 Nov 2017 22:04:00 +0000 (+0100) Subject: basic orbit tests X-Git-Url: http://git.localhorst.tv/?p=blobs.git;a=commitdiff_plain;h=6b6827e81cd13b35249ca44fca31fe2773db6209 basic orbit tests --- diff --git a/tst/world/OrbitTest.cpp b/tst/world/OrbitTest.cpp index e4c96a0..ea13860 100644 --- a/tst/world/OrbitTest.cpp +++ b/tst/world/OrbitTest.cpp @@ -21,13 +21,32 @@ void OrbitTest::tearDown() { } -void OrbitTest::testSMA() { +void OrbitTest::testDefaultOrbit() { Orbit orbit; - orbit.SemiMajorAxis(1.0); CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( - "wrong semi-major axis on orbit", + "wrong semi-major axis on default orbit", 1.0, orbit.SemiMajorAxis(), std::numeric_limits::epsilon() ); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "wrong eccentricity on default orbit", + 0.0, orbit.Eccentricity(), std::numeric_limits::epsilon() + ); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "wrong inclination on default orbit", + 0.0, orbit.Inclination(), std::numeric_limits::epsilon() + ); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "wrong longitude of ascending node on default orbit", + 0.0, orbit.LongitudeAscending(), std::numeric_limits::epsilon() + ); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "wrong argument of periapsis on default orbit", + 0.0, orbit.ArgumentPeriapsis(), std::numeric_limits::epsilon() + ); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "wrong mean anomaly on default orbit", + 0.0, orbit.MeanAnomaly(), std::numeric_limits::epsilon() + ); // reference direction is +X, so at t=0, the body should be // at (sma,0,0) relative to its parent @@ -72,6 +91,294 @@ void OrbitTest::testSMA() { ); } +void OrbitTest::testSMA() { + Orbit orbit; + orbit.SemiMajorAxis(2.0); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "wrong semi-major axis on orbit", + 2.0, orbit.SemiMajorAxis(), std::numeric_limits::epsilon() + ); + + // reference direction is +X, so at t=0, the body should be + // at (sma,0,0) relative to its parent + glm::vec4 pos(orbit.Matrix(0.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); + AssertEqual( + "wrong position at t=0", + glm::vec3(2.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + // at 90° position should be (0,0,sma) since the zero inclination + // reference plane is XZ and rotates counter-clockwise + pos = orbit.Matrix(PI_0p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=90°", + glm::vec3(0.0f, 0.0f, -2.0f), + glm::vec3(pos) / pos.w + ); + + // at 180° position should be (-sma,0,0) + pos = orbit.Matrix(PI) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=180°", + glm::vec3(-2.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + // at 270° position should be (0,0,-sma) + pos = orbit.Matrix(PI_1p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=270°", + glm::vec3(0.0f, 0.0f, 2.0f), + glm::vec3(pos) / pos.w + ); + + // at 360° position should be (sma,0,0), the initial position + pos = orbit.Matrix(PI_2p0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=360°", + glm::vec3(2.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); +} + +void OrbitTest::testEcc() { + Orbit orbit; + orbit.Eccentricity(0.5); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "wrong eccentricity on orbit", + 0.5, orbit.Eccentricity(), std::numeric_limits::epsilon() + ); + + glm::vec4 pos(orbit.Matrix(0.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); + AssertEqual( + "wrong position at t=0", + glm::vec3(0.5f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.Matrix(PI_0p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=90°", + glm::vec3(-0.935130834579468f, 0.0f, -0.779740869998932f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.Matrix(PI) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=180°", + glm::vec3(-1.5f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.Matrix(PI_1p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=270°", + glm::vec3(-0.935130834579468f, 0.0f, 0.779740869998932f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.Matrix(PI_2p0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=360°", + glm::vec3(0.5f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); +} + +void OrbitTest::testInc() { + Orbit orbit; + orbit.Inclination(PI * 0.25); // 45° + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "wrong inclination on orbit", + PI * 0.25, orbit.Inclination(), std::numeric_limits::epsilon() + ); + + // inclination rotates counter clockwise around +X, so at t=0 should be + // at (sma,0,0) relative to its parent + glm::vec4 pos(orbit.Matrix(0.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); + AssertEqual( + "wrong position at t=0", + glm::vec3(1.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.Matrix(PI_0p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=90°", + glm::vec3(0.0f, 0.70710676908493f, -0.70710676908493f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.Matrix(PI) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=180°", + glm::vec3(-1.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.Matrix(PI_1p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=270°", + glm::vec3(0.0f, -0.70710676908493f, 0.70710676908493f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.Matrix(PI_2p0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=360°", + glm::vec3(1.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); +} + +void OrbitTest::testLngAsc() { + Orbit orbit; + orbit.LongitudeAscending(PI * 0.25); // 45° + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "wrong longitude of ascending node on orbit", + PI * 0.25, orbit.LongitudeAscending(), std::numeric_limits::epsilon() + ); + // using an inclination of 90° as well to make the rotation more apparent + orbit.Inclination(PI * 0.5); + + // inclination rotates counter clockwise around +X, while LAN rotates it + // around +Y, so at t=0 should be at (sma*sin(45°),0,-sma*cos(45°)) + glm::vec4 pos(orbit.Matrix(0.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); + AssertEqual( + "wrong position at t=0", + glm::vec3(0.70710676908493f, 0.0f, -0.70710676908493f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.Matrix(PI_0p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=90°", + glm::vec3(0.0f, 1.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.Matrix(PI) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=180°", + glm::vec3(-0.70710676908493f, 0.0f, 0.70710676908493f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.Matrix(PI_1p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=270°", + glm::vec3(0.0f, -1.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.Matrix(PI_2p0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=360°", + glm::vec3(0.70710676908493f, 0.0f, -0.70710676908493f), + glm::vec3(pos) / pos.w + ); +} + +void OrbitTest::testArgPe() { + Orbit orbit; + orbit.ArgumentPeriapsis(PI * 0.25); // 45° + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "wrong argument of periapsis node on orbit", + PI * 0.25, orbit.ArgumentPeriapsis(), std::numeric_limits::epsilon() + ); + // using an inclination of 90° as well to make the rotation more apparent + orbit.Inclination(PI * 0.5); + + // inclination rotates counter clockwise around +X, while APe rotates it + // around +Y in the rotated coordinate system, so at t=0 should be at + // (sma*sin(45°),0,sma*cos(45°)) + glm::vec4 pos(orbit.Matrix(0.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); + AssertEqual( + "wrong position at t=0", + glm::vec3(0.70710676908493f, 0.0f, 0.70710676908493f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.Matrix(PI_0p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=90°", + glm::vec3(0.0f, 1.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.Matrix(PI) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=180°", + glm::vec3(-0.70710676908493f, 0.0f, -0.70710676908493f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.Matrix(PI_1p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=270°", + glm::vec3(0.0f, -1.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.Matrix(PI_2p0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=360°", + glm::vec3(0.70710676908493f, 0.0f, 0.70710676908493f), + glm::vec3(pos) / pos.w + ); +} + +void OrbitTest::testMnAn() { + Orbit orbit; + orbit.MeanAnomaly(PI * 0.25); // 45° + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "wrong mean anomaly on default orbit", + PI * 0.25, orbit.MeanAnomaly(), std::numeric_limits::epsilon() + ); + + // mean anomaly just phase shifts the orbit + glm::vec4 pos(orbit.Matrix(0.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f)); + AssertEqual( + "wrong position at t=0", + glm::vec3(0.70710676908493f, 0.0f, -0.70710676908493f), + glm::vec3(pos) / pos.w + ); + + // at 90° position should be (0,0,sma) since the zero inclination + // reference plane is XZ and rotates counter-clockwise + pos = orbit.Matrix(PI_0p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=90°", + glm::vec3(-0.70710676908493f, 0.0f, -0.70710676908493f), + glm::vec3(pos) / pos.w + ); + + // at 180° position should be (-sma,0,0) + pos = orbit.Matrix(PI) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=180°", + glm::vec3(-0.70710676908493f, 0.0f, 0.70710676908493f), + glm::vec3(pos) / pos.w + ); + + // at 270° position should be (0,0,-sma) + pos = orbit.Matrix(PI_1p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=270°", + glm::vec3(0.70710676908493f, 0.0f, 0.70710676908493f), + glm::vec3(pos) / pos.w + ); + + // at 360° position should be (sma,0,0), the initial position + pos = orbit.Matrix(PI_2p0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=360°", + glm::vec3(0.70710676908493f, 0.0f, -0.70710676908493f), + glm::vec3(pos) / pos.w + ); +} + } } } diff --git a/tst/world/OrbitTest.hpp b/tst/world/OrbitTest.hpp index 2710a44..3f38cce 100644 --- a/tst/world/OrbitTest.hpp +++ b/tst/world/OrbitTest.hpp @@ -13,7 +13,14 @@ class OrbitTest CPPUNIT_TEST_SUITE(OrbitTest); +CPPUNIT_TEST(testDefaultOrbit); + CPPUNIT_TEST(testSMA); +CPPUNIT_TEST(testEcc); +CPPUNIT_TEST(testInc); +CPPUNIT_TEST(testLngAsc); +CPPUNIT_TEST(testArgPe); +CPPUNIT_TEST(testMnAn); CPPUNIT_TEST_SUITE_END(); @@ -21,7 +28,14 @@ public: void setUp(); void tearDown(); + void testDefaultOrbit(); + void testSMA(); + void testEcc(); + void testInc(); + void testLngAsc(); + void testArgPe(); + void testMnAn(); };