Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
3DConversions.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// Source file for something else
12//
13// Created by: Mark Fischler and Walter Brown Thurs July 7, 2005
14//
15// Last update: $Id$
16//
17
18// TODO - For now, all conversions are grouped in this one compilation unit.
19// The intention is to seraparte them into a few .cpp files instead,
20// so that users needing one form need not incorporate code for them all.
21
23
24#include "Math/Math.h"
25
34
35#include <limits>
36
38
40
41namespace ROOT {
42namespace ROOT_MATH_ARCH {
43namespace gv_detail {
44
56
57// ----------------------------------------------------------------------
58void convert(Rotation3D const &from, AxisAngle &to)
59{
60 // conversions from Rotation3D
61 double m[9];
62 from.GetComponents(m, m + 9);
63
64 const double uZ = m[kYX] - m[kXY];
65 const double uY = m[kXZ] - m[kZX];
66 const double uX = m[kZY] - m[kYZ];
67
68 // in case of rotation of an angle PI, the rotation matrix is symmetric and
69 // uX = uY = uZ = 0. Use then conversion through the quaternion
70 if (math_fabs(uX) < 8. * std::numeric_limits<double>::epsilon() &&
71 math_fabs(uY) < 8. * std::numeric_limits<double>::epsilon() &&
72 math_fabs(uZ) < 8. * std::numeric_limits<double>::epsilon()) {
73 Quaternion tmp;
74 convert(from, tmp);
75 convert(tmp, to);
76 return;
77 }
78
80
81 u.SetCoordinates(uX, uY, uZ);
82
83 static const double pi = M_PI;
84
85 double angle;
86 const double cosdelta = (m[kXX] + m[kYY] + m[kZZ] - 1.0) / 2.0;
87 if (cosdelta > 1.0) {
88 angle = 0;
89 } else if (cosdelta < -1.0) {
90 angle = pi;
91 } else {
93 }
94
95 // to.SetAngle(angle);
97 to.Rectify();
98
99} // convert to AxisAngle
100
101static void correctByPi(double &psi, double &phi)
102{
103 static const double pi = M_PI;
104 if (psi > 0) {
105 psi -= pi;
106 } else {
107 psi += pi;
108 }
109 if (phi > 0) {
110 phi -= pi;
111 } else {
112 phi += pi;
113 }
114}
115
116void convert(Rotation3D const &from, EulerAngles &to)
117{
118 // conversion from Rotation3D to Euler Angles
119
120 double r[9];
121 from.GetComponents(r, r + 9);
122
123 double phi, theta, psi;
124 double psiPlusPhi, psiMinusPhi;
125 static const double pi = M_PI;
126 static const double pi_2 = M_PI_2;
127
128 theta = (math_fabs(r[kZZ]) <= 1.0) ? math_acos(r[kZZ]) : (r[kZZ] > 0.0) ? 0 : pi;
129
130 double cosTheta = r[kZZ];
131 if (cosTheta > 1)
132 cosTheta = 1;
133 if (cosTheta < -1)
134 cosTheta = -1;
135
136 // Compute psi +/- phi:
137 // Depending on whether cosTheta is positive or negative and whether it
138 // is less than 1 in absolute value, different mathematically equivalent
139 // expressions are numerically stable.
140 if (cosTheta == 1) {
141 psiPlusPhi = math_atan2(r[kXY] - r[kYX], r[kXX] + r[kYY]);
142 psiMinusPhi = 0;
143 } else if (cosTheta >= 0) {
144 psiPlusPhi = math_atan2(r[kXY] - r[kYX], r[kXX] + r[kYY]);
145 double s = -r[kXY] - r[kYX]; // sin (psi-phi) * (1 - cos theta)
146 double c = r[kXX] - r[kYY]; // cos (psi-phi) * (1 - cos theta)
148 } else if (cosTheta > -1) {
149 psiMinusPhi = math_atan2(-r[kXY] - r[kYX], r[kXX] - r[kYY]);
150 double s = r[kXY] - r[kYX]; // sin (psi+phi) * (1 + cos theta)
151 double c = r[kXX] + r[kYY]; // cos (psi+phi) * (1 + cos theta)
152 psiPlusPhi = math_atan2(s, c);
153 } else { // cosTheta == -1
154 psiMinusPhi = math_atan2(-r[kXY] - r[kYX], r[kXX] - r[kYY]);
155 psiPlusPhi = 0;
156 }
157
158 psi = .5 * (psiPlusPhi + psiMinusPhi);
159 phi = .5 * (psiPlusPhi - psiMinusPhi);
160
161 // Now correct by pi if we have managed to get a value of psiPlusPhi
162 // or psiMinusPhi that was off by 2 pi:
163
164 // set up w[i], all of which would be positive if sin and cosine of
165 // psi and phi were positive:
166 double w[4];
167 w[0] = r[kXZ];
168 w[1] = r[kZX];
169 w[2] = r[kYZ];
170 w[3] = -r[kZY];
171
172 // find biggest relevant term, which is the best one to use in correcting.
173 double maxw = math_fabs(w[0]);
174 int imax = 0;
175 for (int i = 1; i < 4; ++i) {
176 if (math_fabs(w[i]) > maxw) {
177 maxw = math_fabs(w[i]);
178 imax = i;
179 }
180 }
181 // Determine if the correction needs to be applied: The criteria are
182 // different depending on whether a sine or cosine was the determinor:
183 switch (imax) {
184 case 0:
185 if (w[0] > 0 && psi < 0)
186 correctByPi(psi, phi);
187 if (w[0] < 0 && psi > 0)
188 correctByPi(psi, phi);
189 break;
190 case 1:
191 if (w[1] > 0 && phi < 0)
192 correctByPi(psi, phi);
193 if (w[1] < 0 && phi > 0)
194 correctByPi(psi, phi);
195 break;
196 case 2:
197 if (w[2] > 0 && math_fabs(psi) > pi_2)
198 correctByPi(psi, phi);
199 if (w[2] < 0 && math_fabs(psi) < pi_2)
200 correctByPi(psi, phi);
201 break;
202 case 3:
203 if (w[3] > 0 && math_fabs(phi) > pi_2)
204 correctByPi(psi, phi);
205 if (w[3] < 0 && math_fabs(phi) < pi_2)
206 correctByPi(psi, phi);
207 break;
208 }
209
210 to.SetComponents(phi, theta, psi);
211
212} // convert to EulerAngles
213
214////////////////////////////////////////////////////////////////////////////////
215/// conversion from Rotation3D to Quaternion
216
217void convert(Rotation3D const &from, Quaternion &to)
218{
219 double m[9];
220 from.GetComponents(m, m + 9);
221
222 const double d0 = m[kXX] + m[kYY] + m[kZZ];
223 const double d1 = +m[kXX] - m[kYY] - m[kZZ];
224 const double d2 = -m[kXX] + m[kYY] - m[kZZ];
225 const double d3 = -m[kXX] - m[kYY] + m[kZZ];
226
227 // these are related to the various q^2 values;
228 // choose the largest to avoid dividing two small numbers and losing accuracy.
229
230 if (d0 >= d1 && d0 >= d2 && d0 >= d3) {
231 const double q0 = .5 * math_sqrt(1 + d0);
232 const double f = .25 / q0;
233 const double q1 = f * (m[kZY] - m[kYZ]);
234 const double q2 = f * (m[kXZ] - m[kZX]);
235 const double q3 = f * (m[kYX] - m[kXY]);
236 to.SetComponents(q0, q1, q2, q3);
237 to.Rectify();
238 return;
239 } else if (d1 >= d2 && d1 >= d3) {
240 const double q1 = .5 * math_sqrt(1 + d1);
241 const double f = .25 / q1;
242 const double q0 = f * (m[kZY] - m[kYZ]);
243 const double q2 = f * (m[kXY] + m[kYX]);
244 const double q3 = f * (m[kXZ] + m[kZX]);
245 to.SetComponents(q0, q1, q2, q3);
246 to.Rectify();
247 return;
248 } else if (d2 >= d3) {
249 const double q2 = .5 * math_sqrt(1 + d2);
250 const double f = .25 / q2;
251 const double q0 = f * (m[kXZ] - m[kZX]);
252 const double q1 = f * (m[kXY] + m[kYX]);
253 const double q3 = f * (m[kYZ] + m[kZY]);
254 to.SetComponents(q0, q1, q2, q3);
255 to.Rectify();
256 return;
257 } else {
258 const double q3 = .5 * math_sqrt(1 + d3);
259 const double f = .25 / q3;
260 const double q0 = f * (m[kYX] - m[kXY]);
261 const double q1 = f * (m[kXZ] + m[kZX]);
262 const double q2 = f * (m[kYZ] + m[kZY]);
263 to.SetComponents(q0, q1, q2, q3);
264 to.Rectify();
265 return;
266 }
267} // convert to Quaternion
268
269////////////////////////////////////////////////////////////////////////////////
270/// conversion from Rotation3D to RotationZYX
271/// same Math used as for EulerAngles apart from some different meaning of angles and
272/// matrix elements.
273
274void convert(Rotation3D const &from, RotationZYX &to)
275{
276 // theta is assumed to be in range [-PI/2,PI/2].
277 // this is guaranteed by the Rectify function
278
279 static const double pi_2 = M_PI_2;
280
281 double r[9];
282 from.GetComponents(r, r + 9);
283
284 double phi, theta, psi = 0;
285
286 // careful for numeical error make sin(theta) ourtside [-1,1]
287 double sinTheta = r[kXZ];
288 if (sinTheta < -1.0)
289 sinTheta = -1.0;
290 if (sinTheta > 1.0)
291 sinTheta = 1.0;
292 theta = math_asin(sinTheta);
293
294 // compute psi +/- phi
295 // Depending on whether cosTheta is positive or negative and whether it
296 // is less than 1 in absolute value, different mathematically equivalent
297 // expressions are numerically stable.
298 // algorithm from
299 // adapted for the case 3-2-1
300
301 double psiPlusPhi = 0;
302 double psiMinusPhi = 0;
303
304 // valid if sinTheta not eq to -1 otherwise is zero
305 if (sinTheta > -1.0)
306 psiPlusPhi = atan2(r[kYX] + r[kZY], r[kYY] - r[kZX]);
307
308 // valid if sinTheta not eq. to 1
309 if (sinTheta < 1.0)
310 psiMinusPhi = atan2(r[kZY] - r[kYX], r[kYY] + r[kZX]);
311
312 psi = .5 * (psiPlusPhi + psiMinusPhi);
313 phi = .5 * (psiPlusPhi - psiMinusPhi);
314
315 // correction is not necessary if sinTheta = +/- 1
316 // if (sinTheta == 1.0 || sinTheta == -1.0) return;
317
318 // apply the corrections according to max of the other terms
319 // I think is assumed convention that theta is between -PI/2,PI/2.
320 // OTHERWISE RESULT MIGHT BE DIFFERENT ???
321
322 // since we determine phi+psi or phi-psi phi and psi can be both have a shift of +/- PI.
323 // The shift must be applied on both (the sum (or difference) is knows to +/- 2PI )
324 // This can be fixed looking at the other 4 matrix terms, which have terms in sin and cos of psi
325 // and phi. sin(psi+/-PI) = -sin(psi) and cos(psi+/-PI) = -cos(psi).
326 // Use then the biggest term for making the correction to minimize possible numerical errors
327
328 // set up w[i], all of which would be positive if sin and cosine of
329 // psi and phi were positive:
330 double w[4];
331 w[0] = -r[kYZ];
332 w[1] = -r[kXY];
333 w[2] = r[kZZ];
334 w[3] = r[kXX];
335
336 // find biggest relevant term, which is the best one to use in correcting.
337 double maxw = math_fabs(w[0]);
338 int imax = 0;
339 for (int i = 1; i < 4; ++i) {
340 if (math_fabs(w[i]) > maxw) {
341 maxw = math_fabs(w[i]);
342 imax = i;
343 }
344 }
345
346 // Determine if the correction needs to be applied: The criteria are
347 // different depending on whether a sine or cosine was the determinor:
348 switch (imax) {
349 case 0:
350 if (w[0] > 0 && psi < 0)
351 correctByPi(psi, phi);
352 if (w[0] < 0 && psi > 0)
353 correctByPi(psi, phi);
354 break;
355 case 1:
356 if (w[1] > 0 && phi < 0)
357 correctByPi(psi, phi);
358 if (w[1] < 0 && phi > 0)
359 correctByPi(psi, phi);
360 break;
361 case 2:
362 if (w[2] > 0 && math_fabs(psi) > pi_2)
363 correctByPi(psi, phi);
364 if (w[2] < 0 && math_fabs(psi) < pi_2)
365 correctByPi(psi, phi);
366 break;
367 case 3:
368 if (w[3] > 0 && math_fabs(phi) > pi_2)
369 correctByPi(psi, phi);
370 if (w[3] < 0 && math_fabs(phi) < pi_2)
371 correctByPi(psi, phi);
372 break;
373 }
374
375 to.SetComponents(phi, theta, psi);
376
377} // convert to RotationZYX
378
379// ----------------------------------------------------------------------
380// conversions from AxisAngle
381
382void convert(AxisAngle const &from, Rotation3D &to)
383{
384 // conversion from AxisAngle to Rotation3D
385
386 const double sinDelta = math_sin(from.Angle());
387 const double cosDelta = math_cos(from.Angle());
388 const double oneMinusCosDelta = 1.0 - cosDelta;
389
390 const AxisAngle::AxisVector &u = from.Axis();
391 const double uX = u.X();
392 const double uY = u.Y();
393 const double uZ = u.Z();
394
395 double m[9];
396
398 m[kXY] = oneMinusCosDelta * uX * uY - sinDelta * uZ;
399 m[kXZ] = oneMinusCosDelta * uX * uZ + sinDelta * uY;
400
401 m[kYX] = oneMinusCosDelta * uY * uX + sinDelta * uZ;
403 m[kYZ] = oneMinusCosDelta * uY * uZ - sinDelta * uX;
404
405 m[kZX] = oneMinusCosDelta * uZ * uX - sinDelta * uY;
406 m[kZY] = oneMinusCosDelta * uZ * uY + sinDelta * uX;
408
409 to.SetComponents(m, m + 9);
410} // convert to Rotation3D
411
412void convert(AxisAngle const &from, EulerAngles &to)
413{
414 // conversion from AxisAngle to EulerAngles
415 // TODO better : temporary make conversion using Rotation3D
416
417 Rotation3D tmp;
418 convert(from, tmp);
419 convert(tmp, to);
420}
421
422void convert(AxisAngle const &from, Quaternion &to)
423{
424 // conversion from AxisAngle to Quaternion
425
426 double s = math_sin(from.Angle() / 2);
428
429 to.SetComponents(math_cos(from.Angle() / 2), s * axis.X(), s * axis.Y(), s * axis.Z());
430} // convert to Quaternion
431
432void convert(AxisAngle const &from, RotationZYX &to)
433{
434 // conversion from AxisAngle to RotationZYX
435 // TODO better : temporary make conversion using Rotation3D
436 Rotation3D tmp;
437 convert(from, tmp);
438 convert(tmp, to);
439}
440
441// ----------------------------------------------------------------------
442// conversions from EulerAngles
443
444void convert(EulerAngles const &from, Rotation3D &to)
445{
446 // conversion from EulerAngles to Rotation3D
447
448 typedef double Scalar;
449 const Scalar sPhi = math_sin(from.Phi());
450 const Scalar cPhi = math_cos(from.Phi());
451 const Scalar sTheta = math_sin(from.Theta());
452 const Scalar cTheta = math_cos(from.Theta());
453 const Scalar sPsi = math_sin(from.Psi());
454 const Scalar cPsi = math_cos(from.Psi());
456 -sPsi * cPhi - cPsi * cTheta * sPhi, -sPsi * sPhi + cPsi * cTheta * cPhi, cPsi * sTheta,
457 sTheta * sPhi, -sTheta * cPhi, cTheta);
458}
459
460void convert(EulerAngles const &from, AxisAngle &to)
461{
462 // conversion from EulerAngles to AxisAngle
463 // make converting first to quaternion
465 convert(from, q);
466 convert(q, to);
467}
468
469void convert(EulerAngles const &from, Quaternion &to)
470{
471 // conversion from EulerAngles to Quaternion
472
473 typedef double Scalar;
474 const Scalar plus = (from.Phi() + from.Psi()) / 2;
475 const Scalar minus = (from.Phi() - from.Psi()) / 2;
476 const Scalar sPlus = math_sin(plus);
477 const Scalar cPlus = math_cos(plus);
478 const Scalar sMinus = math_sin(minus);
479 const Scalar cMinus = math_cos(minus);
480 const Scalar sTheta = math_sin(from.Theta() / 2);
481 const Scalar cTheta = math_cos(from.Theta() / 2);
482
484 // TODO -- carefully check that this is correct
485}
486
487void convert(EulerAngles const &from, RotationZYX &to)
488{
489 // conversion from EulerAngles to RotationZYX
490 // TODO better : temporary make conversion using Rotation3D
491 Rotation3D tmp;
492 convert(from, tmp);
493 convert(tmp, to);
494}
495
496// ----------------------------------------------------------------------
497// conversions from Quaternion
498
499void convert(Quaternion const &from, Rotation3D &to)
500{
501 // conversion from Quaternion to Rotation3D
502
503 const double q0 = from.U();
504 const double q1 = from.I();
505 const double q2 = from.J();
506 const double q3 = from.K();
507 const double q00 = q0 * q0;
508 const double q01 = q0 * q1;
509 const double q02 = q0 * q2;
510 const double q03 = q0 * q3;
511 const double q11 = q1 * q1;
512 const double q12 = q1 * q2;
513 const double q13 = q1 * q3;
514 const double q22 = q2 * q2;
515 const double q23 = q2 * q3;
516 const double q33 = q3 * q3;
517
518 to.SetComponents(q00 + q11 - q22 - q33, 2 * (q12 - q03), 2 * (q02 + q13), 2 * (q12 + q03), q00 - q11 + q22 - q33,
519 2 * (q23 - q01), 2 * (q13 - q02), 2 * (q23 + q01), q00 - q11 - q22 + q33);
520
521} // conversion to Rotation3D
522
523void convert(Quaternion const &from, AxisAngle &to)
524{
525 // conversion from Quaternion to AxisAngle
526
527 double u = from.U();
528 if (u >= 0) {
529 if (u > 1)
530 u = 1;
531 const double angle = 2.0 * math_acos(from.U());
532 DisplacementVector3D<Cartesian3D<double>> axis(from.I(), from.J(), from.K());
533 to.SetComponents(axis, angle);
534 } else {
535 if (u < -1)
536 u = -1;
537 const double angle = 2.0 * math_acos(-from.U());
538 DisplacementVector3D<Cartesian3D<double>> axis(-from.I(), -from.J(), -from.K());
539 to.SetComponents(axis, angle);
540 }
541} // conversion to AxisAngle
542
543void convert(Quaternion const &from, EulerAngles &to)
544{
545 // conversion from Quaternion to EulerAngles
546 // TODO better
547 // temporary make conversion using Rotation3D
548
549 Rotation3D tmp;
550 convert(from, tmp);
551 convert(tmp, to);
552}
553
554void convert(Quaternion const &from, RotationZYX &to)
555{
556 // conversion from Quaternion to RotationZYX
557 // TODO better : temporary make conversion using Rotation3D
558 Rotation3D tmp;
559 convert(from, tmp);
560 convert(tmp, to);
561}
562
563// ----------------------------------------------------------------------
564// conversions from RotationZYX
565void convert(RotationZYX const &from, Rotation3D &to)
566{
567 // conversion to Rotation3D (matrix)
568
569 double phi, theta, psi = 0;
570 from.GetComponents(phi, theta, psi);
571 to.SetComponents(
572 math_cos(theta) * math_cos(phi), -math_cos(theta) * math_sin(phi), math_sin(theta),
573
574 math_cos(psi) * math_sin(phi) + math_sin(psi) * math_sin(theta) * math_cos(phi),
575 math_cos(psi) * math_cos(phi) - math_sin(psi) * math_sin(theta) * math_sin(phi), -math_sin(psi) * math_cos(theta),
576
577 math_sin(psi) * math_sin(phi) - math_cos(psi) * math_sin(theta) * math_cos(phi),
578 math_sin(psi) * math_cos(phi) + math_cos(psi) * math_sin(theta) * math_sin(phi), math_cos(psi) * math_cos(theta));
579}
580void convert(RotationZYX const &from, AxisAngle &to)
581{
582 // conversion to axis angle
583 // TODO better : temporary make conversion using Rotation3D
584 Rotation3D tmp;
585 convert(from, tmp);
586 convert(tmp, to);
587}
588void convert(RotationZYX const &from, EulerAngles &to)
589{
590 // conversion to Euler angle
591 // TODO better : temporary make conversion using Rotation3D
592 Rotation3D tmp;
593 convert(from, tmp);
594 convert(tmp, to);
595}
596void convert(RotationZYX const &from, Quaternion &to)
597{
598 double phi, theta, psi = 0;
599 from.GetComponents(phi, theta, psi);
600
601 double sphi2 = math_sin(phi / 2);
602 double cphi2 = math_cos(phi / 2);
603 double stheta2 = math_sin(theta / 2);
604 double ctheta2 = math_cos(theta / 2);
605 double spsi2 = math_sin(psi / 2);
606 double cpsi2 = math_cos(psi / 2);
607 to.SetComponents(
610}
611
612// ----------------------------------------------------------------------
613// conversions from RotationX
614
615void convert(RotationX const &from, Rotation3D &to)
616{
617 // conversion from RotationX to Rotation3D
618
619 const double c = from.CosAngle();
620 const double s = from.SinAngle();
621 to.SetComponents(1, 0, 0, 0, c, -s, 0, s, c);
622}
623
624void convert(RotationX const &from, AxisAngle &to)
625{
626 // conversion from RotationX to AxisAngle
627
629 to.SetComponents(axis, from.Angle());
630}
631
632void convert(RotationX const &from, EulerAngles &to)
633{
634 // conversion from RotationX to EulerAngles
635 // TODO better: temporary make conversion using Rotation3D
636
637 Rotation3D tmp;
638 convert(from, tmp);
639 convert(tmp, to);
640}
641
642void convert(RotationX const &from, Quaternion &to)
643{
644 // conversion from RotationX to Quaternion
645
646 to.SetComponents(math_cos(from.Angle() / 2), math_sin(from.Angle() / 2), 0, 0);
647}
648
649void convert(RotationX const &from, RotationZYX &to)
650{
651 // conversion from RotationX to RotationZYX
652 to.SetComponents(0, 0, from.Angle());
653}
654
655// ----------------------------------------------------------------------
656// conversions from RotationY
657
658void convert(RotationY const &from, Rotation3D &to)
659{
660 // conversion from RotationY to Rotation3D
661
662 const double c = from.CosAngle();
663 const double s = from.SinAngle();
664 to.SetComponents(c, 0, s, 0, 1, 0, -s, 0, c);
665}
666
667void convert(RotationY const &from, AxisAngle &to)
668{
669 // conversion from RotationY to AxisAngle
670
672 to.SetComponents(axis, from.Angle());
673}
674
675void convert(RotationY const &from, EulerAngles &to)
676{
677 // conversion from RotationY to EulerAngles
678 // TODO better: temporary make conversion using Rotation3D
679
680 Rotation3D tmp;
681 convert(from, tmp);
682 convert(tmp, to);
683}
684
685void convert(RotationY const &from, RotationZYX &to)
686{
687 // conversion from RotationY to RotationZYX
688 to.SetComponents(0, from.Angle(), 0);
689}
690
691void convert(RotationY const &from, Quaternion &to)
692{
693 // conversion from RotationY to Quaternion
694
695 to.SetComponents(math_cos(from.Angle() / 2), 0, math_sin(from.Angle() / 2), 0);
696}
697
698// ----------------------------------------------------------------------
699// conversions from RotationZ
700
701void convert(RotationZ const &from, Rotation3D &to)
702{
703 // conversion from RotationZ to Rotation3D
704
705 const double c = from.CosAngle();
706 const double s = from.SinAngle();
707 to.SetComponents(c, -s, 0, s, c, 0, 0, 0, 1);
708}
709
710void convert(RotationZ const &from, AxisAngle &to)
711{
712 // conversion from RotationZ to AxisAngle
713
715 to.SetComponents(axis, from.Angle());
716}
717
718void convert(RotationZ const &from, EulerAngles &to)
719{
720 // conversion from RotationZ to EulerAngles
721 // TODO better: temporary make conversion using Rotation3D
722
723 Rotation3D tmp;
724 convert(from, tmp);
725 convert(tmp, to);
726}
727
728void convert(RotationZ const &from, RotationZYX &to)
729{
730 // conversion from RotationY to RotationZYX
731 to.SetComponents(from.Angle(), 0, 0);
732}
733
734void convert(RotationZ const &from, Quaternion &to)
735{
736 // conversion from RotationZ to Quaternion
737
738 to.SetComponents(math_cos(from.Angle() / 2), 0, 0, math_sin(from.Angle() / 2));
739}
740
741} // namespace gv_detail
742} // namespace ROOT_MATH_ARCH
743} // namespace ROOT
#define M_PI_2
Definition Math.h:41
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define M_PI
Definition Rotated.cxx:105
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 TPoint angle
float * q
AxisAngle class describing rotation represented with direction axis (3D Vector) and an angle of rotat...
Definition AxisAngle.h:46
DisplacementVector3D< Cartesian3D< Scalar > > AxisVector
definition of vector axis
Definition AxisAngle.h:54
void SetComponents(IT begin, IT end)
Set the axis and then the angle given a pair of pointers or iterators defining the beginning and end ...
Definition AxisAngle.h:126
AxisVector Axis() const
access to rotation axis
Definition AxisAngle.h:197
Scalar Angle() const
access to rotation angle
Definition AxisAngle.h:202
void Rectify()
Re-adjust components to eliminate small deviations from the axis being a unit vector and angles out o...
Definition AxisAngle.cxx:53
EulerAngles class describing rotation as three angles (Euler Angles).
Definition EulerAngles.h:50
void SetComponents(IT begin, IT end)
Set the three Euler angles given a pair of pointers or iterators defining the beginning and end of an...
Scalar Psi() const
Return Psi Euler angle.
Scalar Phi() const
Return Phi Euler angle.
Scalar Theta() const
Return Theta Euler angle.
Rotation class with the (3D) rotation represented by a unit quaternion (u, i, j, k).
Definition Quaternion.h:52
Scalar U() const
Access to the four quaternion components: U() is the coefficient of the identity Pauli matrix,...
Definition Quaternion.h:180
void Rectify()
Re-adjust components to eliminate small deviations from |Q| = 1 orthonormality.
void SetComponents(IT begin, IT end)
Set the four components given an iterator to the start of the desired data, and another to the end (4...
Definition Quaternion.h:115
Rotation class with the (3D) rotation represented by a 3x3 orthogonal matrix.
Definition Rotation3D.h:71
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
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
Rotation class representing a 3D rotation about the X axis by the angle of rotation.
Definition RotationX.h:45
Scalar SinAngle() const
Sine or Cosine of the rotation angle.
Definition RotationX.h:105
Scalar Angle() const
Angle of rotation.
Definition RotationX.h:100
Rotation class representing a 3D rotation about the Y axis by the angle of rotation.
Definition RotationY.h:45
Scalar Angle() const
Angle of rotation.
Definition RotationY.h:100
Scalar SinAngle() const
Sine or Cosine of the rotation angle.
Definition RotationY.h:105
Rotation class with the (3D) rotation represented by angles describing first a rotation of an angle p...
Definition RotationZYX.h:64
void SetComponents(IT begin, IT end)
Set the three Euler angles given a pair of pointers or iterators defining the beginning and end of an...
void GetComponents(IT begin, IT end) const
Get the axis and then the angle into data specified by an iterator begin and another to the end of th...
Rotation class representing a 3D rotation about the Z axis by the angle of rotation.
Definition RotationZ.h:45
Scalar Angle() const
Angle of rotation.
Definition RotationZ.h:100
Scalar SinAngle() const
Sine or Cosine of the rotation angle.
Definition RotationZ.h:105
void convert(R1 const &, R2 const)
static void correctByPi(double &psi, double &phi)
Scalar math_cos(Scalar x)
Rotation3D::Scalar Scalar
Scalar math_sqrt(Scalar x)
Scalar math_asin(Scalar x)
Scalar math_acos(Scalar x)
Scalar math_atan2(Scalar x, Scalar y)
Scalar math_fabs(Scalar x)
Scalar math_sin(Scalar x)
TMarker m
Definition textangle.C:8