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