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()) {
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
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
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());
459 to.SetComponents(cPsi * cPhi - sPsi * cTheta * sPhi, cPsi * sPhi + sPsi * cTheta * cPhi, sPsi * sTheta,
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
487 to.SetComponents(cTheta * cPlus, -sTheta * cMinus, -sTheta * sMinus, -cTheta * sPlus);
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
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
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
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
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
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
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
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
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
AxisVector Axis() const
access to rotation axis
Definition AxisAngle.h:197
Scalar Angle() const
access to rotation angle
Definition AxisAngle.h:202
EulerAngles class describing rotation as three angles (Euler Angles).
Definition EulerAngles.h:50
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
Rotation class with the (3D) rotation represented by a 3x3 orthogonal matrix.
Definition Rotation3D.h:71
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 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