X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fmath%2FSGMathTest.cxx;h=ef1f50747953e244c3454a5e0731c3422a7887ce;hb=b99f53fda3b06378668bdccd4a9d07161f263366;hp=010f9995dfddf87df7a8d5174dbb8def8aa132cb;hpb=f161f78a33b175ff0241688c276ba18c5ba9dd7b;p=simgear.git diff --git a/simgear/math/SGMathTest.cxx b/simgear/math/SGMathTest.cxx index 010f9995..ef1f5074 100644 --- a/simgear/math/SGMathTest.cxx +++ b/simgear/math/SGMathTest.cxx @@ -22,9 +22,8 @@ #include #include -#include - #include "SGMath.hxx" +#include "sg_random.h" template bool @@ -200,6 +199,34 @@ QuatTest(void) return true; } +template +bool +QuatDerivativeTest(void) +{ + for (unsigned i = 0; i < 100; ++i) { + // Generate the test case: + // Give a lower bound to the distance, so avoid testing cancelation + T dt = T(0.01) + sg_random(); + // Start with orientation o0, angular velocity av and a random stepsize + SGQuat o0 = SGQuat::fromEulerDeg(T(360)*sg_random(), T(360)*sg_random(), T(360)*sg_random()); + SGVec3 av(sg_random(), sg_random(), sg_random()); + // Do one euler step and renormalize + SGQuat o1 = normalize(o0 + dt*o0.derivative(av)); + + // Check if we can restore the angular velocity + SGVec3 av2 = SGQuat::forwardDifferenceVelocity(o0, o1, dt); + if (!equivalent(av, av2)) + return false; + + // Test with the equivalent orientation + o1 = -o1; + av2 = SGQuat::forwardDifferenceVelocity(o0, o1, dt); + if (!equivalent(av, av2)) + return false; + } + return true; +} + template bool MatrixTest(void) @@ -271,12 +298,37 @@ GeodesyTest(void) if (!equivalent(cart0, cart1)) return false; + // test course / advance routines + // uses examples from Williams aviation formulary + SGGeoc lax = SGGeoc::fromRadM(-2.066470, 0.592539, 10.0); + SGGeoc jfk = SGGeoc::fromRadM(-1.287762, 0.709186, 10.0); + + double distNm = SGGeodesy::distanceRad(lax, jfk) * SG_RAD_TO_NM; + std::cout << "distance is " << distNm << std::endl; + if (0.5 < fabs(distNm - 2144)) // 2144 nm + return false; + + double crsDeg = SGGeodesy::courseRad(lax, jfk) * SG_RADIANS_TO_DEGREES; + std::cout << "course is " << crsDeg << std::endl; + if (0.5 < fabs(crsDeg - 66)) // 66 degrees + return false; + + SGGeoc adv; + SGGeodesy::advanceRadM(lax, crsDeg * SG_DEGREES_TO_RADIANS, 100 * SG_NM_TO_METER, adv); + std::cout << "lon:" << adv.getLongitudeRad() << ", lat:" << adv.getLatitudeRad() << std::endl; + + if (0.01 < fabs(adv.getLongitudeRad() - (-2.034206)) || + 0.01 < fabs(adv.getLatitudeRad() - 0.604180)) + return false; + return true; } int main(void) { + sg_srandom(17); + // Do vector tests if (!Vec3Test()) return EXIT_FAILURE; @@ -288,6 +340,10 @@ main(void) return EXIT_FAILURE; if (!QuatTest()) return EXIT_FAILURE; + if (!QuatDerivativeTest()) + return EXIT_FAILURE; + if (!QuatDerivativeTest()) + return EXIT_FAILURE; // Do matrix tests if (!MatrixTest())