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