Newer
Older
ralfulrich
committed
#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one
// cpp file
#include <corsika/geometry/CoordinateSystem.h>
#include <corsika/geometry/Helix.h>
#include <corsika/geometry/LineTrajectory.h>
#include <corsika/geometry/Point.h>
#include <corsika/geometry/Sphere.h>
#include <corsika/geometry/Trajectory.h>
#include <corsika/units/PhysicalUnits.h>
using namespace corsika::geometry;
using namespace corsika::units;
TEST_CASE("transformations between CoordinateSystems") {
CoordinateSystem rootCS;
REQUIRE(CoordinateSystem::GetTransformation(rootCS, rootCS)
.isApprox(EigenTransform::Identity()));
corsika::QuantityVector<length_d> const coordinates{0_m, 0_m, 0_m};
Point p1(rootCS, coordinates);
ralfulrich
committed
corsika::QuantityVector<magnetic_flux_density_d> components{1. * tesla, 0. * tesla,
0. * tesla};
Vector<magnetic_flux_density_d> v1(rootCS, components);
ralfulrich
committed
REQUIRE((p1.GetCoordinates() - coordinates).norm().magnitude() == Approx(0));
REQUIRE((p1.GetCoordinates(rootCS) - coordinates).norm().magnitude() == Approx(0));
SECTION("unconnected CoordinateSystems") {
CoordinateSystem rootCS2;
REQUIRE_THROWS(CoordinateSystem::GetTransformation(rootCS, rootCS2));
}
SECTION("translations") {
corsika::QuantityVector<length_d> const translationVector{0_m, 4_m, 0_m};
CoordinateSystem translatedCS = rootCS.translate(translationVector);
REQUIRE(translatedCS.GetReference() == &rootCS);
REQUIRE((p1.GetCoordinates(translatedCS) + translationVector).norm().magnitude() ==
Approx(0));
// Vectors are not subject to translations
REQUIRE(
(v1.GetComponents(rootCS) - v1.GetComponents(translatedCS)).norm().magnitude() ==
Approx(0));
Point p2(translatedCS, {0_m, 0_m, 0_m});
REQUIRE(((p2 - p1).GetComponents() - translationVector).norm().magnitude() ==
Approx(0));
}
SECTION("multiple translations") {
corsika::QuantityVector<length_d> const tv1{0_m, 5_m, 0_m};
CoordinateSystem cs2 = rootCS.translate(tv1);
corsika::QuantityVector<length_d> const tv2{3_m, 0_m, 0_m};
CoordinateSystem cs3 = rootCS.translate(tv2);
corsika::QuantityVector<length_d> const tv3{0_m, 0_m, 2_m};
CoordinateSystem cs4 = cs3.translate(tv3);
REQUIRE(cs4.GetReference()->GetReference() == &rootCS);
REQUIRE(CoordinateSystem::GetTransformation(cs3, cs2).isApprox(
rootCS.translate({3_m, -5_m, 0_m}).GetTransform()));
REQUIRE(CoordinateSystem::GetTransformation(cs2, cs3).isApprox(
rootCS.translate({-3_m, +5_m, 0_m}).GetTransform()));
}
SECTION("rotations") {
corsika::QuantityVector<length_d> const axis{0_m, 0_m, 1_km};
double const angle = 90. / 180. * M_PI;
CoordinateSystem rotatedCS = rootCS.rotate(axis, angle);
REQUIRE(rotatedCS.GetReference() == &rootCS);
REQUIRE(v1.GetComponents(rotatedCS)[1].magnitude() ==
Approx((-1. * tesla).magnitude()));
// vector norm invariant under rotation
REQUIRE(v1.GetComponents(rotatedCS).norm().magnitude() ==
Approx(v1.GetComponents(rootCS).norm().magnitude()));
}
SECTION("multiple rotations") {
corsika::QuantityVector<length_d> const zAxis{0_m, 0_m, 1_km};
corsika::QuantityVector<length_d> const yAxis{0_m, 7_nm, 0_m};
corsika::QuantityVector<length_d> const xAxis{2_m, 0_nm, 0_m};
double const angle = 90. / 180. * M_PI;
CoordinateSystem rotated1 = rootCS.rotate(zAxis, angle);
CoordinateSystem rotated2 = rotated1.rotate(yAxis, angle);
CoordinateSystem rotated3 = rotated2.rotate(zAxis, -angle);
CoordinateSystem combined = rootCS.rotate(xAxis, -angle);
auto comp1 = v1.GetComponents(rootCS);
auto comp3 = v1.GetComponents(combined);
REQUIRE((comp1 - comp3).norm().magnitude() == Approx(0));
}
CoordinateSystem rootCS;
Point center(rootCS, {0_m, 3_m, 4_m});
Sphere sphere(center, 5_m);
SECTION("isInside") {
REQUIRE_FALSE(sphere.isInside(Point(rootCS, {100_m, 0_m, 0_m})));
REQUIRE(sphere.isInside(Point(rootCS, {2_m, 3_m, 4_m})));
}
TEST_CASE("Trajectories") {
CoordinateSystem rootCS;
Point r0(rootCS, {0_m, 0_m, 0_m});
SECTION("Line") {
Vector<SpeedType::dimension_type> v0(rootCS,
{1_m / second, 0_m / second, 0_m / second});
LineTrajectory lineTrajectory(r0, v0);
REQUIRE((lineTrajectory.GetPosition(2_s).GetCoordinates() -
corsika::QuantityVector<length_d>(2_m, 0_m, 0_m))
.norm()
.magnitude() == Approx(0));
BaseTrajectory* base = &lineTrajectory;
REQUIRE(lineTrajectory.GetPosition(2_s).GetCoordinates() ==
base->GetPosition(2_s).GetCoordinates());
}
}