OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
TestCoordinateSystemTrafo.cpp
Go to the documentation of this file.
1#include "gtest/gtest.h"
2
4#include "Ippl.h"
5
6#include <cmath>
7
8namespace {
9 constexpr double tol = 1e-12;
10
11 using Vector3 = ippl::Vector<double, 3>;
12
13 Quaternion rotationAroundX(double angle) {
14 return Quaternion(std::cos(0.5 * angle), std::sin(0.5 * angle), 0.0, 0.0);
15 }
16
17 Quaternion rotationAroundY(double angle) {
18 return Quaternion(std::cos(0.5 * angle), 0.0, std::sin(0.5 * angle), 0.0);
19 }
20
21 Quaternion rotationAroundZ(double angle) {
22 return Quaternion(std::cos(0.5 * angle), 0.0, 0.0, std::sin(0.5 * angle));
23 }
24
25 void expectVectorNear(const Vector3& actual, const Vector3& expected, double tolerance = tol) {
26 EXPECT_NEAR(actual(0), expected(0), tolerance);
27 EXPECT_NEAR(actual(1), expected(1), tolerance);
28 EXPECT_NEAR(actual(2), expected(2), tolerance);
29 }
30} // namespace
31
32class CoordinateSystemTrafoTest : public ::testing::Test {
33protected:
34 static void SetUpTestSuite() {
35 int argc = 0;
36 char** argv = nullptr;
37
38 ippl::initialize(argc, argv);
39 }
40
41 static void TearDownTestSuite() { ippl::finalize(); }
42};
43
44TEST_F(CoordinateSystemTrafoTest, DefaultConstructorIsIdentity) {
46 Vector3 point(1.0, -2.0, 3.0);
47 Vector3 vector(-4.0, 5.0, -6.0);
48
49 expectVectorNear(trafo.getOrigin(), Vector3(0.0));
50 EXPECT_DOUBLE_EQ(trafo.getRotation().real(), 1.0);
51 EXPECT_DOUBLE_EQ(trafo.getRotation()(1), 0.0);
52 EXPECT_DOUBLE_EQ(trafo.getRotation()(2), 0.0);
53 EXPECT_DOUBLE_EQ(trafo.getRotation()(3), 0.0);
54
55 expectVectorNear(trafo.transformTo(point), point);
56 expectVectorNear(trafo.transformFrom(point), point);
57 expectVectorNear(trafo.rotateTo(vector), vector);
58 expectVectorNear(trafo.rotateFrom(vector), vector);
59}
60
61TEST_F(CoordinateSystemTrafoTest, TransformRoundTrip) {
62 CoordinateSystemTrafo trafo(Vector3(1.5, -2.0, 0.75), rotationAroundZ(M_PI / 2.0));
63 Vector3 point(2.5, 3.0, -1.0);
64
65 const Vector3 local = trafo.transformTo(point);
66
67 expectVectorNear(trafo.transformFrom(local), point);
68}
69
71 CoordinateSystemTrafo trafo(Vector3(3.0, -1.0, 2.0), rotationAroundY(M_PI / 3.0));
72 Vector3 vector(1.0, -4.0, 2.0);
73
74 const Vector3 local = trafo.rotateTo(vector);
75
76 expectVectorNear(trafo.rotateFrom(local), vector);
77}
78
79TEST_F(CoordinateSystemTrafoTest, InverseMatchesTransformFromAndRotateFrom) {
80 CoordinateSystemTrafo trafo(Vector3(-1.0, 2.0, 4.0), rotationAroundX(M_PI / 4.0));
81 CoordinateSystemTrafo inverse = trafo.inverted();
82 Vector3 point(3.0, -2.0, 0.5);
83 Vector3 vector(-1.0, 5.0, 2.0);
84
85 expectVectorNear(inverse.transformTo(trafo.transformTo(point)), point);
86 expectVectorNear(inverse.transformTo(point), trafo.transformFrom(point));
87 expectVectorNear(inverse.rotateTo(vector), trafo.rotateFrom(vector));
88}
89
90TEST_F(CoordinateSystemTrafoTest, InvertInPlaceMatchesInverted) {
91 CoordinateSystemTrafo trafo(Vector3(0.5, -1.5, 2.5), rotationAroundY(M_PI / 5.0));
92 CoordinateSystemTrafo inverse = trafo.inverted();
93
94 trafo.invert();
95
96 expectVectorNear(trafo.getOrigin(), inverse.getOrigin());
97 EXPECT_NEAR(trafo.getRotation().real(), inverse.getRotation().real(), tol);
98 EXPECT_NEAR(trafo.getRotation()(1), inverse.getRotation()(1), tol);
99 EXPECT_NEAR(trafo.getRotation()(2), inverse.getRotation()(2), tol);
100 EXPECT_NEAR(trafo.getRotation()(3), inverse.getRotation()(3), tol);
101}
102
103TEST_F(CoordinateSystemTrafoTest, CompositionAppliesRightThenLeftToPoints) {
104 CoordinateSystemTrafo left(Vector3(2.0, 0.0, 1.0), rotationAroundZ(M_PI / 2.0));
105 CoordinateSystemTrafo right(Vector3(-1.0, 3.0, 0.5), rotationAroundX(M_PI / 6.0));
106 CoordinateSystemTrafo composed = left * right;
107 Vector3 point(4.0, -2.0, 1.0);
108
109 expectVectorNear(composed.transformTo(point), left.transformTo(right.transformTo(point)));
110}
111
112TEST_F(CoordinateSystemTrafoTest, CompositionAppliesRightThenLeftToVectors) {
113 CoordinateSystemTrafo left(Vector3(1.0, -2.0, 0.0), rotationAroundY(M_PI / 7.0));
114 CoordinateSystemTrafo right(Vector3(0.0, 1.0, 2.0), rotationAroundZ(M_PI / 3.0));
115 CoordinateSystemTrafo composed = left * right;
116 Vector3 vector(3.0, -1.0, 2.0);
117
118 expectVectorNear(composed.rotateTo(vector), left.rotateTo(right.rotateTo(vector)));
119}
TEST_F(CoordinateSystemTrafoTest, DefaultConstructorIsIdentity)
Rigid spatial transform between a parent frame and a local frame.
ippl::Vector< double, 3 > getOrigin() const
ippl::Vector< double, 3 > transformFrom(const ippl::Vector< double, 3 > &r) const
Map a point from the local frame back to the parent frame.
ippl::Vector< double, 3 > rotateFrom(const ippl::Vector< double, 3 > &r) const
Rotate a vector from the local frame back into the parent frame.
ippl::Vector< double, 3 > rotateTo(const ippl::Vector< double, 3 > &r) const
Rotate a vector from the parent frame into the local frame.
ippl::Vector< double, 3 > transformTo(const ippl::Vector< double, 3 > &r) const
Map a point from the parent frame to the local frame.
CoordinateSystemTrafo inverted() const
Return the inverse transform.
Quaternion getRotation() const
void invert()
Invert the transform in place.
Quaternion storage and rotation algebra used by OPALX geometry code.
double real() const
Return the scalar part .
constexpr double e
The value of.
Definition Physics.h:49