42 enum ERotation3DMatrixIndex
43 { kXX = Rotation3D::kXX, kXY = Rotation3D::kXY, kXZ = Rotation3D::kXZ
44 , kYX = Rotation3D::kYX, kYY = Rotation3D::kYY, kYZ = Rotation3D::kYZ
45 , kZX = Rotation3D::kZX, kZY = Rotation3D::kZY, kZZ = Rotation3D::kZZ
50 void convert( Rotation3D
const & from, AxisAngle & to)
54 from.GetComponents(m, m+9);
56 const double uZ = m[kYX] - m[kXY];
57 const double uY = m[kXZ] - m[kZX];
58 const double uX = m[kZY] - m[kYZ];
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() ) {
72 AxisAngle::AxisVector u;
74 u.SetCoordinates( uX, uY, uZ );
76 static const double pi = M_PI;
79 const double cosdelta = (m[kXX] + m[kYY] + m[kZZ] - 1.0) / 2.0;
82 }
else if (cosdelta < -1.0) {
85 angle = std::acos( cosdelta );
90 to.SetComponents(u, angle);
95 static void correctByPi (
double& psi,
double& phi ) {
96 static const double pi = M_PI;
109 void convert( Rotation3D
const & from, EulerAngles & to)
116 from.GetComponents(r,r+9);
118 double phi, theta, psi;
119 double psiPlusPhi, psiMinusPhi;
120 static const double pi = M_PI;
121 static const double pi_2 = M_PI_2;
123 theta = (std::fabs(r[kZZ]) <= 1.0) ? std::acos(r[kZZ]) :
124 (r[kZZ] > 0.0) ? 0 : pi;
126 double cosTheta = r[kZZ];
127 if (cosTheta > 1) cosTheta = 1;
128 if (cosTheta < -1) cosTheta = -1;
135 psiPlusPhi = atan2 ( r[kXY] - r[kYX], r[kXX] + r[kYY] );
137 }
else if (cosTheta >= 0) {
138 psiPlusPhi = atan2 ( r[kXY] - r[kYX], r[kXX] + r[kYY] );
139 double s = -r[kXY] - r[kYX];
140 double c = r[kXX] - r[kYY];
141 psiMinusPhi = atan2 ( s, c );
142 }
else if (cosTheta > -1) {
143 psiMinusPhi = atan2 ( -r[kXY] - r[kYX], r[kXX] - r[kYY] );
144 double s = r[kXY] - r[kYX];
145 double c = r[kXX] + r[kYY];
146 psiPlusPhi = atan2 ( s, c );
148 psiMinusPhi = atan2 ( -r[kXY] - r[kYX], r[kXX] - r[kYY] );
152 psi = .5 * (psiPlusPhi + psiMinusPhi);
153 phi = .5 * (psiPlusPhi - psiMinusPhi);
161 w[0] = r[kXZ]; w[1] = r[kZX]; w[2] = r[kYZ]; w[3] = -r[kZY];
164 double maxw = std::fabs(w[0]);
166 for (
int i = 1; i < 4; ++i) {
167 if (std::fabs(w[i]) > maxw) {
168 maxw = std::fabs(w[i]);
176 if (w[0] > 0 && psi < 0) correctByPi ( psi, phi );
177 if (w[0] < 0 && psi > 0) correctByPi ( psi, phi );
180 if (w[1] > 0 && phi < 0) correctByPi ( psi, phi );
181 if (w[1] < 0 && phi > 0) correctByPi ( psi, phi );
184 if (w[2] > 0 && std::fabs(psi) > pi_2) correctByPi ( psi, phi );
185 if (w[2] < 0 && std::fabs(psi) < pi_2) correctByPi ( psi, phi );
188 if (w[3] > 0 && std::fabs(phi) > pi_2) correctByPi ( psi, phi );
189 if (w[3] < 0 && std::fabs(phi) < pi_2) correctByPi ( psi, phi );
193 to.SetComponents( phi, theta, psi );
200 void convert( Rotation3D
const & from, Quaternion & to)
203 from.GetComponents(m, m+9);
205 const double d0 = m[kXX] + m[kYY] + m[kZZ];
206 const double d1 = + m[kXX] - m[kYY] - m[kZZ];
207 const double d2 = - m[kXX] + m[kYY] - m[kZZ];
208 const double d3 = - m[kXX] - m[kYY] + m[kZZ];
213 if ( d0 >= d1 && d0 >= d2 && d0 >= d3 ) {
214 const double q0 = .5*std::sqrt(1+d0);
215 const double f = .25/q0;
216 const double q1 = f*(m[kZY]-m[kYZ]);
217 const double q2 = f*(m[kXZ]-m[kZX]);
218 const double q3 = f*(m[kYX]-m[kXY]);
219 to.SetComponents(q0,q1,q2,q3);
222 }
else if ( d1 >= d2 && d1 >= d3 ) {
223 const double q1 = .5*std::sqrt(1+d1);
224 const double f = .25/q1;
225 const double q0 = f*(m[kZY]-m[kYZ]);
226 const double q2 = f*(m[kXY]+m[kYX]);
227 const double q3 = f*(m[kXZ]+m[kZX]);
228 to.SetComponents(q0,q1,q2,q3);
231 }
else if ( d2 >= d3 ) {
232 const double q2 = .5*std::sqrt(1+d2);
233 const double f = .25/q2;
234 const double q0 = f*(m[kXZ]-m[kZX]);
235 const double q1 = f*(m[kXY]+m[kYX]);
236 const double q3 = f*(m[kYZ]+m[kZY]);
237 to.SetComponents(q0,q1,q2,q3);
241 const double q3 = .5*std::sqrt(1+d3);
242 const double f = .25/q3;
243 const double q0 = f*(m[kYX]-m[kXY]);
244 const double q1 = f*(m[kXZ]+m[kZX]);
245 const double q2 = f*(m[kYZ]+m[kZY]);
246 to.SetComponents(q0,q1,q2,q3);
258 void convert( Rotation3D
const & from, RotationZYX & to)
263 static const double pi_2 = M_PI_2;
266 from.GetComponents(r,r+9);
268 double phi,theta,psi = 0;
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 );
283 double psiPlusPhi = 0;
284 double psiMinusPhi = 0;
287 if (sinTheta > - 1.0)
288 psiPlusPhi = atan2 ( r[kYX] + r[kZY], r[kYY] - r[kZX] );
292 psiMinusPhi = atan2 ( r[kZY] - r[kYX] , r[kYY] + r[kZX] );
294 psi = .5 * (psiPlusPhi + psiMinusPhi);
295 phi = .5 * (psiPlusPhi - psiMinusPhi);
313 w[0] = -r[kYZ]; w[1] = -r[kXY]; w[2] = r[kZZ]; w[3] = r[kXX];
316 double maxw = std::fabs(w[0]);
318 for (
int i = 1; i < 4; ++i) {
319 if (std::fabs(w[i]) > maxw) {
320 maxw = std::fabs(w[i]);
329 if (w[0] > 0 && psi < 0) correctByPi ( psi, phi );
330 if (w[0] < 0 && psi > 0) correctByPi ( psi, phi );
333 if (w[1] > 0 && phi < 0) correctByPi ( psi, phi );
334 if (w[1] < 0 && phi > 0) correctByPi ( psi, phi );
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 );
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 );
346 to.SetComponents(phi, theta, psi);
353 void convert( AxisAngle
const & from, Rotation3D & to)
357 const double sinDelta = std::sin( from.Angle() );
358 const double cosDelta = std::cos( from.Angle() );
359 const double oneMinusCosDelta = 1.0 - cosDelta;
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();
368 m[kXX] = oneMinusCosDelta * uX * uX + cosDelta;
369 m[kXY] = oneMinusCosDelta * uX * uY - sinDelta * uZ;
370 m[kXZ] = oneMinusCosDelta * uX * uZ + sinDelta * uY;
372 m[kYX] = oneMinusCosDelta * uY * uX + sinDelta * uZ;
373 m[kYY] = oneMinusCosDelta * uY * uY + cosDelta;
374 m[kYZ] = oneMinusCosDelta * uY * uZ - sinDelta * uX;
376 m[kZX] = oneMinusCosDelta * uZ * uX - sinDelta * uY;
377 m[kZY] = oneMinusCosDelta * uZ * uY + sinDelta * uX;
378 m[kZZ] = oneMinusCosDelta * uZ * uZ + cosDelta;
380 to.SetComponents(m,m+9);
383 void convert( AxisAngle
const & from , EulerAngles & to )
393 void convert( AxisAngle
const & from, Quaternion & to)
397 double s = std::sin (from.Angle()/2);
398 DisplacementVector3D< Cartesian3D<double> > axis = from.Axis();
400 to.SetComponents( std::cos(from.Angle()/2),
407 void convert( AxisAngle
const & from , RotationZYX & to )
420 void convert( EulerAngles
const & from, Rotation3D & to)
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() );
432 ( cPsi*cPhi-sPsi*cTheta*sPhi, cPsi*sPhi+sPsi*cTheta*cPhi, sPsi*sTheta
433 , -sPsi*cPhi-cPsi*cTheta*sPhi, -sPsi*sPhi+cPsi*cTheta*cPhi, cPsi*sTheta
434 , sTheta*sPhi, -sTheta*cPhi, cTheta
438 void convert( EulerAngles
const & from, AxisAngle & to)
447 void convert( EulerAngles
const & from, Quaternion & to)
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 );
461 to.SetComponents ( cTheta*cPlus, -sTheta*cMinus, -sTheta*sMinus, -cTheta*sPlus );
465 void convert( EulerAngles
const & from , RotationZYX & to )
478 void convert( Quaternion
const & from, Rotation3D & to)
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;
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 );
504 void convert( Quaternion
const & from, AxisAngle & to)
511 const double angle = 2.0 * std::acos ( from.U() );
512 DisplacementVector3D< Cartesian3D<double> >
513 axis (from.I(), from.J(), from.K());
514 to.SetComponents ( axis, angle );
516 if ( u < -1 ) u = -1;
517 const double angle = 2.0 * std::acos ( -from.U() );
518 DisplacementVector3D< Cartesian3D<double> >
519 axis (-from.I(), -from.J(), -from.K());
520 to.SetComponents ( axis, angle );
524 void convert( Quaternion
const & from, EulerAngles & to )
535 void convert( Quaternion
const & from , RotationZYX & to )
546 void convert( RotationZYX
const & from, Rotation3D & to) {
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),
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),
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)
565 void convert( RotationZYX
const & from, AxisAngle & to) {
572 void convert( RotationZYX
const & from, EulerAngles & to) {
579 void convert( RotationZYX
const & from, Quaternion & to) {
580 double phi,theta,psi = 0;
581 from.GetComponents(phi,theta,psi);
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,
590 sphi2 * cpsi2 * stheta2 + cphi2 * spsi2 * ctheta2,
591 cphi2 * cpsi2 * stheta2 - sphi2 * spsi2 * ctheta2,
592 sphi2 * cpsi2 * ctheta2 + cphi2 * spsi2 * stheta2
600 void convert( RotationX
const & from, Rotation3D & to)
604 const double c = from.CosAngle();
605 const double s = from.SinAngle();
606 to.SetComponents ( 1, 0, 0,
611 void convert( RotationX
const & from, AxisAngle & to)
615 DisplacementVector3D< Cartesian3D<double> > axis (1, 0, 0);
616 to.SetComponents ( axis, from.Angle() );
619 void convert( RotationX
const & from , EulerAngles & to )
629 void convert( RotationX
const & from, Quaternion & to)
633 to.SetComponents (std::cos(from.Angle()/2), std::sin(from.Angle()/2), 0, 0);
636 void convert( RotationX
const & from , RotationZYX & to )
639 to.SetComponents(0,0,from.Angle());
646 void convert( RotationY
const & from, Rotation3D & to)
650 const double c = from.CosAngle();
651 const double s = from.SinAngle();
652 to.SetComponents ( c, 0, s,
657 void convert( RotationY
const & from, AxisAngle & to)
661 DisplacementVector3D< Cartesian3D<double> > axis (0, 1, 0);
662 to.SetComponents ( axis, from.Angle() );
665 void convert( RotationY
const & from, EulerAngles & to )
675 void convert( RotationY
const & from , RotationZYX & to )
678 to.SetComponents(0,from.Angle(),0);
682 void convert( RotationY
const & from, Quaternion & to)
686 to.SetComponents (std::cos(from.Angle()/2), 0, std::sin(from.Angle()/2), 0);
694 void convert( RotationZ
const & from, Rotation3D & to)
698 const double c = from.CosAngle();
699 const double s = from.SinAngle();
700 to.SetComponents ( c, -s, 0,
705 void convert( RotationZ
const & from, AxisAngle & to)
709 DisplacementVector3D< Cartesian3D<double> > axis (0, 0, 1);
710 to.SetComponents ( axis, from.Angle() );
713 void convert( RotationZ
const & from , EulerAngles & to )
723 void convert( RotationZ
const & from , RotationZYX & to )
726 to.SetComponents(from.Angle(),0,0);
729 void convert( RotationZ
const & from, Quaternion & to)
733 to.SetComponents (std::cos(from.Angle()/2), 0, 0, std::sin(from.Angle()/2));