X-Git-Url: http://git.localhorst.tv/?a=blobdiff_plain;f=tst%2Fworld%2FOrbitTest.cpp;h=3becd711371d8b4374795902d3aeb1c761ac1d32;hb=348143f5e41a5692ed7c8deab200f3c62f4395a2;hp=ea13860ea3d0d6c4d904a009124d95d3b19a1e7a;hpb=6b6827e81cd13b35249ca44fca31fe2773db6209;p=blobs.git diff --git a/tst/world/OrbitTest.cpp b/tst/world/OrbitTest.cpp index ea13860..3becd71 100644 --- a/tst/world/OrbitTest.cpp +++ b/tst/world/OrbitTest.cpp @@ -2,17 +2,17 @@ #include "../assert.hpp" -#include "const.hpp" +#include "math/const.hpp" #include "world/Orbit.hpp" -CPPUNIT_TEST_SUITE_REGISTRATION(blobs::test::world::OrbitTest); +CPPUNIT_TEST_SUITE_REGISTRATION(blobs::world::test::OrbitTest); -using blobs::world::Orbit; +using blobs::test::AssertEqual; namespace blobs { -namespace test { namespace world { +namespace test { void OrbitTest::setUp() { } @@ -21,7 +21,7 @@ void OrbitTest::tearDown() { } -void OrbitTest::testDefaultOrbit() { +void OrbitTest::testDefault() { Orbit orbit; CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( "wrong semi-major axis on default orbit", @@ -59,7 +59,7 @@ void OrbitTest::testDefaultOrbit() { // 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); + pos = orbit.Matrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); AssertEqual( "wrong position at t=90°", glm::vec3(0.0f, 0.0f, -1.0f), @@ -75,7 +75,7 @@ void OrbitTest::testDefaultOrbit() { ); // at 270° position should be (0,0,-sma) - pos = orbit.Matrix(PI_1p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + pos = orbit.Matrix(PI * 1.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); AssertEqual( "wrong position at t=270°", glm::vec3(0.0f, 0.0f, 1.0f), @@ -83,7 +83,7 @@ void OrbitTest::testDefaultOrbit() { ); // 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); + pos = orbit.Matrix(PI * 2.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); AssertEqual( "wrong position at t=360°", glm::vec3(1.0f, 0.0f, 0.0f), @@ -110,7 +110,7 @@ void OrbitTest::testSMA() { // 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); + pos = orbit.Matrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); AssertEqual( "wrong position at t=90°", glm::vec3(0.0f, 0.0f, -2.0f), @@ -126,7 +126,7 @@ void OrbitTest::testSMA() { ); // at 270° position should be (0,0,-sma) - pos = orbit.Matrix(PI_1p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + pos = orbit.Matrix(PI * 1.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); AssertEqual( "wrong position at t=270°", glm::vec3(0.0f, 0.0f, 2.0f), @@ -134,7 +134,7 @@ void OrbitTest::testSMA() { ); // 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); + pos = orbit.Matrix(PI * 2.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); AssertEqual( "wrong position at t=360°", glm::vec3(2.0f, 0.0f, 0.0f), @@ -157,7 +157,7 @@ void OrbitTest::testEcc() { glm::vec3(pos) / pos.w ); - pos = orbit.Matrix(PI_0p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + pos = orbit.Matrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); AssertEqual( "wrong position at t=90°", glm::vec3(-0.935130834579468f, 0.0f, -0.779740869998932f), @@ -171,14 +171,14 @@ void OrbitTest::testEcc() { glm::vec3(pos) / pos.w ); - pos = orbit.Matrix(PI_1p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + pos = orbit.Matrix(PI * 1.5) * 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); + pos = orbit.Matrix(PI * 2.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); AssertEqual( "wrong position at t=360°", glm::vec3(0.5f, 0.0f, 0.0f), @@ -203,7 +203,7 @@ void OrbitTest::testInc() { glm::vec3(pos) / pos.w ); - pos = orbit.Matrix(PI_0p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + pos = orbit.Matrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); AssertEqual( "wrong position at t=90°", glm::vec3(0.0f, 0.70710676908493f, -0.70710676908493f), @@ -217,14 +217,14 @@ void OrbitTest::testInc() { glm::vec3(pos) / pos.w ); - pos = orbit.Matrix(PI_1p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + pos = orbit.Matrix(PI * 1.5) * 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); + pos = orbit.Matrix(PI * 2.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); AssertEqual( "wrong position at t=360°", glm::vec3(1.0f, 0.0f, 0.0f), @@ -251,7 +251,7 @@ void OrbitTest::testLngAsc() { glm::vec3(pos) / pos.w ); - pos = orbit.Matrix(PI_0p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + pos = orbit.Matrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); AssertEqual( "wrong position at t=90°", glm::vec3(0.0f, 1.0f, 0.0f), @@ -265,14 +265,14 @@ void OrbitTest::testLngAsc() { glm::vec3(pos) / pos.w ); - pos = orbit.Matrix(PI_1p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + pos = orbit.Matrix(PI * 1.5) * 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); + pos = orbit.Matrix(PI * 2.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); AssertEqual( "wrong position at t=360°", glm::vec3(0.70710676908493f, 0.0f, -0.70710676908493f), @@ -300,7 +300,7 @@ void OrbitTest::testArgPe() { glm::vec3(pos) / pos.w ); - pos = orbit.Matrix(PI_0p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + pos = orbit.Matrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); AssertEqual( "wrong position at t=90°", glm::vec3(0.0f, 1.0f, 0.0f), @@ -314,14 +314,14 @@ void OrbitTest::testArgPe() { glm::vec3(pos) / pos.w ); - pos = orbit.Matrix(PI_1p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + pos = orbit.Matrix(PI * 1.5) * 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); + pos = orbit.Matrix(PI * 2.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); AssertEqual( "wrong position at t=360°", glm::vec3(0.70710676908493f, 0.0f, 0.70710676908493f), @@ -347,7 +347,7 @@ void OrbitTest::testMnAn() { // 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); + pos = orbit.Matrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); AssertEqual( "wrong position at t=90°", glm::vec3(-0.70710676908493f, 0.0f, -0.70710676908493f), @@ -363,7 +363,7 @@ void OrbitTest::testMnAn() { ); // at 270° position should be (0,0,-sma) - pos = orbit.Matrix(PI_1p5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + pos = orbit.Matrix(PI * 1.5) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); AssertEqual( "wrong position at t=270°", glm::vec3(0.70710676908493f, 0.0f, 0.70710676908493f), @@ -371,7 +371,7 @@ void OrbitTest::testMnAn() { ); // 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); + pos = orbit.Matrix(PI * 2.0) * glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); AssertEqual( "wrong position at t=360°", glm::vec3(0.70710676908493f, 0.0f, -0.70710676908493f), @@ -379,6 +379,312 @@ void OrbitTest::testMnAn() { ); } +void OrbitTest::testInverseDefault() { + Orbit orbit; + + // inverse matrix should project expected orbit position back to the origin + glm::vec4 pos(orbit.InverseMatrix(0.0) * glm::vec4(1.0f, 0.0f, 0.0f, 1.0f)); + AssertEqual( + "wrong position at t=0", + glm::vec3(0.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.InverseMatrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, -1.0f, 1.0f); + AssertEqual( + "wrong position at t=90°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + // at 180° position should be (-sma,0,0) + pos = orbit.InverseMatrix(PI) * glm::vec4(-1.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=180°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + // at 270° position should be (0,0,-sma) + pos = orbit.InverseMatrix(PI * 1.5) * glm::vec4(0.0f, 0.0f, 1.0f, 1.0f); + AssertEqual( + "wrong position at t=270°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + // at 360° position should be (sma,0,0), the initial position + pos = orbit.InverseMatrix(PI * 2.0) * glm::vec4(1.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=360°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); +} + +void OrbitTest::testInverseSMA() { + Orbit orbit; + orbit.SemiMajorAxis(2.0); + + // reference direction is +X, so at t=0, the body should be + // at (sma,0,0) relative to its parent + glm::vec4 pos(orbit.InverseMatrix(0.0) * glm::vec4(2.0f, 0.0f, 0.0f, 1.0f)); + AssertEqual( + "wrong position at t=0", + glm::vec3(0.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.InverseMatrix(PI * 0.5) * glm::vec4(0.0f, 0.0f, -2.0f, 1.0f); + AssertEqual( + "wrong position at t=90°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + // at 180° position should be (-sma,0,0) + pos = orbit.InverseMatrix(PI) * glm::vec4(-2.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=180°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + // at 270° position should be (0,0,-sma) + pos = orbit.InverseMatrix(PI * 1.5) * glm::vec4(0.0f, 0.0f, 2.0f, 1.0f); + AssertEqual( + "wrong position at t=270°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + // at 360° position should be (sma,0,0), the initial position + pos = orbit.InverseMatrix(PI * 2.0) * glm::vec4(2.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=360°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); +} + +void OrbitTest::testInverseEcc() { + Orbit orbit; + orbit.Eccentricity(0.5); + + glm::vec4 pos(orbit.InverseMatrix(0.0) * glm::vec4(0.5f, 0.0f, 0.0f, 1.0f)); + AssertEqual( + "wrong position at t=0", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.InverseMatrix(PI * 0.5) * glm::vec4(-0.935130834579468f, 0.0f, -0.779740869998932f, 1.0f); + AssertEqual( + "wrong position at t=90°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.InverseMatrix(PI) * glm::vec4(-1.5f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=180°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.InverseMatrix(PI * 1.5) * glm::vec4(-0.935130834579468f, 0.0f, 0.779740869998932f, 1.0f); + AssertEqual( + "wrong position at t=270°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.InverseMatrix(PI * 2.0) * glm::vec4(0.5f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=360°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); +} + +void OrbitTest::testInverseInc() { + Orbit orbit; + orbit.Inclination(PI * 0.25); // 45° + + // inclination rotates counter clockwise around +X, so at t=0 should be + // at (sma,0,0) relative to its parent + glm::vec4 pos(orbit.InverseMatrix(0.0) * glm::vec4(1.0f, 0.0f, 0.0f, 1.0f)); + AssertEqual( + "wrong position at t=0", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.InverseMatrix(PI * 0.5) * glm::vec4(0.0f, 0.70710676908493f, -0.70710676908493f, 1.0f); + AssertEqual( + "wrong position at t=90°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.InverseMatrix(PI) * glm::vec4(-1.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=180°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.InverseMatrix(PI * 1.5) * glm::vec4(0.0f, -0.70710676908493f, 0.70710676908493f, 1.0f); + AssertEqual( + "wrong position at t=270°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.InverseMatrix(PI * 2.0) * glm::vec4(1.0f, 0.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=360°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); +} + +void OrbitTest::testInverseLngAsc() { + Orbit orbit; + orbit.LongitudeAscending(PI * 0.25); // 45° + 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.InverseMatrix(0.0) * glm::vec4(0.70710676908493f, 0.0f, -0.70710676908493f, 1.0f)); + AssertEqual( + "wrong position at t=0", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.InverseMatrix(PI * 0.5) * glm::vec4(0.0f, 1.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=90°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.InverseMatrix(PI) * glm::vec4(-0.70710676908493f, 0.0f, 0.70710676908493f, 1.0f); + AssertEqual( + "wrong position at t=180°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.InverseMatrix(PI * 1.5) * glm::vec4(0.0f, -1.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=270°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.InverseMatrix(PI * 2.0) * glm::vec4(0.70710676908493f, 0.0f, -0.70710676908493f, 1.0f); + AssertEqual( + "wrong position at t=360°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); +} + +void OrbitTest::testInverseArgPe() { + Orbit orbit; + orbit.ArgumentPeriapsis(PI * 0.25); // 45° + 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.InverseMatrix(0.0) * glm::vec4(0.70710676908493f, 0.0f, 0.70710676908493f, 1.0f)); + AssertEqual( + "wrong position at t=0", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.InverseMatrix(PI * 0.5) * glm::vec4(0.0f, 1.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=90°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.InverseMatrix(PI) * glm::vec4(-0.70710676908493f, 0.0f, -0.70710676908493f, 1.0f); + AssertEqual( + "wrong position at t=180°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.InverseMatrix(PI * 1.5) * glm::vec4(0.0f, -1.0f, 0.0f, 1.0f); + AssertEqual( + "wrong position at t=270°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + pos = orbit.InverseMatrix(PI * 2.0) * glm::vec4(0.70710676908493f, 0.0f, 0.70710676908493f, 1.0f); + AssertEqual( + "wrong position at t=360°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); +} + +void OrbitTest::testInverseMnAn() { + Orbit orbit; + orbit.MeanAnomaly(PI * 0.25); // 45° + + // mean anomaly just phase shifts the orbit + glm::vec4 pos(orbit.InverseMatrix(0.0) * glm::vec4(0.70710676908493f, 0.0f, -0.70710676908493f, 1.0f)); + AssertEqual( + "wrong position at t=0", + glm::vec3(0.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.InverseMatrix(PI * 0.5) * glm::vec4(-0.70710676908493f, 0.0f, -0.70710676908493f, 1.0f); + AssertEqual( + "wrong position at t=90°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + // at 180° position should be (-sma,0,0) + pos = orbit.InverseMatrix(PI) * glm::vec4(-0.70710676908493f, 0.0f, 0.70710676908493f, 1.0f); + AssertEqual( + "wrong position at t=180°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + // at 270° position should be (0,0,-sma) + pos = orbit.InverseMatrix(PI * 1.5) * glm::vec4(0.70710676908493f, 0.0f, 0.70710676908493f, 1.0f); + AssertEqual( + "wrong position at t=270°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); + + // at 360° position should be (sma,0,0), the initial position + pos = orbit.InverseMatrix(PI * 2.0) * glm::vec4(0.70710676908493f, 0.0f, -0.70710676908493f, 1.0f); + AssertEqual( + "wrong position at t=360°", + glm::vec3(0.0f, 0.0f, 0.0f), + glm::vec3(pos) / pos.w + ); +} } } }