OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
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 
39 // Class Rotation3D
40 // ------------------------------------------------------------------------
41 
42 Rotation3D::Rotation3D(double vx, double vy, double vz):
43  R() {
44  double phi = sqrt(vx * vx + vy * vy + vz * vz);
45 
46  if(phi != 0.0) {
47  double factor = sin(phi / 2.0) / phi;
48  double S0 = cos(phi / 2.0);
49  double S1 = factor * vx;
50  double S2 = factor * vy;
51  double S3 = factor * vz;
52 
53  R(0, 0) = 2.0 * (S1 * S1 + S0 * S0) - 1.0;
54  R(0, 1) = 2.0 * (S1 * S2 - S0 * S3);
55  R(0, 2) = 2.0 * (S1 * S3 + S0 * S2);
56 
57  R(1, 0) = 2.0 * (S2 * S1 + S0 * S3);
58  R(1, 1) = 2.0 * (S2 * S2 + S0 * S0) - 1.0;
59  R(1, 2) = 2.0 * (S2 * S3 - S0 * S1);
60 
61  R(2, 0) = 2.0 * (S3 * S1 - S0 * S2);
62  R(2, 1) = 2.0 * (S3 * S2 + S0 * S1);
63  R(2, 2) = 2.0 * (S3 * S3 + S0 * S0) - 1.0;
64  }
65 }
66 
67 
68 void Rotation3D::getAxis(double &vx, double &vy, double &vz) const {
69  vx = (R(2, 1) - R(1, 2)) / 2.0;
70  vy = (R(0, 2) - R(2, 0)) / 2.0;
71  vz = (R(1, 0) - R(0, 1)) / 2.0;
72  double c = (R(0, 0) + R(1, 1) + R(2, 2) - 1.0) / 2.0;
73  double s = sqrt(vx * vx + vy * vy + vz * vz);
74  double phi = atan2(s, c);
75 
76  if(c < 0.0) {
77  // NOTE: We must avoid negative arguments to sqrt(),
78  // which may occur due to rounding errors.
79  vx = (vx > 0.0 ? phi : (-phi)) * sqrt(std::max(R(0, 0) - c, 0.0) / (1.0 - c));
80  vy = (vy > 0.0 ? phi : (-phi)) * sqrt(std::max(R(1, 1) - c, 0.0) / (1.0 - c));
81  vz = (vz > 0.0 ? phi : (-phi)) * sqrt(std::max(R(2, 2) - c, 0.0) / (1.0 - c));
82  } else if(std::abs(s) > 1.0e-10) {
83  double factor = phi / s;
84  vx *= factor;
85  vy *= factor;
86  vz *= factor;
87  }
88 }
89 
90 
92  double vx, vy, vz;
93  getAxis(vx, vy, vz);
94  return Vector3D(vx, vy, vz);
95 }
96 
97 
99  Rotation3D inv;
100 
101  for(int i = 0; i < 3; i++) {
102  for(int j = 0; j < 3; j++) {
103  inv.R(i, j) = R(j, i);
104  }
105  }
106 
107  return inv;
108 }
109 
110 
112  return (R(0, 1) == 0.0) && (R(1, 0) == 0.0) && (R(0, 2) == 0.0) && (R(2, 0) == 0.0);
113 }
114 
115 
117  return (R(1, 2) == 0.0) && (R(2, 1) == 0.0) && (R(1, 0) == 0.0) && (R(0, 1) == 0.0);
118 }
119 
120 
122  return (R(2, 0) == 0.0) && (R(0, 2) == 0.0) && (R(2, 1) == 0.0) && (R(1, 2) == 0.0);
123 }
124 
125 
127  return Rotation3D();
128 }
129 
130 
132  Rotation3D result;
133  result.R(1, 1) = result.R(2, 2) = cos(angle);
134  result.R(1, 2) = - (result.R(2, 1) = sin(angle));
135  return result;
136 }
137 
138 
140  Rotation3D result;
141  result.R(2, 2) = result.R(0, 0) = cos(angle);
142  result.R(2, 0) = - (result.R(0, 2) = sin(angle));
143  return result;
144 }
145 
146 
148  Rotation3D result;
149  result.R(0, 0) = result.R(1, 1) = cos(angle);
150  result.R(0, 1) = - (result.R(1, 0) = sin(angle));
151  return result;
152 }
bool isPureYRotation() const
Test for rotation.
Definition: Rotation3D.cpp:116
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
constexpr double e
The value of .
Definition: Physics.h:40
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:123
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
Rotation3D inverse() const
Inversion.
Definition: Rotation3D.cpp:98
bool isPureZRotation() const
Test for rotation.
Definition: Rotation3D.cpp:121
static Rotation3D Identity()
Make identity.
Definition: Rotation3D.cpp:126
Rotation3D()
Default constructor.
Definition: Rotation3D.h:126
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:52
Matrix3D R
Definition: Rotation3D.h:119
bool isPureXRotation() const
Test for rotation.
Definition: Rotation3D.cpp:111
static Rotation3D ZRotation(double angle)
Make rotation.
Definition: Rotation3D.cpp:147
PETE_TBTree< FnArcTan2, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > atan2(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
A 3-dimension vector.
Definition: Vector3D.h:31
static Rotation3D YRotation(double angle)
Make rotation.
Definition: Rotation3D.cpp:139
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
static Rotation3D XRotation(double angle)
Make rotation.
Definition: Rotation3D.cpp:131
Rotation in 3-dimensional space.
Definition: Rotation3D.h:46
Vector3D getAxis() const
Get axis vector.
Definition: Rotation3D.cpp:91