Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
Rotation3D.cxx
Go to the documentation of this file.
1// @(#)root/mathcore:$Id$
2// Authors: W. Brown, M. Fischler, L. Moneta 2005
3
4/**********************************************************************
5 * *
6 * Copyright (c) 2005 , LCG ROOT FNAL MathLib Team *
7 * *
8 * *
9 **********************************************************************/
10
11// Header file for class Rotation in 3 dimensions, represented by 3x3 matrix
12//
13// Created by: Mark Fischler Tues July 5 2005
14//
16
17#include <cmath>
18#include <algorithm>
19
22
24
26
27namespace ROOT {
28
29namespace ROOT_MATH_ARCH {
30
31// ========== Constructors and Assignment =====================
32
34{
35 // constructor of a identity rotation
36 fM[kXX] = 1.0;
37 fM[kXY] = 0.0;
38 fM[kXZ] = 0.0;
39 fM[kYX] = 0.0;
40 fM[kYY] = 1.0;
41 fM[kYZ] = 0.0;
42 fM[kZX] = 0.0;
43 fM[kZY] = 0.0;
44 fM[kZZ] = 1.0;
45}
46
48{
49 // rectify rotation matrix (make orthogonal)
50 // The "nearest" orthogonal matrix X to a nearly-orthogonal matrix A
51 // (in the sense that X is exactly orthogonal and the sum of the squares
52 // of the element differences X-A is as small as possible) is given by
53 // X = A * inverse(sqrt(A.transpose()*A.inverse())).
54
55 // Step 1 -- form symmetric M = A.transpose * A
56
57 double m11 = fM[kXX] * fM[kXX] + fM[kYX] * fM[kYX] + fM[kZX] * fM[kZX];
58 double m12 = fM[kXX] * fM[kXY] + fM[kYX] * fM[kYY] + fM[kZX] * fM[kZY];
59 double m13 = fM[kXX] * fM[kXZ] + fM[kYX] * fM[kYZ] + fM[kZX] * fM[kZZ];
60 double m22 = fM[kXY] * fM[kXY] + fM[kYY] * fM[kYY] + fM[kZY] * fM[kZY];
61 double m23 = fM[kXY] * fM[kXZ] + fM[kYY] * fM[kYZ] + fM[kZY] * fM[kZZ];
62 double m33 = fM[kXZ] * fM[kXZ] + fM[kYZ] * fM[kYZ] + fM[kZZ] * fM[kZZ];
63
64 // Step 2 -- find lower-triangular U such that U * U.transpose = M
65
66 double u11 = math_sqrt(m11);
67 double u21 = m12 / u11;
68 double u31 = m13 / u11;
69 double u22 = math_sqrt(m22 - u21 * u21);
70 double u32 = (m23 - m12 * m13 / m11) / u22;
71 double u33 = math_sqrt(m33 - u31 * u31 - u32 * u32);
72
73 // Step 3 -- find V such that V*V = U. U is also lower-triangular
74
75 double v33 = 1 / u33;
76 double v32 = -v33 * u32 / u22;
77 double v31 = -(v32 * u21 + v33 * u31) / u11;
78 double v22 = 1 / u22;
79 double v21 = -v22 * u21 / u11;
80 double v11 = 1 / u11;
81
82 // Step 4 -- N = V.transpose * V is inverse(sqrt(A.transpose()*A.inverse()))
83
84 double n11 = v11 * v11 + v21 * v21 + v31 * v31;
85 double n12 = v11 * v21 + v21 * v22 + v31 * v32;
86 double n13 = v11 * v31 + v21 * v32 + v31 * v33;
87 double n22 = v21 * v21 + v22 * v22 + v32 * v32;
88 double n23 = v21 * v31 + v22 * v32 + v32 * v33;
89 double n33 = v31 * v31 + v32 * v32 + v33 * v33;
90
91 // Step 5 -- The new matrix is A * N
92
93 double mA[9];
94 for (size_t i = 0; i < 9; i++) {
95 mA[i] = fM[i];
96 }
97
98 fM[kXX] = mA[kXX] * n11 + mA[kXY] * n12 + mA[kXZ] * n13;
99 fM[kXY] = mA[kXX] * n12 + mA[kXY] * n22 + mA[kXZ] * n23;
100 fM[kXZ] = mA[kXX] * n13 + mA[kXY] * n23 + mA[kXZ] * n33;
101 fM[kYX] = mA[kYX] * n11 + mA[kYY] * n12 + mA[kYZ] * n13;
102 fM[kYY] = mA[kYX] * n12 + mA[kYY] * n22 + mA[kYZ] * n23;
103 fM[kYZ] = mA[kYX] * n13 + mA[kYY] * n23 + mA[kYZ] * n33;
104 fM[kZX] = mA[kZX] * n11 + mA[kZY] * n12 + mA[kZZ] * n13;
105 fM[kZY] = mA[kZX] * n12 + mA[kZY] * n22 + mA[kZZ] * n23;
106 fM[kZZ] = mA[kZX] * n13 + mA[kZY] * n23 + mA[kZZ] * n33;
107
108} // Rectify()
109
110static inline void swap(double &a, double &b)
111{
112 // swap two values
113 double t = b;
114 b = a;
115 a = t;
116}
117
119{
120 // invert a rotation
121 swap(fM[kXY], fM[kYX]);
122 swap(fM[kXZ], fM[kZX]);
123 swap(fM[kYZ], fM[kZY]);
124}
125
127{
128 // combine with an AxisAngle rotation
129 return operator*(Rotation3D(a));
130}
131
133{
134 // combine with an EulerAngles rotation
135 return operator*(Rotation3D(e));
136}
137
139{
140 // combine with a Quaternion rotation
141 return operator*(Rotation3D(q));
142}
143
145{
146 // combine with a RotastionZYX rotation
147 return operator*(Rotation3D(r));
148}
149
150#if !defined(ROOT_MATH_SYCL) && !defined(ROOT_MATH_CUDA)
151
152std::ostream &operator<<(std::ostream &os, const Rotation3D &r)
153{
154 // TODO - this will need changing for machine-readable issues
155 // and even the human readable form needs formatting improvements
156 double m[9];
157 r.GetComponents(m, m + 9);
158 os << "\n" << m[0] << " " << m[1] << " " << m[2];
159 os << "\n" << m[3] << " " << m[4] << " " << m[5];
160 os << "\n" << m[6] << " " << m[7] << " " << m[8] << "\n";
161 return os;
162}
163
164#endif
165
166} // namespace ROOT_MATH_ARCH
167} // namespace ROOT
#define b(i)
Definition RSha256.hxx:100
#define a(i)
Definition RSha256.hxx:99
#define e(i)
Definition RSha256.hxx:103
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
float * q
AxisAngle class describing rotation represented with direction axis (3D Vector) and an angle of rotat...
Definition AxisAngle.h:46
EulerAngles class describing rotation as three angles (Euler Angles).
Definition EulerAngles.h:50
Rotation class with the (3D) rotation represented by a unit quaternion (u, i, j, k).
Definition Quaternion.h:52
Rotation class with the (3D) rotation represented by a 3x3 orthogonal matrix.
Definition Rotation3D.h:71
void Invert()
Invert a rotation in place.
void Rectify()
Re-adjust components to eliminate small deviations from perfect orthonormality.
Rotation3D()
Default constructor (identity rotation)
AVector operator*(const AVector &v) const
Overload operator * for rotation on a vector.
Definition Rotation3D.h:445
Rotation class with the (3D) rotation represented by angles describing first a rotation of an angle p...
Definition RotationZYX.h:64
static void swap(double &a, double &b)
Scalar math_sqrt(Scalar x)
std::ostream & operator<<(std::ostream &os, const AxisAngle &a)
Stream Output and Input.
Definition AxisAngle.cxx:98
TMarker m
Definition textangle.C:8