00001
00002
00003
00004
00005
00006
00007 #ifndef SIMTK_ROTATION_H
00008 #define SIMTK_ROTATION_H
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include "SimTKcommon/SmallMatrix.h"
00044 #include "SimTKcommon/internal/UnitVec.h"
00045 #include "SimTKcommon/internal/Quaternion.h"
00046 #include "SimTKcommon/internal/CoordinateAxis.h"
00047
00048
00049 #include <iosfwd>
00050
00051
00052
00053 namespace SimTK {
00054
00055
00056 enum BodyOrSpaceType { BodyRotationSequence=0, SpaceRotationSequence=1 };
00057
00058
00059
00060 template <class P> class Rotation_;
00061 template <class P> class InverseRotation_;
00062
00063 typedef Rotation_<Real> Rotation;
00064 typedef Rotation_<float> fRotation;
00065 typedef Rotation_<double> dRotation;
00066
00067 typedef InverseRotation_<Real> InverseRotation;
00068 typedef InverseRotation_<float> fInverseRotation;
00069 typedef InverseRotation_<double> dInverseRotation;
00070
00071
00116
00117 template <class P>
00118 class Rotation_ : public Mat<3,3,P> {
00119 typedef P RealP;
00120 typedef Mat<2,2,P> Mat22P;
00121 typedef Mat<3,2,P> Mat32P;
00122 typedef Mat<3,3,P> Mat33P;
00123 typedef Vec<2,P> Vec2P;
00124 typedef Vec<3,P> Vec3P;
00125 typedef Vec<4,P> Vec4P;
00126 typedef UnitVec<P,1> UnitVec3P;
00127 typedef SymMat<3,P> SymMat33P;
00128 typedef Quaternion_<P> QuaternionP;
00129 public:
00130
00131 Rotation_() : Mat33P(1) {}
00132 Rotation_& setRotationToIdentityMatrix() { Mat33P::operator=(RealP(1)); return *this; }
00133 Rotation_& setRotationToNaN() { Mat33P::setToNaN(); return *this; }
00134
00135
00136 Rotation_( const Rotation_& R ) : Mat33P(R) {}
00137 Rotation_& operator=( const Rotation_& R ) { Mat33P::operator=( R.asMat33() ); return *this; }
00138
00140
00141 Rotation_( RealP angle, const CoordinateAxis& axis ) { setRotationFromAngleAboutAxis( angle, axis ); }
00142 Rotation_( RealP angle, const CoordinateAxis::XCoordinateAxis ) { setRotationFromAngleAboutX( std::cos(angle), std::sin(angle) ); }
00143 Rotation_( RealP angle, const CoordinateAxis::YCoordinateAxis ) { setRotationFromAngleAboutY( std::cos(angle), std::sin(angle) ); }
00144 Rotation_( RealP angle, const CoordinateAxis::ZCoordinateAxis ) { setRotationFromAngleAboutZ( std::cos(angle), std::sin(angle) ); }
00146
00147
00148 Rotation_& setRotationFromAngleAboutAxis( RealP angle, const CoordinateAxis& axis ) { return axis.isXAxis() ? setRotationFromAngleAboutX(angle) : (axis.isYAxis() ? setRotationFromAngleAboutY(angle) : setRotationFromAngleAboutZ(angle) ); }
00149 Rotation_& setRotationFromAngleAboutX( RealP angle ) { return setRotationFromAngleAboutX( std::cos(angle), std::sin(angle) ); }
00150 Rotation_& setRotationFromAngleAboutY( RealP angle ) { return setRotationFromAngleAboutY( std::cos(angle), std::sin(angle) ); }
00151 Rotation_& setRotationFromAngleAboutZ( RealP angle ) { return setRotationFromAngleAboutZ( std::cos(angle), std::sin(angle) ); }
00152 Rotation_& setRotationFromAngleAboutX( RealP cosAngle, RealP sinAngle ) { Mat33P& R = *this; R[0][0] = 1; R[0][1] = R[0][2] = R[1][0] = R[2][0] = 0; R[1][1] = R[2][2] = cosAngle; R[1][2] = -(R[2][1] = sinAngle); return *this; }
00153 Rotation_& setRotationFromAngleAboutY( RealP cosAngle, RealP sinAngle ) { Mat33P& R = *this; R[1][1] = 1; R[0][1] = R[1][0] = R[1][2] = R[2][1] = 0; R[0][0] = R[2][2] = cosAngle; R[2][0] = -(R[0][2] = sinAngle); return *this; }
00154 Rotation_& setRotationFromAngleAboutZ( RealP cosAngle, RealP sinAngle ) { Mat33P& R = *this; R[2][2] = 1; R[0][2] = R[1][2] = R[2][0] = R[2][1] = 0; R[0][0] = R[1][1] = cosAngle; R[0][1] = -(R[1][0] = sinAngle); return *this; }
00156
00158
00159 Rotation_( RealP angle, const UnitVec3P& unitVector ) { setRotationFromAngleAboutUnitVector(angle,unitVector); }
00160 Rotation_( RealP angle, const Vec3P& nonUnitVector ) { setRotationFromAngleAboutNonUnitVector(angle,nonUnitVector); }
00162
00163
00164 Rotation_& setRotationFromAngleAboutNonUnitVector( RealP angle, const Vec3P& nonUnitVector ) { return setRotationFromAngleAboutUnitVector( angle, UnitVec3P(nonUnitVector) ); }
00165 SimTK_SimTKCOMMON_EXPORT Rotation_& setRotationFromAngleAboutUnitVector( RealP angle, const UnitVec3P& unitVector );
00167
00169 Rotation_( BodyOrSpaceType bodyOrSpace, RealP angle1, const CoordinateAxis& axis1, RealP angle2, const CoordinateAxis& axis2 ) { setRotationFromTwoAnglesTwoAxes( bodyOrSpace,angle1,axis1,angle2,axis2); }
00171 Rotation_( BodyOrSpaceType bodyOrSpace, RealP angle1, const CoordinateAxis& axis1, RealP angle2, const CoordinateAxis& axis2, RealP angle3, const CoordinateAxis& axis3 ) { setRotationFromThreeAnglesThreeAxes(bodyOrSpace,angle1,axis1,angle2,axis2,angle3,axis3); }
00173 SimTK_SimTKCOMMON_EXPORT Rotation_& setRotationFromTwoAnglesTwoAxes( BodyOrSpaceType bodyOrSpace, RealP angle1, const CoordinateAxis& axis1, RealP angle2, const CoordinateAxis& axis2 );
00175 SimTK_SimTKCOMMON_EXPORT Rotation_& setRotationFromThreeAnglesThreeAxes( BodyOrSpaceType bodyOrSpace, RealP angle1, const CoordinateAxis& axis1, RealP angle2, const CoordinateAxis& axis2, RealP angle3, const CoordinateAxis& axis3 );
00176
00180 void setRotationToBodyFixedXY( const Vec2P& v) { setRotationFromTwoAnglesTwoAxes( BodyRotationSequence, v[0], XAxis, v[1], YAxis ); }
00185 void setRotationToBodyFixedXYZ( const Vec3P& v) { setRotationFromThreeAnglesThreeAxes( BodyRotationSequence, v[0], XAxis, v[1], YAxis, v[2], ZAxis ); }
00186
00188 explicit Rotation_( const QuaternionP& q ) { setRotationFromQuaternion(q); }
00190 SimTK_SimTKCOMMON_EXPORT Rotation_& setRotationFromQuaternion( const QuaternionP& q );
00191
00193 Rotation_( const Mat33P& m, bool ) : Mat33P(m) {}
00194
00196 explicit Rotation_( const Mat33P& m ) { setRotationFromApproximateMat33(m); }
00198 SimTK_SimTKCOMMON_EXPORT Rotation_& setRotationFromApproximateMat33( const Mat33P& m );
00199
00202
00203 Rotation_( const UnitVec3P& uvec, const CoordinateAxis axis ) { setRotationFromOneAxis(uvec,axis); }
00204 SimTK_SimTKCOMMON_EXPORT Rotation_& setRotationFromOneAxis( const UnitVec3P& uvec, const CoordinateAxis axis );
00206
00213
00214 Rotation_( const UnitVec3P& uveci, const CoordinateAxis& axisi, const Vec3P& vecjApprox, const CoordinateAxis& axisjApprox ) { setRotationFromTwoAxes(uveci,axisi,vecjApprox,axisjApprox); }
00215 SimTK_SimTKCOMMON_EXPORT Rotation_& setRotationFromTwoAxes( const UnitVec3P& uveci, const CoordinateAxis& axisi, const Vec3P& vecjApprox, const CoordinateAxis& axisjApprox );
00217
00218
00219
00220
00221
00222
00223
00224
00227 SimTK_SimTKCOMMON_EXPORT RealP convertOneAxisRotationToOneAngle( const CoordinateAxis& axis1 ) const;
00230 SimTK_SimTKCOMMON_EXPORT Vec2P convertTwoAxesRotationToTwoAngles( BodyOrSpaceType bodyOrSpace, const CoordinateAxis& axis1, const CoordinateAxis& axis2 ) const;
00233 SimTK_SimTKCOMMON_EXPORT Vec3P convertThreeAxesRotationToThreeAngles( BodyOrSpaceType bodyOrSpace, const CoordinateAxis& axis1, const CoordinateAxis& axis2, const CoordinateAxis& axis3 ) const;
00235 SimTK_SimTKCOMMON_EXPORT QuaternionP convertRotationToQuaternion() const;
00237 Vec4P convertRotationToAngleAxis() const { return convertRotationToQuaternion().convertQuaternionToAngleAxis(); }
00238
00240 Vec2P convertRotationToBodyFixedXY() const { return convertTwoAxesRotationToTwoAngles( BodyRotationSequence, XAxis, YAxis ); }
00242 Vec3P convertRotationToBodyFixedXYZ() const { return convertThreeAxesRotationToThreeAngles( BodyRotationSequence, XAxis, YAxis, ZAxis ); }
00243
00251 SimTK_SimTKCOMMON_EXPORT SymMat33P reexpressSymMat33(const SymMat33P& S_BB) const;
00252
00254
00255 SimTK_SimTKCOMMON_EXPORT bool isSameRotationToWithinAngle( const Rotation_& R, RealP okPointingAngleErrorRads ) const;
00256 bool isSameRotationToWithinAngleOfMachinePrecision( const Rotation_& R) const
00257 { return isSameRotationToWithinAngle( R, NTraits<P>::getSignificant() ); }
00259 RealP getMaxAbsDifferenceInRotationElements( const Rotation_& R ) const {
00260 const Mat33P& A = asMat33(); const Mat33P& B = R.asMat33(); RealP maxDiff = 0;
00261 for( int i=0; i<=2; i++ ) for( int j=0; j<=2; j++ )
00262 { RealP absDiff = std::fabs(A[i][j] - B[i][j]);
00263 if( absDiff > maxDiff ) maxDiff = absDiff; }
00264 return maxDiff;
00265 }
00266
00267 bool areAllRotationElementsSameToEpsilon( const Rotation_& R, RealP epsilon ) const
00268 { return getMaxAbsDifferenceInRotationElements(R) <= epsilon ; }
00269 bool areAllRotationElementsSameToMachinePrecision( const Rotation_& R ) const
00270 { return areAllRotationElementsSameToEpsilon( R, NTraits<P>::getSignificant() ); }
00271
00273 inline Rotation_( const InverseRotation_<P>& );
00275 inline Rotation_& operator=( const InverseRotation_<P>& );
00276
00278 const InverseRotation_<P>& invert() const { return *reinterpret_cast<const InverseRotation_<P>*>(this); }
00280 InverseRotation_<P>& updInvert() { return *reinterpret_cast<InverseRotation_<P>*>(this); }
00281
00284
00285 const InverseRotation_<P>& transpose() const { return invert(); }
00286 const InverseRotation_<P>& operator~() const { return invert(); }
00287 InverseRotation_<P>& updTranspose() { return updInvert(); }
00288 InverseRotation_<P>& operator~() { return updInvert(); }
00290
00292
00293 inline Rotation_& operator*=( const Rotation_<P>& R );
00294 inline Rotation_& operator/=( const Rotation_<P>& R );
00295 inline Rotation_& operator*=( const InverseRotation_<P>& );
00296 inline Rotation_& operator/=( const InverseRotation_<P>& );
00298
00301
00302 const Mat33P& asMat33() const { return *static_cast<const Mat33P*>(this); }
00303 Mat33P toMat33() const { return asMat33(); }
00305
00307 typedef UnitVec<P,Mat33P::RowSpacing> ColType;
00308 typedef UnitRow<P,Mat33P::ColSpacing> RowType;
00309 const RowType& row( int i ) const { return reinterpret_cast<const RowType&>(asMat33()[i]); }
00310 const ColType& col( int j ) const { return reinterpret_cast<const ColType&>(asMat33()(j)); }
00311 const ColType& x() const { return col(0); }
00312 const ColType& y() const { return col(1); }
00313 const ColType& z() const { return col(2); }
00314 const RowType& operator[]( int i ) const { return row(i); }
00315 const ColType& operator()( int j ) const { return col(j); }
00316
00318
00319 Rotation_& setRotationFromMat33TrustMe( const Mat33P& m )
00320 { Mat33P& R = *this; R=m; return *this; }
00321 Rotation_& setRotationColFromUnitVecTrustMe( int colj, const UnitVec3P& uvecj )
00322 { Mat33P& R = *this; R(colj)=uvecj.asVec3(); return *this; }
00323 Rotation_& setRotationFromUnitVecsTrustMe( const UnitVec3P& colA, const UnitVec3P& colB, const UnitVec3P& colC )
00324 { Mat33P& R = *this; R(0)=colA.asVec3(); R(1)=colB.asVec3(); R(2)=colC.asVec3(); return *this; }
00326
00327
00328
00329 public:
00330
00336 static Vec3P convertAngVelToBodyFixed321Dot(const Vec3P& q, const Vec3P& w_PB_B) {
00337 const RealP s1 = std::sin(q[1]), c1 = std::cos(q[1]);
00338 const RealP s2 = std::sin(q[2]), c2 = std::cos(q[2]);
00339 const RealP ooc1 = RealP(1)/c1;
00340 const RealP s2oc1 = s2*ooc1, c2oc1 = c2*ooc1;
00341
00342 const Mat33P E( 0, s2oc1 , c2oc1 ,
00343 0, c2 , -s2 ,
00344 1, s1*s2oc1 , s1*c2oc1 );
00345 return E * w_PB_B;
00346 }
00347
00350 static Vec3P convertBodyFixed321DotToAngVel(const Vec3P& q, const Vec3P& qd) {
00351 const RealP s1 = std::sin(q[1]), c1 = std::cos(q[1]);
00352 const RealP s2 = std::sin(q[2]), c2 = std::cos(q[2]);
00353
00354 const Mat33P Einv( -s1 , 0 , 1 ,
00355 c1*s2 , c2 , 0 ,
00356 c1*c2 , -s2 , 0 );
00357 return Einv*qd;
00358 }
00359
00360
00361
00362 static Vec3P convertAngVelDotToBodyFixed321DotDot
00363 (const Vec3P& q, const Vec3P& w_PB_B, const Vec3P& wdot)
00364 {
00365 const RealP s1 = std::sin(q[1]), c1 = std::cos(q[1]);
00366 const RealP s2 = std::sin(q[2]), c2 = std::cos(q[2]);
00367 const RealP ooc1 = 1/c1;
00368 const RealP s2oc1 = s2*ooc1, c2oc1 = c2*ooc1;
00369
00370 const Mat33P E( 0 , s2oc1 , c2oc1 ,
00371 0 , c2 , -s2 ,
00372 1 , s1*s2oc1 , s1*c2oc1 );
00373 const Vec3P qdot = E * w_PB_B;
00374
00375 const RealP t = qdot[1]*qdot[2]*s1*ooc1;
00376 const RealP a = t*c2oc1;
00377 const RealP b = -t*s2oc1;
00378
00379 const Mat33P Edot( 0 , a , b ,
00380 0 , -qdot[2]*s2 , -qdot[2]*c2 ,
00381 0 , s1*a + qdot[1]*s2 , s1*b + qdot[1]*c2 );
00382
00383 return E*wdot + Edot*w_PB_B;
00384 }
00385
00394 static Mat33P calcNForBodyXYZInBodyFrame(const Vec3P& q) {
00395
00396
00397 return calcNForBodyXYZInBodyFrame(Vec3P(0,std::cos(q[1]),std::cos(q[2])),
00398 Vec3P(0,std::sin(q[1]),std::sin(q[2])));
00399 }
00400
00406 static Mat33P calcNForBodyXYZInBodyFrame(const Vec3P& cq, const Vec3P& sq) {
00407 const RealP s1 = sq[1], c1 = cq[1];
00408 const RealP s2 = sq[2], c2 = cq[2];
00409 const RealP ooc1 = 1/c1;
00410 const RealP s2oc1 = s2*ooc1, c2oc1 = c2*ooc1;
00411
00412 return Mat33P( c2oc1 , -s2oc1 , 0,
00413 s2 , c2 , 0,
00414 -s1*c2oc1 , s1*s2oc1, 1 );
00415 }
00416
00426 static Mat33P calcNDotForBodyXYZInBodyFrame(const Vec3P& q, const Vec3P& qdot) {
00427
00428
00429 return calcNDotForBodyXYZInBodyFrame(Vec3P(0,std::cos(q[1]),std::cos(q[2])),
00430 Vec3P(0,std::sin(q[1]),std::sin(q[2])),
00431 qdot);
00432 }
00433
00439 static Mat33P calcNDotForBodyXYZInBodyFrame(const Vec3P& cq, const Vec3P& sq,
00440 const Vec3P& qdot)
00441 {
00442 const RealP s1 = sq[1], c1 = cq[1];
00443 const RealP s2 = sq[2], c2 = cq[2];
00444 const RealP ooc1 = 1/c1;
00445 const RealP s2oc1 = s2*ooc1, c2oc1 = c2*ooc1;
00446
00447 const RealP t = qdot[1]*qdot[2]*s1*ooc1;
00448 const RealP a = t*c2oc1;
00449 const RealP b = -t*s2oc1;
00450
00451 return Mat33P( b , -a , 0,
00452 qdot[2]*c2 , -qdot[2]*s2 , 0,
00453 -s1*b - qdot[1]*c2 , s1*a + qdot[1]*s2 , 0 );
00454 }
00455
00462 static Mat33P calcNInvForBodyXYZInBodyFrame(const Vec3P& q) {
00463
00464
00465 return calcNInvForBodyXYZInBodyFrame(Vec3P(0,std::cos(q[1]),std::cos(q[2])),
00466 Vec3P(0,std::sin(q[1]),std::sin(q[2])));
00467 }
00468
00474 static Mat33P calcNInvForBodyXYZInBodyFrame(const Vec3P& cq, const Vec3P& sq)
00475 {
00476 const RealP s1 = sq[1], c1 = cq[1];
00477 const RealP s2 = sq[2], c2 = cq[2];
00478
00479 return Mat33P( c1*c2 , s2 , 0 ,
00480 -c1*s2 , c2 , 0 ,
00481 s1 , 0 , 1 );
00482 }
00483
00492 static Vec3P convertAngVelInBodyFrameToBodyXYZDot(const Vec3P& q, const Vec3P& w_PB_B)
00493 { return convertAngVelInBodyFrameToBodyXYZDot(Vec3P(0,std::cos(q[1]),std::cos(q[2])),
00494 Vec3P(0,std::sin(q[1]),std::sin(q[2])),
00495 w_PB_B); }
00496
00502 static Vec3P convertAngVelInBodyFrameToBodyXYZDot
00503 (const Vec3P& cq, const Vec3P& sq, const Vec3P& w_PB_B)
00504 { return calcNForBodyXYZInBodyFrame(cq,sq)*w_PB_B; }
00505
00511 static Vec3P convertBodyXYZDotToAngVelInBodyFrame(const Vec3P& q, const Vec3P& qdot)
00512 { return convertBodyXYZDotToAngVelInBodyFrame(Vec3P(0,std::cos(q[1]),std::cos(q[2])),
00513 Vec3P(0,std::sin(q[1]),std::sin(q[2])),
00514 qdot); }
00515
00521 static Vec3P convertBodyXYZDotToAngVelInBodyFrame
00522 (const Vec3P& cq, const Vec3P& sq, const Vec3P& qdot)
00523 { return calcNInvForBodyXYZInBodyFrame(cq,sq)*qdot; }
00524
00530 static Vec3P convertAngVelDotInBodyFrameToBodyXYZDotDot
00531 (const Vec3P& q, const Vec3P& w_PB_B, const Vec3P& wdot_PB_B)
00532 {
00533
00534
00535 return convertAngVelDotInBodyFrameToBodyXYZDotDot
00536 (Vec3P(0,std::cos(q[1]),std::cos(q[2])),
00537 Vec3P(0,std::sin(q[1]),std::sin(q[2])),
00538 w_PB_B, wdot_PB_B);
00539 }
00540
00546 static Vec3P convertAngVelDotInBodyFrameToBodyXYZDotDot
00547 (const Vec3P& cq, const Vec3P& sq, const Vec3P& w_PB_B, const Vec3P& wdot_PB_B)
00548 {
00549 const Mat33P N = calcNForBodyXYZInBodyFrame(cq,sq);
00550 const Vec3P qdot = N * w_PB_B;
00551 const Mat33P NDot = calcNDotForBodyXYZInBodyFrame(cq,sq,qdot);
00552
00553 return N*wdot_PB_B + NDot*w_PB_B;
00554 }
00555
00561 static Mat<4,3,P> calcUnnormalizedNForQuaternion(const Vec4P& q) {
00562 const Vec4P e = q/2;
00563 const RealP ne1 = -e[1], ne2 = -e[2], ne3 = -e[3];
00564 return Mat<4,3,P>( ne1, ne2, ne3,
00565 e[0], e[3], ne2,
00566 ne3, e[0], e[1],
00567 e[2], ne1, e[0]);
00568 }
00569
00576 static Mat<4,3,P> calcUnnormalizedNDotForQuaternion(const Vec4P& qdot) {
00577 const Vec4P ed = qdot/2;
00578 const RealP ned1 = -ed[1], ned2 = -ed[2], ned3 = -ed[3];
00579 return Mat<4,3,P>( ned1, ned2, ned3,
00580 ed[0], ed[3], ned2,
00581 ned3, ed[0], ed[1],
00582 ed[2], ned1, ed[0]);
00583 }
00584
00593 static Mat<3,4,P> calcUnnormalizedNInvForQuaternion(const Vec4P& q) {
00594 const Vec4P e = 2*q;
00595 const RealP ne1 = -e[1], ne2 = -e[2], ne3 = -e[3];
00596 return Mat<3,4,P>(ne1, e[0], ne3, e[2],
00597 ne2, e[3], e[0], ne1,
00598 ne3, ne2, e[1], e[0]);
00599 }
00600
00601
00606 static Vec4P convertAngVelToQuaternionDot(const Vec4P& q, const Vec3P& w_PB_P) {
00607 return calcUnnormalizedNForQuaternion(q)*w_PB_P;
00608 }
00609
00613 static Vec3P convertQuaternionDotToAngVel(const Vec4P& q, const Vec4P& qdot) {
00614 return calcUnnormalizedNInvForQuaternion(q)*qdot;
00615 }
00616
00622 static Vec4P convertAngVelDotToQuaternionDotDot
00623 (const Vec4P& q, const Vec3P& w_PB_P, const Vec3P& wdot_PB_P)
00624 {
00625 const Mat<4,3,P> N = calcUnnormalizedNForQuaternion(q);
00626 const Vec4P qdot = N*w_PB_P;
00627 const Mat<4,3,P> NDot = calcUnnormalizedNDotForQuaternion(qdot);
00628
00629 return N*wdot_PB_P + NDot*w_PB_P;
00630 }
00631
00632
00633 private:
00634
00635
00636
00637
00638 Rotation_( const RealP& xx, const RealP& xy, const RealP& xz,
00639 const RealP& yx, const RealP& yy, const RealP& yz,
00640 const RealP& zx, const RealP& zy, const RealP& zz )
00641 : Mat33P( xx,xy,xz, yx,yy,yz, zx,zy,zz ) {}
00642
00643
00644
00645 SimTK_SimTKCOMMON_EXPORT Rotation_& setTwoAngleTwoAxesBodyFixedForwardCyclicalRotation( RealP cosAngle1, RealP sinAngle1, const CoordinateAxis& axis1, RealP cosAngle2, RealP sinAngle2, const CoordinateAxis& axis2 );
00646 SimTK_SimTKCOMMON_EXPORT Rotation_& setThreeAngleTwoAxesBodyFixedForwardCyclicalRotation( RealP cosAngle1, RealP sinAngle1, const CoordinateAxis& axis1, RealP cosAngle2, RealP sinAngle2, const CoordinateAxis& axis2, RealP cosAngle3, RealP sinAngle3 );
00647 SimTK_SimTKCOMMON_EXPORT Rotation_& setThreeAngleThreeAxesBodyFixedForwardCyclicalRotation( RealP cosAngle1, RealP sinAngle1, const CoordinateAxis& axis1, RealP cosAngle2, RealP sinAngle2, const CoordinateAxis& axis2, RealP cosAngle3, RealP sinAngle3, const CoordinateAxis& axis3 );
00648
00649
00650
00651 SimTK_SimTKCOMMON_EXPORT Vec2P convertTwoAxesBodyFixedRotationToTwoAngles( const CoordinateAxis& axis1, const CoordinateAxis& axis2 ) const;
00652 SimTK_SimTKCOMMON_EXPORT Vec3P convertTwoAxesBodyFixedRotationToThreeAngles( const CoordinateAxis& axis1, const CoordinateAxis& axis2 ) const;
00653 SimTK_SimTKCOMMON_EXPORT Vec3P convertThreeAxesBodyFixedRotationToThreeAngles( const CoordinateAxis& axis1, const CoordinateAxis& axis2, const CoordinateAxis& axis3 ) const;
00654
00655
00656
00657
00658
00659 private:
00660
00661 static Mat33P calcQBlockForBodyXYZInBodyFrame(const Vec3P& a)
00662 { return calcNForBodyXYZInBodyFrame(a); }
00663
00664 static Mat33P calcQInvBlockForBodyXYZInBodyFrame(const Vec3P& a)
00665 { return calcNInvForBodyXYZInBodyFrame(a); }
00666
00667 static Mat<4,3,P> calcUnnormalizedQBlockForQuaternion(const Vec4P& q)
00668 { return calcUnnormalizedNForQuaternion(q); }
00669
00670 static Mat<3,4,P> calcUnnormalizedQInvBlockForQuaternion(const Vec4P& q)
00671 { return calcUnnormalizedNInvForQuaternion(q); }
00672
00673 static Vec3P convertAngVelToBodyFixed123Dot(const Vec3P& q, const Vec3P& w_PB_B)
00674 { return convertAngVelInBodyFrameToBodyXYZDot(q,w_PB_B); }
00675
00676 static Vec3P convertBodyFixed123DotToAngVel(const Vec3P& q, const Vec3P& qdot)
00677 { return convertBodyXYZDotToAngVelInBodyFrame(q,qdot); }
00678
00679 static Vec3P convertAngVelDotToBodyFixed123DotDot
00680 (const Vec3P& q, const Vec3P& w_PB_B, const Vec3P& wdot_PB_B)
00681 { return convertAngVelDotInBodyFrameToBodyXYZDotDot(q,w_PB_B,wdot_PB_B); }
00682
00683
00684
00685
00686
00687 private:
00688
00689 static Rotation_ zero() { return Rotation_(); }
00690 static Rotation_ NaN() { Rotation_ r; r.setRotationToNaN(); return r; }
00691
00693 Rotation_& setToZero() { return setRotationToIdentityMatrix(); }
00694 Rotation_& setToIdentityMatrix() { return setRotationToIdentityMatrix(); }
00695 Rotation_& setToNaN() { return setRotationToNaN(); }
00696 static Rotation_ trustMe( const Mat33P& m ) { return Rotation_(m,true); }
00697
00698
00699 static Rotation_ aboutX( const RealP& angleInRad ) { return Rotation_( angleInRad, XAxis ); }
00700 static Rotation_ aboutY( const RealP& angleInRad ) { return Rotation_( angleInRad, YAxis ); }
00701 static Rotation_ aboutZ( const RealP& angleInRad ) { return Rotation_( angleInRad, ZAxis ); }
00702 static Rotation_ aboutAxis( const RealP& angleInRad, const UnitVec3P& axis ) { return Rotation_(angleInRad,axis); }
00703 static Rotation_ aboutAxis( const RealP& angleInRad, const Vec3P& axis ) { return Rotation_(angleInRad,axis); }
00704 void setToRotationAboutZ( const RealP& q ) { setRotationFromAngleAboutZ( q ); }
00705
00706
00707 static Rotation_ aboutXThenOldY(const RealP& xInRad, const RealP& yInRad) { return Rotation_( SpaceRotationSequence, xInRad, XAxis, yInRad, YAxis ); }
00708 static Rotation_ aboutYThenOldX(const RealP& yInRad, const RealP& xInRad) { return Rotation_( SpaceRotationSequence, yInRad, YAxis, xInRad, XAxis ); }
00709 static Rotation_ aboutXThenOldZ(const RealP& xInRad, const RealP& zInRad) { return Rotation_( SpaceRotationSequence, xInRad, XAxis, zInRad, ZAxis ); }
00710 static Rotation_ aboutZThenOldX(const RealP& zInRad, const RealP& xInRad) { return Rotation_( SpaceRotationSequence, zInRad, ZAxis, xInRad, XAxis ); }
00711 static Rotation_ aboutYThenOldZ(const RealP& yInRad, const RealP& zInRad) { return Rotation_( SpaceRotationSequence, yInRad, YAxis, zInRad, ZAxis ); }
00712 static Rotation_ aboutZThenOldY(const RealP& zInRad, const RealP& yInRad) { return Rotation_( SpaceRotationSequence, zInRad, ZAxis, yInRad, YAxis ); }
00713
00714
00715 static Rotation_ aboutXThenNewY(const RealP& xInRad, const RealP& yInRad) { return Rotation_( BodyRotationSequence, xInRad, XAxis, yInRad, YAxis ); }
00716 static Rotation_ aboutYThenNewX(const RealP& yInRad, const RealP& xInRad) { return aboutXThenOldY(xInRad, yInRad); }
00717 static Rotation_ aboutXThenNewZ(const RealP& xInRad, const RealP& zInRad) { return aboutZThenOldX(zInRad, xInRad); }
00718 static Rotation_ aboutZThenNewX(const RealP& zInRad, const RealP& xInRad) { return aboutXThenOldZ(xInRad, zInRad); }
00719 static Rotation_ aboutYThenNewZ(const RealP& yInRad, const RealP& zInRad) { return aboutZThenOldY(zInRad, yInRad); }
00720 static Rotation_ aboutZThenNewY(const RealP& zInRad, const RealP& yInRad) { return aboutYThenOldZ(yInRad, zInRad); }
00721
00724 explicit Rotation_( const UnitVec3P& uvecZ ) { setRotationFromOneAxis(uvecZ,ZAxis); }
00725
00727
00728
00729 Rotation_( const Vec3P& x, const Vec3P& yish ) { setRotationFromTwoAxes( UnitVec3P(x), XAxis, yish, YAxis ); }
00730
00732 void setToQuaternion( const QuaternionP& q ) { setRotationFromQuaternion(q); }
00733
00738
00739 void setToBodyFixed321( const Vec3P& v) { setRotationFromThreeAnglesThreeAxes( BodyRotationSequence, v[0], ZAxis, v[1], YAxis, v[2], XAxis ); }
00740 void setToBodyFixed123( const Vec3P& v) { setRotationToBodyFixedXYZ(v); }
00741
00744 Vec4P convertToAngleAxis() const { return convertRotationToAngleAxis(); }
00745
00747 QuaternionP convertToQuaternion() const { return convertRotationToQuaternion(); }
00748
00751 void setToSpaceFixed12( const Vec2P& q ) { setRotationFromTwoAnglesTwoAxes( SpaceRotationSequence, q[0], XAxis, q[1], YAxis ); }
00752
00756 Vec3P convertToBodyFixed123() const { return convertRotationToBodyFixedXYZ(); }
00757 Vec2P convertToBodyFixed12() const { return convertRotationToBodyFixedXY(); }
00758 Vec2P convertToSpaceFixed12() const { return convertTwoAxesRotationToTwoAngles( SpaceRotationSequence, XAxis, YAxis ); }
00759 };
00760
00761
00766 template <class P>
00767 class InverseRotation_ : public Mat<3,3,P>::TransposeType {
00768 typedef P RealP;
00769 typedef Rotation_<P> RotationP;
00770 typedef Mat<3,3,P> Mat33P;
00771 typedef SymMat<3,P> SymMat33P;
00772 typedef Mat<2,2,P> Mat22P;
00773 typedef Mat<3,2,P> Mat32P;
00774 typedef Vec<2,P> Vec2P;
00775 typedef Vec<3,P> Vec3P;
00776 typedef Vec<4,P> Vec4P;
00777 typedef Quaternion_<P> QuaternionP;
00778 public:
00781 typedef typename Mat<3,3,P>::TransposeType BaseMat;
00782
00785
00786
00787 typedef UnitVec<P,BaseMat::RowSpacing> ColType;
00789 typedef UnitRow<P,BaseMat::ColSpacing> RowType;
00791
00795 InverseRotation_() : BaseMat(1) {}
00796
00798 InverseRotation_( const InverseRotation_& R ) : BaseMat(R) {}
00800 InverseRotation_& operator=( const InverseRotation_& R )
00801 { BaseMat::operator=(R.asMat33()); return *this; }
00802
00809 SimTK_SimTKCOMMON_EXPORT SymMat33P reexpressSymMat33(const SymMat33P& S_BB) const;
00810
00812
00813 const RotationP& invert() const {return *reinterpret_cast<const RotationP*>(this);}
00814 RotationP& updInvert() {return *reinterpret_cast<RotationP*>(this);}
00816
00819
00820 const RotationP& transpose() const { return invert(); }
00821 const RotationP& operator~() const { return invert(); }
00822 RotationP& updTranspose() { return updInvert(); }
00823 RotationP& operator~() { return updInvert(); }
00825
00831
00832 const RowType& row( int i ) const { return reinterpret_cast<const RowType&>(asMat33()[i]); }
00833 const ColType& col( int j ) const { return reinterpret_cast<const ColType&>(asMat33()(j)); }
00834 const ColType& x() const { return col(0); }
00835 const ColType& y() const { return col(1); }
00836 const ColType& z() const { return col(2); }
00837 const RowType& operator[]( int i ) const { return row(i); }
00838 const ColType& operator()( int j ) const { return col(j); }
00840
00843
00844 const BaseMat& asMat33() const { return *static_cast<const BaseMat*>(this); }
00845 BaseMat toMat33() const { return asMat33(); }
00847 };
00848
00850 template <class P> SimTK_SimTKCOMMON_EXPORT std::ostream&
00851 operator<<(std::ostream&, const Rotation_<P>&);
00853 template <class P> SimTK_SimTKCOMMON_EXPORT std::ostream&
00854 operator<<(std::ostream&, const InverseRotation_<P>&);
00855
00859
00860 template <class P, int S> inline UnitVec<P,1>
00861 operator*(const Rotation_<P>& R, const UnitVec<P,S>& v) {return UnitVec<P,1>(R.asMat33()* v.asVec3(), true);}
00862 template <class P, int S> inline UnitRow<P,1>
00863 operator*(const UnitRow<P,S>& r, const Rotation_<P>& R) {return UnitRow<P,1>(r.asRow3() * R.asMat33(), true);}
00864 template <class P, int S> inline UnitVec<P,1>
00865 operator*(const InverseRotation_<P>& R, const UnitVec<P,S>& v) {return UnitVec<P,1>(R.asMat33()* v.asVec3(), true);}
00866 template <class P, int S> inline UnitRow<P,1>
00867 operator*(const UnitRow<P,S>& r, const InverseRotation_<P>& R) {return UnitRow<P,1>(r.asRow3() * R.asMat33(), true);}
00869
00870
00871 template <class P> inline
00872 Rotation_<P>::Rotation_(const InverseRotation_<P>& R) : Mat<3,3,P>( R.asMat33() ) {}
00873 template <class P> inline Rotation_<P>&
00874 Rotation_<P>::operator=(const InverseRotation_<P>& R) {static_cast<Mat<3,3,P>&>(*this) = R.asMat33(); return *this;}
00875 template <class P> inline Rotation_<P>&
00876 Rotation_<P>::operator*=(const Rotation_<P>& R) {static_cast<Mat<3,3,P>&>(*this) *= R.asMat33(); return *this;}
00877 template <class P> inline Rotation_<P>&
00878 Rotation_<P>::operator/=(const Rotation_<P>& R) {static_cast<Mat<3,3,P>&>(*this) *= (~R).asMat33(); return *this;}
00879 template <class P> inline Rotation_<P>&
00880 Rotation_<P>::operator*=(const InverseRotation_<P>& R) {static_cast<Mat<3,3,P>&>(*this) *= R.asMat33(); return *this;}
00881 template <class P> inline Rotation_<P>&
00882 Rotation_<P>::operator/=(const InverseRotation_<P>& R) {static_cast<Mat<3,3,P>&>(*this) *= (~R).asMat33(); return *this;}
00883
00885
00886 template <class P> inline Rotation_<P>
00887 operator*(const Rotation_<P>& R1, const Rotation_<P>& R2) {return Rotation_<P>(R1) *= R2;}
00888 template <class P> inline Rotation_<P>
00889 operator*(const Rotation_<P>& R1, const InverseRotation_<P>& R2) {return Rotation_<P>(R1) *= R2;}
00890 template <class P> inline Rotation_<P>
00891 operator*(const InverseRotation_<P>& R1, const Rotation_<P>& R2) {return Rotation_<P>(R1) *= R2;}
00892 template <class P> inline Rotation_<P>
00893 operator*(const InverseRotation_<P>& R1, const InverseRotation_<P>& R2) {return Rotation_<P>(R1) *= R2;}
00895
00898
00899 template <class P> inline Rotation_<P>
00900 operator/( const Rotation_<P>& R1, const Rotation_<P>& R2 ) {return Rotation_<P>(R1) /= R2;}
00901 template <class P> inline Rotation_<P>
00902 operator/( const Rotation_<P>& R1, const InverseRotation& R2 ) {return Rotation_<P>(R1) /= R2;}
00903 template <class P> inline Rotation_<P>
00904 operator/( const InverseRotation_<P>& R1, const Rotation_<P>& R2 ) {return Rotation_<P>(R1) /= R2;}
00905 template <class P> inline Rotation_<P>
00906 operator/( const InverseRotation_<P>& R1, const InverseRotation_<P>& R2 ) {return Rotation_<P>(R1) /= R2;}
00908
00909
00910
00911 }
00912
00913
00914 #endif // SIMTK_ROTATION_H_
00915
00916
00917