Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
Rotation3D.h
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 Thurs June 9 2005
14//
15// Last update: $Id$
16//
17#ifndef ROOT_MathX_GenVectorX_Rotation3D
18#define ROOT_MathX_GenVectorX_Rotation3D 1
19
27
35
37
38#include <algorithm>
39#include <cassert>
40#include <iostream>
41
43
45
46using namespace ROOT::ROOT_MATH_ARCH;
47
48namespace ROOT {
49namespace ROOT_MATH_ARCH {
50
51//__________________________________________________________________________________________
52/**
53 Rotation class with the (3D) rotation represented by
54 a 3x3 orthogonal matrix.
55 This is the optimal representation for application to vectors.
56 See also ROOT::Math::AxisAngle, ROOT::Math::EulerAngles, and ROOT::Math::Quaternion for
57 classes which have conversion operators to Rotation3D.
58
59 All Rotations types (not only Rotation3D) can be applied to all 3D Vector classes
60 (like ROOT::Math::DisplacementVector3D and ROOT::Math::PositionVector3D)
61 and also to the 4D Vectors (ROOT::Math::LorentzVector classes), acting on the 3D components.
62 A rotation operation is applied by using the operator() or the operator *.
63 With the operator * is possible also to combine rotations.
64 Note that the operator is NOT commutative, the order how the rotations are applied is relevant.
65
66 @ingroup GenVectorX
67
68 @see GenVectorX
69*/
70
72
73public:
74 typedef double Scalar;
75
77 kXX = 0,
78 kXY = 1,
79 kXZ = 2,
80 kYX = 3,
81 kYY = 4,
82 kYZ = 5,
83 kZX = 6,
84 kZY = 7,
85 kZZ = 8
86 };
87
88 // ========== Constructors and Assignment =====================
89
90 /**
91 Default constructor (identity rotation)
92 */
93 Rotation3D();
94
95 /**
96 Construct given a pair of pointers or iterators defining the
97 beginning and end of an array of nine Scalars
98 */
99 template <class IT>
100 Rotation3D(IT begin, IT end)
101 {
102 SetComponents(begin, end);
103 }
104
105 /**
106 copy constructor
107 */
108 Rotation3D(Rotation3D const &r) { *this = r; }
109
110 /**
111 Construct from an AxisAngle
112 */
113 explicit Rotation3D(AxisAngle const &a) { gv_detail::convert(a, *this); }
114
115 /**
116 Construct from EulerAngles
117 */
118 explicit Rotation3D(EulerAngles const &e) { gv_detail::convert(e, *this); }
119
120 /**
121 Construct from RotationZYX
122 */
123 explicit Rotation3D(RotationZYX const &e) { gv_detail::convert(e, *this); }
124
125 /**
126 Construct from a Quaternion
127 */
128 explicit Rotation3D(Quaternion const &q) { gv_detail::convert(q, *this); }
129
130 /**
131 Construct from an axial rotation
132 */
133 explicit Rotation3D(RotationZ const &r) { gv_detail::convert(r, *this); }
134 explicit Rotation3D(RotationY const &r) { gv_detail::convert(r, *this); }
135 explicit Rotation3D(RotationX const &r) { gv_detail::convert(r, *this); }
136
137 /**
138 Construct from a linear algebra matrix of size at least 3x3,
139 which must support operator()(i,j) to obtain elements (0,0) thru (2,2).
140 Precondition: The matrix is assumed to be orthonormal. No checking
141 or re-adjusting is performed.
142 */
143 template <class ForeignMatrix>
144 explicit Rotation3D(const ForeignMatrix &m)
145 {
147 }
148
149 /**
150 Construct from three orthonormal vectors (which must have methods
151 x(), y() and z()) which will be used as the columns of the rotation
152 matrix. The orthonormality will be checked, and values adjusted
153 so that the result will always be a good rotation matrix.
154 */
155 template <class ForeignVector>
157 {
159 }
160
161 // compiler generated destruuctor is ok
162
163 /**
164 Raw constructor from nine Scalar components (without any checking)
165 */
167 {
168 SetComponents(xx, xy, xz, yx, yy, yz, zx, zy, zz);
169 }
170
171 // need to implement assignment operator to avoid using the templated one
172
173 /**
174 Assignment operator
175 */
177 {
178 SetComponents(rhs.fM[0], rhs.fM[1], rhs.fM[2], rhs.fM[3], rhs.fM[4], rhs.fM[5], rhs.fM[6], rhs.fM[7], rhs.fM[8]);
179 return *this;
180 }
181
182 /**
183 Assign from an AxisAngle
184 */
186
187 /**
188 Assign from EulerAngles
189 */
191
192 /**
193 Assign from RotationZYX
194 */
196
197 /**
198 Assign from a Quaternion
199 */
201
202 /**
203 Assign from an axial rotation
204 */
208
209 /**
210 Assign from an orthonormal linear algebra matrix of size 3x3,
211 which must support operator()(i,j) to obtain elements (0,0) thru (2,2).
212 */
213 template <class ForeignMatrix>
215 {
216 SetComponents(m(0, 0), m(0, 1), m(0, 2), m(1, 0), m(1, 1), m(1, 2), m(2, 0), m(2, 1), m(2, 2));
217 return *this;
218 }
219
220 /**
221 Re-adjust components to eliminate small deviations from perfect
222 orthonormality.
223 */
224 void Rectify();
225
226 // ======== Components ==============
227
228 /**
229 Set components from three orthonormal vectors (which must have methods
230 x(), y() and z()) which will be used as the columns of the rotation
231 matrix. The orthonormality will be checked, and values adjusted
232 so that the result will always be a good rotation matrix.
233 */
234 template <class ForeignVector>
236 {
237 fM[kXX] = v1.x();
238 fM[kXY] = v2.x();
239 fM[kXZ] = v3.x();
240 fM[kYX] = v1.y();
241 fM[kYY] = v2.y();
242 fM[kYZ] = v3.y();
243 fM[kZX] = v1.z();
244 fM[kZY] = v2.z();
245 fM[kZZ] = v3.z();
246 Rectify();
247 }
248
249 /**
250 Get components into three vectors which will be the (orthonormal)
251 columns of the rotation matrix. (The vector class must have a
252 constructor from 3 Scalars.)
253 */
254 template <class ForeignVector>
261
262 /**
263 Set the 9 matrix components given an iterator to the start of
264 the desired data, and another to the end (9 past start).
265 */
266 template <class IT>
267 void SetComponents(IT begin, IT end)
268 {
269 for (int i = 0; i < 9; ++i) {
270 fM[i] = *begin;
271 ++begin;
272 }
273 (void)end;
274 assert(end == begin);
275 }
276
277 /**
278 Get the 9 matrix components into data specified by an iterator begin
279 and another to the end of the desired data (9 past start).
280 */
281 template <class IT>
282 void GetComponents(IT begin, IT end) const
283 {
284 for (int i = 0; i < 9; ++i) {
285 *begin = fM[i];
286 ++begin;
287 }
288 (void)end;
289 assert(end == begin);
290 }
291
292 /**
293 Get the 9 matrix components into data specified by an iterator begin
294 */
295 template <class IT>
296 void GetComponents(IT begin) const
297 {
298 std::copy(fM, fM + 9, begin);
299 }
300
301 /**
302 Set components from a linear algebra matrix of size at least 3x3,
303 which must support operator()(i,j) to obtain elements (0,0) thru (2,2).
304 Precondition: The matrix is assumed to be orthonormal. NO checking
305 or re-adjusting is performed.
306 */
307 template <class ForeignMatrix>
309 {
310 fM[kXX] = m(0, 0);
311 fM[kXY] = m(0, 1);
312 fM[kXZ] = m(0, 2);
313 fM[kYX] = m(1, 0);
314 fM[kYY] = m(1, 1);
315 fM[kYZ] = m(1, 2);
316 fM[kZX] = m(2, 0);
317 fM[kZY] = m(2, 1);
318 fM[kZZ] = m(2, 2);
319 }
320
321 /**
322 Get components into a linear algebra matrix of size at least 3x3,
323 which must support operator()(i,j) for write access to elements
324 (0,0) thru (2,2).
325 */
326 template <class ForeignMatrix>
328 {
329 m(0, 0) = fM[kXX];
330 m(0, 1) = fM[kXY];
331 m(0, 2) = fM[kXZ];
332 m(1, 0) = fM[kYX];
333 m(1, 1) = fM[kYY];
334 m(1, 2) = fM[kYZ];
335 m(2, 0) = fM[kZX];
336 m(2, 1) = fM[kZY];
337 m(2, 2) = fM[kZZ];
338 }
339
340 /**
341 Set the components from nine scalars -- UNCHECKED for orthonormaility
342 */
344 {
345 fM[kXX] = xx;
346 fM[kXY] = xy;
347 fM[kXZ] = xz;
348 fM[kYX] = yx;
349 fM[kYY] = yy;
350 fM[kYZ] = yz;
351 fM[kZX] = zx;
352 fM[kZY] = zy;
353 fM[kZZ] = zz;
354 }
355
356 /**
357 Get the nine components into nine scalars
358 */
360 Scalar &zz) const
361 {
362 xx = fM[kXX];
363 xy = fM[kXY];
364 xz = fM[kXZ];
365 yx = fM[kYX];
366 yy = fM[kYY];
367 yz = fM[kYZ];
368 zx = fM[kZX];
369 zy = fM[kZY];
370 zz = fM[kZZ];
371 }
372
373 // =========== operations ==============
374
375 /**
376 Access operator, used to have direct access to rotation matrix's entries
377 \param i row index in {0,1,2}
378 \param j column index in {0,1,2}
379 */
380 Scalar operator()(size_t i, size_t j) const
381 {
382 if (i < 3 && j < 3)
383 return fM[i + 3 * j];
384#if !defined(ROOT_MATH_SYCL) && !defined(ROOT_MATH_CUDA)
385 else
386 GenVector_Throw("Rotation3D::operator(size_t i, size_t j):\n"
387 " indices i and j must range in {0,1,2}");
388#endif
389 return 0.0;
390 }
391
392 /**
393 Rotation operation on a displacement vector in any coordinate system
394 */
395 template <class CoordSystem, class U>
397 {
399 xyz.SetXYZ(fM[kXX] * v.X() + fM[kXY] * v.Y() + fM[kXZ] * v.Z(),
400 fM[kYX] * v.X() + fM[kYY] * v.Y() + fM[kYZ] * v.Z(),
401 fM[kZX] * v.X() + fM[kZY] * v.Y() + fM[kZZ] * v.Z());
403 }
404
405 /**
406 Rotation operation on a position vector in any coordinate system
407 */
408 template <class CoordSystem, class U>
415
416 /**
417 Rotation operation on a Lorentz vector in any spatial coordinate system
418 */
419 template <class CoordSystem>
421 {
423 xyz = operator()(xyz);
424 LorentzVector<PxPyPzE4D<double>> xyzt(xyz.X(), xyz.Y(), xyz.Z(), v.E());
426 }
427
428 /**
429 Rotation operation on an arbitrary vector v.
430 Preconditions: v must implement methods x(), y(), and z()
431 and the arbitrary vector type must have a constructor taking (x,y,z)
432 */
433 template <class ForeignVector>
440
441 /**
442 Overload operator * for rotation on a vector
443 */
444 template <class AVector>
445 inline AVector operator*(const AVector &v) const
446 {
447 return operator()(v);
448 }
449
450 /**
451 Invert a rotation in place
452 */
453 void Invert();
454
455 /**
456 Return inverse of a rotation
457 */
459 {
460 Rotation3D t(*this);
461 t.Invert();
462 return t;
463 }
464
465 // ========= Multi-Rotation Operations ===============
466
467 /**
468 Multiply (combine) two rotations
469 */
471 {
472 return Rotation3D(fM[kXX] * r.fM[kXX] + fM[kXY] * r.fM[kYX] + fM[kXZ] * r.fM[kZX],
473 fM[kXX] * r.fM[kXY] + fM[kXY] * r.fM[kYY] + fM[kXZ] * r.fM[kZY],
474 fM[kXX] * r.fM[kXZ] + fM[kXY] * r.fM[kYZ] + fM[kXZ] * r.fM[kZZ]
475
476 ,
477 fM[kYX] * r.fM[kXX] + fM[kYY] * r.fM[kYX] + fM[kYZ] * r.fM[kZX],
478 fM[kYX] * r.fM[kXY] + fM[kYY] * r.fM[kYY] + fM[kYZ] * r.fM[kZY],
479 fM[kYX] * r.fM[kXZ] + fM[kYY] * r.fM[kYZ] + fM[kYZ] * r.fM[kZZ]
480
481 ,
482 fM[kZX] * r.fM[kXX] + fM[kZY] * r.fM[kYX] + fM[kZZ] * r.fM[kZX],
483 fM[kZX] * r.fM[kXY] + fM[kZY] * r.fM[kYY] + fM[kZZ] * r.fM[kZY],
484 fM[kZX] * r.fM[kXZ] + fM[kZY] * r.fM[kYZ] + fM[kZZ] * r.fM[kZZ]);
485 }
486
487 /**
488 Multiplication with arbitrary rotations
489 */
490 // note: cannot have a template method since it is ambiguous with the operator * on vectors
491
492 Rotation3D operator*(const AxisAngle &a) const;
493 Rotation3D operator*(const EulerAngles &e) const;
494 Rotation3D operator*(const Quaternion &q) const;
495 Rotation3D operator*(const RotationZYX &r) const;
496 Rotation3D operator*(const RotationX &rx) const;
497 Rotation3D operator*(const RotationY &ry) const;
498 Rotation3D operator*(const RotationZ &rz) const;
499
500 /**
501 Post-Multiply (on right) by another rotation : T = T*R
502 */
503 template <class R>
505 {
506 return *this = (*this) * r;
507 }
508
509 /**
510 Equality/inequality operators
511 */
512 bool operator==(const Rotation3D &rhs) const
513 {
514 if (fM[0] != rhs.fM[0])
515 return false;
516 if (fM[1] != rhs.fM[1])
517 return false;
518 if (fM[2] != rhs.fM[2])
519 return false;
520 if (fM[3] != rhs.fM[3])
521 return false;
522 if (fM[4] != rhs.fM[4])
523 return false;
524 if (fM[5] != rhs.fM[5])
525 return false;
526 if (fM[6] != rhs.fM[6])
527 return false;
528 if (fM[7] != rhs.fM[7])
529 return false;
530 if (fM[8] != rhs.fM[8])
531 return false;
532 return true;
533 }
534 bool operator!=(const Rotation3D &rhs) const { return !operator==(rhs); }
535
536private:
537 Scalar fM[9]; // 9 elements (3x3 matrix) representing the rotation
538
539}; // Rotation3D
540
541// ============ Class Rotation3D ends here ============
542
543/**
544 Distance between two rotations
545 */
546template <class R>
547inline typename Rotation3D::Scalar Distance(const Rotation3D &r1, const R &r2)
548{
549 return gv_detail::dist(r1, r2);
550}
551
552/**
553 Multiplication of an axial rotation by a Rotation3D
554 */
558
559/**
560 Multiplication of an axial rotation by another axial Rotation
561 */
564
567
570
571#if !defined(ROOT_MATH_SYCL) && !defined(ROOT_MATH_CUDA)
572
573/**
574 Stream Output and Input
575 */
576// TODO - I/O should be put in the manipulator form
577
578std::ostream &operator<<(std::ostream &os, const Rotation3D &r);
579#endif
580
581} // namespace ROOT_MATH_ARCH
582} // namespace ROOT
583
584#endif // ROOT_MathX_GenVectorX_Rotation3D
#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
Option_t Option_t TPoint xy
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
Rotation3D operator*(const Rotation3D &r) const
Multiply (combine) two rotations.
Definition Rotation3D.h:470
void Invert()
Invert a rotation in place.
Rotation3D(AxisAngle const &a)
Construct from an AxisAngle.
Definition Rotation3D.h:113
Rotation3D(Quaternion const &q)
Construct from a Quaternion.
Definition Rotation3D.h:128
void SetComponents(const ForeignVector &v1, const ForeignVector &v2, const ForeignVector &v3)
Set components from three orthonormal vectors (which must have methods x(), y() and z()) which will b...
Definition Rotation3D.h:235
Rotation3D & operator=(AxisAngle const &a)
Assign from an AxisAngle.
Definition Rotation3D.h:185
bool operator==(const Rotation3D &rhs) const
Equality/inequality operators.
Definition Rotation3D.h:512
Rotation3D & operator=(Rotation3D const &rhs)
Assignment operator.
Definition Rotation3D.h:176
void SetRotationMatrix(const ForeignMatrix &m)
Set components from a linear algebra matrix of size at least 3x3, which must support operator()(i,...
Definition Rotation3D.h:308
void GetComponents(ForeignVector &v1, ForeignVector &v2, ForeignVector &v3) const
Get components into three vectors which will be the (orthonormal) columns of the rotation matrix.
Definition Rotation3D.h:255
Rotation3D(RotationZ const &r)
Construct from an axial rotation.
Definition Rotation3D.h:133
Rotation3D & operator=(const ForeignMatrix &m)
Assign from an orthonormal linear algebra matrix of size 3x3, which must support operator()(i,...
Definition Rotation3D.h:214
DisplacementVector3D< CoordSystem, U > operator()(const DisplacementVector3D< CoordSystem, U > &v) const
Rotation operation on a displacement vector in any coordinate system.
Definition Rotation3D.h:396
void Rectify()
Re-adjust components to eliminate small deviations from perfect orthonormality.
Rotation3D(EulerAngles const &e)
Construct from EulerAngles.
Definition Rotation3D.h:118
Rotation3D(RotationX const &r)
Definition Rotation3D.h:135
PositionVector3D< CoordSystem, U > operator()(const PositionVector3D< CoordSystem, U > &v) const
Rotation operation on a position vector in any coordinate system.
Definition Rotation3D.h:409
Rotation3D & operator=(EulerAngles const &e)
Assign from EulerAngles.
Definition Rotation3D.h:190
void GetComponents(IT begin, IT end) const
Get the 9 matrix components into data specified by an iterator begin and another to the end of the de...
Definition Rotation3D.h:282
Rotation3D(Scalar xx, Scalar xy, Scalar xz, Scalar yx, Scalar yy, Scalar yz, Scalar zx, Scalar zy, Scalar zz)
Raw constructor from nine Scalar components (without any checking)
Definition Rotation3D.h:166
Rotation3D(RotationY const &r)
Definition Rotation3D.h:134
Scalar operator()(size_t i, size_t j) const
Access operator, used to have direct access to rotation matrix's entries.
Definition Rotation3D.h:380
void GetRotationMatrix(ForeignMatrix &m) const
Get components into a linear algebra matrix of size at least 3x3, which must support operator()(i,...
Definition Rotation3D.h:327
void GetComponents(IT begin) const
Get the 9 matrix components into data specified by an iterator begin.
Definition Rotation3D.h:296
Rotation3D Inverse() const
Return inverse of a rotation.
Definition Rotation3D.h:458
Rotation3D & operator=(Quaternion const &q)
Assign from a Quaternion.
Definition Rotation3D.h:200
Rotation3D(IT begin, IT end)
Construct given a pair of pointers or iterators defining the beginning and end of an array of nine Sc...
Definition Rotation3D.h:100
bool operator!=(const Rotation3D &rhs) const
Definition Rotation3D.h:534
Rotation3D(const ForeignMatrix &m)
Construct from a linear algebra matrix of size at least 3x3, which must support operator()(i,...
Definition Rotation3D.h:144
LorentzVector< CoordSystem > operator()(const LorentzVector< CoordSystem > &v) const
Rotation operation on a Lorentz vector in any spatial coordinate system.
Definition Rotation3D.h:420
Rotation3D & operator=(RotationY const &r)
Definition Rotation3D.h:206
void SetComponents(IT begin, IT end)
Set the 9 matrix components given an iterator to the start of the desired data, and another to the en...
Definition Rotation3D.h:267
Rotation3D()
Default constructor (identity rotation)
Rotation3D & operator=(RotationX const &r)
Definition Rotation3D.h:207
Rotation3D(const ForeignVector &v1, const ForeignVector &v2, const ForeignVector &v3)
Construct from three orthonormal vectors (which must have methods x(), y() and z()) which will be use...
Definition Rotation3D.h:156
Rotation3D & operator=(RotationZYX const &r)
Assign from RotationZYX.
Definition Rotation3D.h:195
AVector operator*(const AVector &v) const
Overload operator * for rotation on a vector.
Definition Rotation3D.h:445
void GetComponents(Scalar &xx, Scalar &xy, Scalar &xz, Scalar &yx, Scalar &yy, Scalar &yz, Scalar &zx, Scalar &zy, Scalar &zz) const
Get the nine components into nine scalars.
Definition Rotation3D.h:359
Rotation3D & operator*=(const R &r)
Post-Multiply (on right) by another rotation : T = T*R.
Definition Rotation3D.h:504
void SetComponents(Scalar xx, Scalar xy, Scalar xz, Scalar yx, Scalar yy, Scalar yz, Scalar zx, Scalar zy, Scalar zz)
Set the components from nine scalars – UNCHECKED for orthonormaility.
Definition Rotation3D.h:343
ForeignVector operator()(const ForeignVector &v) const
Rotation operation on an arbitrary vector v.
Definition Rotation3D.h:434
Rotation3D(Rotation3D const &r)
copy constructor
Definition Rotation3D.h:108
Rotation3D & operator=(RotationZ const &r)
Assign from an axial rotation.
Definition Rotation3D.h:205
Rotation3D(RotationZYX const &e)
Construct from RotationZYX.
Definition Rotation3D.h:123
Rotation class representing a 3D rotation about the X axis by the angle of rotation.
Definition RotationX.h:45
Rotation class representing a 3D rotation about the Y axis by the angle of rotation.
Definition RotationY.h:45
Rotation class with the (3D) rotation represented by angles describing first a rotation of an angle p...
Definition RotationZYX.h:64
Rotation class representing a 3D rotation about the Z axis by the angle of rotation.
Definition RotationZ.h:45
double dist(Rotation3D const &r1, Rotation3D const &r2)
void convert(R1 const &, R2 const)
AxisAngle::Scalar Distance(const AxisAngle &r1, const R &r2)
Distance between two rotations.
Definition AxisAngle.h:346
void GenVector_Throw(const char *)
function throwing exception, by creating internally a GenVector_exception only when needed
std::ostream & operator<<(std::ostream &os, const AxisAngle &a)
Stream Output and Input.
Definition AxisAngle.cxx:98
AxisAngle operator*(RotationX const &r1, AxisAngle const &r2)
Multiplication of an axial rotation by an AxisAngle.
TMarker m
Definition textangle.C:8