OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
Rotation3D.cpp
Go to the documentation of this file.
1// ------------------------------------------------------------------------
2// $RCSfile: Rotation3D.cpp,v $
3// ------------------------------------------------------------------------
4// $Revision: 1.2 $
5// ------------------------------------------------------------------------
6// Copyright: see Copyright.readme
7// ------------------------------------------------------------------------
8//
9// Class: Rotation3D
10// Represents a rotation in 3-dimensional space.
11//
12// There are two possible external representations:
13//
14// - Matrix3D R.
15// The matrix R is an element of SO(3). Its column vectors define the
16// unit vectors of the rotated coordinate system, expressed in the
17// original system. This representation is used internally and can only
18// be read from a Rotation3D object. To build such an object, use the
19// other representation.
20//
21// - Vector3D V.
22// The direction of V defines the axis of rotation, and its length the
23// rotation angle. A zero vector represents the identity.
24//
25// ------------------------------------------------------------------------
26// Class category: BeamlineGeometry
27// ------------------------------------------------------------------------
28//
29// $Date: 2001/08/24 19:32:00 $
30// $Author: jsberg $
31//
32// ------------------------------------------------------------------------
33
35#include <algorithm>
36#include <cmath>
37
38// Class Rotation3D
39// ------------------------------------------------------------------------
40
41Rotation3D::Rotation3D(double vx, double vy, double vz) : R() {
42 double phi = std::sqrt(vx * vx + vy * vy + vz * vz);
43
44 if (phi != 0.0) {
45 double factor = std::sin(phi / 2.0) / phi;
46 double S0 = std::cos(phi / 2.0);
47 double S1 = factor * vx;
48 double S2 = factor * vy;
49 double S3 = factor * vz;
50
51 R(0, 0) = 2.0 * (S1 * S1 + S0 * S0) - 1.0;
52 R(0, 1) = 2.0 * (S1 * S2 - S0 * S3);
53 R(0, 2) = 2.0 * (S1 * S3 + S0 * S2);
54
55 R(1, 0) = 2.0 * (S2 * S1 + S0 * S3);
56 R(1, 1) = 2.0 * (S2 * S2 + S0 * S0) - 1.0;
57 R(1, 2) = 2.0 * (S2 * S3 - S0 * S1);
58
59 R(2, 0) = 2.0 * (S3 * S1 - S0 * S2);
60 R(2, 1) = 2.0 * (S3 * S2 + S0 * S1);
61 R(2, 2) = 2.0 * (S3 * S3 + S0 * S0) - 1.0;
62 }
63}
64
65void Rotation3D::getAxis(double& vx, double& vy, double& vz) const {
66 vx = (R(2, 1) - R(1, 2)) / 2.0;
67 vy = (R(0, 2) - R(2, 0)) / 2.0;
68 vz = (R(1, 0) - R(0, 1)) / 2.0;
69 double c = (R(0, 0) + R(1, 1) + R(2, 2) - 1.0) / 2.0;
70 double s = std::sqrt(vx * vx + vy * vy + vz * vz);
71 double phi = std::atan2(s, c);
72
73 if (c < 0.0) {
74 // NOTE: We must avoid negative arguments to sqrt(),
75 // which may occur due to rounding errors.
76 vx = (vx > 0.0 ? phi : (-phi)) * std::sqrt(std::max(R(0, 0) - c, 0.0) / (1.0 - c));
77 vy = (vy > 0.0 ? phi : (-phi)) * std::sqrt(std::max(R(1, 1) - c, 0.0) / (1.0 - c));
78 vz = (vz > 0.0 ? phi : (-phi)) * std::sqrt(std::max(R(2, 2) - c, 0.0) / (1.0 - c));
79 } else if (std::abs(s) > 1.0e-10) {
80 double factor = phi / s;
81 vx *= factor;
82 vy *= factor;
83 vz *= factor;
84 }
85}
86
88 double vx, vy, vz;
89 getAxis(vx, vy, vz);
90 return Vector3D(vx, vy, vz);
91}
92
94 Rotation3D inv;
95
96 for (int i = 0; i < 3; i++) {
97 for (int j = 0; j < 3; j++) {
98 inv.R(i, j) = R(j, i);
99 }
100 }
101
102 return inv;
103}
104
106 return (R(0, 1) == 0.0) && (R(1, 0) == 0.0) && (R(0, 2) == 0.0) && (R(2, 0) == 0.0);
107}
108
110 return (R(1, 2) == 0.0) && (R(2, 1) == 0.0) && (R(1, 0) == 0.0) && (R(0, 1) == 0.0);
111}
112
114 return (R(2, 0) == 0.0) && (R(0, 2) == 0.0) && (R(2, 1) == 0.0) && (R(1, 2) == 0.0);
115}
116
118
120 Rotation3D result;
121 result.R(1, 1) = result.R(2, 2) = std::cos(angle);
122 result.R(1, 2) = -(result.R(2, 1) = std::sin(angle));
123 return result;
124}
125
127 Rotation3D result;
128 result.R(2, 2) = result.R(0, 0) = std::cos(angle);
129 result.R(2, 0) = -(result.R(0, 2) = std::sin(angle));
130 return result;
131}
132
134 Rotation3D result;
135 result.R(0, 0) = result.R(1, 1) = std::cos(angle);
136 result.R(0, 1) = -(result.R(1, 0) = std::sin(angle));
137 return result;
138}
Rotation in 3-dimensional space.
Definition Rotation3D.h:45
static Rotation3D Identity()
Make identity.
Matrix3D R
Definition Rotation3D.h:115
static Rotation3D ZRotation(double angle)
Make rotation.
static Rotation3D YRotation(double angle)
Make rotation.
Rotation3D inverse() const
Inversion.
bool isPureXRotation() const
Test for rotation.
Vector3D getAxis() const
Get axis vector.
bool isPureZRotation() const
Test for rotation.
static Rotation3D XRotation(double angle)
Make rotation.
bool isPureYRotation() const
Test for rotation.
Rotation3D()
Default constructor.
Definition Rotation3D.h:121
A 3-dimension vector.
Definition Vector3D.h:30