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