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 class InverseRotation;
00061
00062
00063
00088
00089 class Rotation : public Mat33 {
00090 public:
00091
00092 Rotation() : Mat33(1) {}
00093 Rotation& setRotationToIdentityMatrix() { Mat33::operator=(1); return *this; }
00094 Rotation& setRotationToNaN() { Mat33::setToNaN(); return *this; }
00095
00096
00097 Rotation( const Rotation& R ) : Mat33(R) {}
00098 Rotation& operator=( const Rotation& R ) { Mat33::operator=( R.asMat33() ); return *this; }
00099
00101
00102 Rotation( Real angle, const CoordinateAxis& axis ) { setRotationFromAngleAboutAxis( angle, axis ); }
00103 Rotation( Real angle, const CoordinateAxis::XCoordinateAxis ) { setRotationFromAngleAboutX( std::cos(angle), std::sin(angle) ); }
00104 Rotation( Real angle, const CoordinateAxis::YCoordinateAxis ) { setRotationFromAngleAboutY( std::cos(angle), std::sin(angle) ); }
00105 Rotation( Real angle, const CoordinateAxis::ZCoordinateAxis ) { setRotationFromAngleAboutZ( std::cos(angle), std::sin(angle) ); }
00107
00108
00109 Rotation& setRotationFromAngleAboutAxis( Real angle, const CoordinateAxis& axis ) { return axis.isXAxis() ? setRotationFromAngleAboutX(angle) : (axis.isYAxis() ? setRotationFromAngleAboutY(angle) : setRotationFromAngleAboutZ(angle) ); }
00110 Rotation& setRotationFromAngleAboutX( Real angle ) { return setRotationFromAngleAboutX( std::cos(angle), std::sin(angle) ); }
00111 Rotation& setRotationFromAngleAboutY( Real angle ) { return setRotationFromAngleAboutY( std::cos(angle), std::sin(angle) ); }
00112 Rotation& setRotationFromAngleAboutZ( Real angle ) { return setRotationFromAngleAboutZ( std::cos(angle), std::sin(angle) ); }
00113 Rotation& setRotationFromAngleAboutX( Real cosAngle, Real sinAngle ) { Mat33& 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; }
00114 Rotation& setRotationFromAngleAboutY( Real cosAngle, Real sinAngle ) { Mat33& 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; }
00115 Rotation& setRotationFromAngleAboutZ( Real cosAngle, Real sinAngle ) { Mat33& 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; }
00117
00119
00120 Rotation( Real angle, const UnitVec3& unitVector ) { setRotationFromAngleAboutUnitVector(angle,unitVector); }
00121 Rotation( Real angle, const Vec3& nonUnitVector ) { setRotationFromAngleAboutNonUnitVector(angle,nonUnitVector); }
00123
00124
00125 Rotation& setRotationFromAngleAboutNonUnitVector( Real angle, const Vec3& nonUnitVector ) { return setRotationFromAngleAboutUnitVector( angle, UnitVec3(nonUnitVector) ); }
00126 SimTK_SimTKCOMMON_EXPORT Rotation& setRotationFromAngleAboutUnitVector( Real angle, const UnitVec3& unitVector );
00128
00130 Rotation( BodyOrSpaceType bodyOrSpace, Real angle1, const CoordinateAxis& axis1, Real angle2, const CoordinateAxis& axis2 ) { setRotationFromTwoAnglesTwoAxes( bodyOrSpace,angle1,axis1,angle2,axis2); }
00132 Rotation( BodyOrSpaceType bodyOrSpace, Real angle1, const CoordinateAxis& axis1, Real angle2, const CoordinateAxis& axis2, Real angle3, const CoordinateAxis& axis3 ) { setRotationFromThreeAnglesThreeAxes(bodyOrSpace,angle1,axis1,angle2,axis2,angle3,axis3); }
00134 SimTK_SimTKCOMMON_EXPORT Rotation& setRotationFromTwoAnglesTwoAxes( BodyOrSpaceType bodyOrSpace, Real angle1, const CoordinateAxis& axis1, Real angle2, const CoordinateAxis& axis2 );
00136 SimTK_SimTKCOMMON_EXPORT Rotation& setRotationFromThreeAnglesThreeAxes( BodyOrSpaceType bodyOrSpace, Real angle1, const CoordinateAxis& axis1, Real angle2, const CoordinateAxis& axis2, Real angle3, const CoordinateAxis& axis3 );
00137
00141 void setRotationToBodyFixedXY( const Vec2& v) { setRotationFromTwoAnglesTwoAxes( BodyRotationSequence, v[0], XAxis, v[1], YAxis ); }
00146 void setRotationToBodyFixedXYZ( const Vec3& v) { setRotationFromThreeAnglesThreeAxes( BodyRotationSequence, v[0], XAxis, v[1], YAxis, v[2], ZAxis ); }
00147
00149 explicit Rotation( const Quaternion& q ) { setRotationFromQuaternion(q); }
00151 SimTK_SimTKCOMMON_EXPORT Rotation& setRotationFromQuaternion( const Quaternion& q );
00152
00154 Rotation( const Mat33& m, bool ) : Mat33(m) {}
00155
00157 explicit Rotation( const Mat33& m ) { setRotationFromApproximateMat33(m); }
00159 SimTK_SimTKCOMMON_EXPORT Rotation& setRotationFromApproximateMat33( const Mat33& m );
00160
00163
00164 Rotation( const UnitVec3& uvec, const CoordinateAxis axis ) { setRotationFromOneAxis(uvec,axis); }
00165 SimTK_SimTKCOMMON_EXPORT Rotation& setRotationFromOneAxis( const UnitVec3& uvec, const CoordinateAxis axis );
00167
00170
00171 Rotation( const UnitVec3& uveci, const CoordinateAxis& axisi, const Vec3& vecjApprox, const CoordinateAxis& axisjApprox ) { setRotationFromTwoAxes(uveci,axisi,vecjApprox,axisjApprox); }
00172 SimTK_SimTKCOMMON_EXPORT Rotation& setRotationFromTwoAxes( const UnitVec3& uveci, const CoordinateAxis& axisi, const Vec3& vecjApprox, const CoordinateAxis& axisjApprox );
00174
00175
00176
00177
00178
00179
00180
00181
00184 SimTK_SimTKCOMMON_EXPORT Real convertOneAxisRotationToOneAngle( const CoordinateAxis& axis1 ) const;
00187 SimTK_SimTKCOMMON_EXPORT Vec2 convertTwoAxesRotationToTwoAngles( BodyOrSpaceType bodyOrSpace, const CoordinateAxis& axis1, const CoordinateAxis& axis2 ) const;
00190 SimTK_SimTKCOMMON_EXPORT Vec3 convertThreeAxesRotationToThreeAngles( BodyOrSpaceType bodyOrSpace, const CoordinateAxis& axis1, const CoordinateAxis& axis2, const CoordinateAxis& axis3 ) const;
00192 SimTK_SimTKCOMMON_EXPORT Quaternion convertRotationToQuaternion() const;
00194 Vec4 convertRotationToAngleAxis() const { return convertRotationToQuaternion().convertQuaternionToAngleAxis(); }
00195
00197 Vec2 convertRotationToBodyFixedXY() const { return convertTwoAxesRotationToTwoAngles( BodyRotationSequence, XAxis, YAxis ); }
00199 Vec3 convertRotationToBodyFixedXYZ() const { return convertThreeAxesRotationToThreeAngles( BodyRotationSequence, XAxis, YAxis, ZAxis ); }
00200
00202
00203 SimTK_SimTKCOMMON_EXPORT bool isSameRotationToWithinAngle( const Rotation& R, Real okPointingAngleErrorRads ) const;
00204 bool isSameRotationToWithinAngleOfMachinePrecision( const Rotation& R) const { return isSameRotationToWithinAngle( R, SignificantReal ); }
00206 Real getMaxAbsDifferenceInRotationElements( const Rotation& R ) const { const Mat33& A = asMat33(); const Mat33& B = R.asMat33(); Real maxDiff = 0.0; for( int i=0; i<=2; i++ ) for( int j=0; j<=2; j++ ) { Real absDiff = std::fabs(A[i][j] - B[i][j]); if( absDiff > maxDiff ) maxDiff = absDiff; } return maxDiff; }
00207 bool areAllRotationElementsSameToEpsilon( const Rotation& R, Real epsilon ) const { return getMaxAbsDifferenceInRotationElements(R) <= epsilon ; }
00208 bool areAllRotationElementsSameToMachinePrecision( const Rotation& R ) const { return areAllRotationElementsSameToEpsilon( R, SignificantReal ); }
00209
00211 inline Rotation( const InverseRotation& );
00213 inline Rotation& operator=( const InverseRotation& );
00214
00216 const InverseRotation& invert() const { return *reinterpret_cast<const InverseRotation*>(this); }
00218 InverseRotation& updInvert() { return *reinterpret_cast<InverseRotation*>(this); }
00219
00220
00221 const InverseRotation& transpose() const { return invert(); }
00222 const InverseRotation& operator~() const { return invert(); }
00223 InverseRotation& updTranspose() { return updInvert(); }
00224 InverseRotation& operator~() { return updInvert(); }
00225
00226
00227 inline Rotation& operator*=( const Rotation& R );
00228 inline Rotation& operator/=( const Rotation& R );
00229 inline Rotation& operator*=( const InverseRotation& );
00230 inline Rotation& operator/=( const InverseRotation& );
00231
00234
00235 const Mat33& asMat33() const { return *static_cast<const Mat33*>(this); }
00236 Mat33 toMat33() const { return asMat33(); }
00238
00239
00240 typedef UnitVec<Mat33::RowSpacing> ColType;
00241 typedef UnitRow<Mat33::ColSpacing> RowType;
00242 const RowType& row( int i ) const { return reinterpret_cast<const RowType&>(asMat33()[i]); }
00243 const ColType& col( int j ) const { return reinterpret_cast<const ColType&>(asMat33()(j)); }
00244 const ColType& x() const { return col(0); }
00245 const ColType& y() const { return col(1); }
00246 const ColType& z() const { return col(2); }
00247 const RowType& operator[]( int i ) const { return row(i); }
00248 const ColType& operator()( int j ) const { return col(j); }
00249
00251
00252 Rotation& setRotationFromMat33TrustMe( const Mat33& m ) { Mat33& R = *this; R[0][0]=m[0][0]; R[0][1]=m[0][1]; R[0][2]=m[0][2]; R[1][0]=m[1][0]; R[1][1]=m[1][1]; R[1][2]=m[1][2]; R[2][0]=m[2][0]; R[2][1]=m[2][1]; R[2][2]=m[2][2]; return *this; }
00253 Rotation& setRotationColFromUnitVecTrustMe( int coli, const UnitVec3& uveci ) { Mat33& R = *this; R[0][coli]=uveci[0]; R[1][coli]=uveci[1]; R[2][coli]=uveci[2]; return *this; }
00254 Rotation& setRotationFromUnitVecsTrustMe( const UnitVec3& colA, const UnitVec3& colB, const UnitVec3& colC ) { setRotationColFromUnitVecTrustMe(0,colA); setRotationColFromUnitVecTrustMe(1,colB); return setRotationColFromUnitVecTrustMe(2,colC); }
00256
00257
00258
00259
00260 private:
00261
00262 static Rotation zero() { return Rotation(); }
00263 static Rotation NaN() { Rotation r; r.setRotationToNaN(); return r; }
00264
00266 Rotation& setToZero() { return setRotationToIdentityMatrix(); }
00267 Rotation& setToIdentityMatrix() { return setRotationToIdentityMatrix(); }
00268 Rotation& setToNaN() { return setRotationToNaN(); }
00269 static Rotation trustMe( const Mat33& m ) { return Rotation(m,true); }
00270
00271
00272 static Rotation aboutX( const Real& angleInRad ) { return Rotation( angleInRad, XAxis ); }
00273 static Rotation aboutY( const Real& angleInRad ) { return Rotation( angleInRad, YAxis ); }
00274 static Rotation aboutZ( const Real& angleInRad ) { return Rotation( angleInRad, ZAxis ); }
00275 static Rotation aboutAxis( const Real& angleInRad, const UnitVec3& axis ) { return Rotation(angleInRad,axis); }
00276 static Rotation aboutAxis( const Real& angleInRad, const Vec3& axis ) { return Rotation(angleInRad,axis); }
00277 void setToRotationAboutZ( const Real& q ) { setRotationFromAngleAboutZ( q ); }
00278
00279
00280 static Rotation aboutXThenOldY(const Real& xInRad, const Real& yInRad) { return Rotation( SpaceRotationSequence, xInRad, XAxis, yInRad, YAxis ); }
00281 static Rotation aboutYThenOldX(const Real& yInRad, const Real& xInRad) { return Rotation( SpaceRotationSequence, yInRad, YAxis, xInRad, XAxis ); }
00282 static Rotation aboutXThenOldZ(const Real& xInRad, const Real& zInRad) { return Rotation( SpaceRotationSequence, xInRad, XAxis, zInRad, ZAxis ); }
00283 static Rotation aboutZThenOldX(const Real& zInRad, const Real& xInRad) { return Rotation( SpaceRotationSequence, zInRad, ZAxis, xInRad, XAxis ); }
00284 static Rotation aboutYThenOldZ(const Real& yInRad, const Real& zInRad) { return Rotation( SpaceRotationSequence, yInRad, YAxis, zInRad, ZAxis ); }
00285 static Rotation aboutZThenOldY(const Real& zInRad, const Real& yInRad) { return Rotation( SpaceRotationSequence, zInRad, ZAxis, yInRad, YAxis ); }
00286
00287
00288 static Rotation aboutXThenNewY(const Real& xInRad, const Real& yInRad) { return Rotation( BodyRotationSequence, xInRad, XAxis, yInRad, YAxis ); }
00289 static Rotation aboutYThenNewX(const Real& yInRad, const Real& xInRad) { return aboutXThenOldY(xInRad, yInRad); }
00290 static Rotation aboutXThenNewZ(const Real& xInRad, const Real& zInRad) { return aboutZThenOldX(zInRad, xInRad); }
00291 static Rotation aboutZThenNewX(const Real& zInRad, const Real& xInRad) { return aboutXThenOldZ(xInRad, zInRad); }
00292 static Rotation aboutYThenNewZ(const Real& yInRad, const Real& zInRad) { return aboutZThenOldY(zInRad, yInRad); }
00293 static Rotation aboutZThenNewY(const Real& zInRad, const Real& yInRad) { return aboutYThenOldZ(yInRad, zInRad); }
00294
00297 explicit Rotation( const UnitVec3& uvecZ ) { setRotationFromOneAxis(uvecZ,ZAxis); }
00298
00300
00301
00302 Rotation( const Vec3& x, const Vec3& yish ) { setRotationFromTwoAxes( UnitVec3(x), XAxis, yish, YAxis ); }
00303
00305 void setToQuaternion( const Quaternion& q ) { setRotationFromQuaternion(q); }
00306
00311
00312 void setToBodyFixed321( const Vec3& v) { setRotationFromThreeAnglesThreeAxes( BodyRotationSequence, v[0], ZAxis, v[1], YAxis, v[2], XAxis ); }
00313 void setToBodyFixed123( const Vec3& v) { setRotationToBodyFixedXYZ(v); }
00314
00317 Vec4 convertToAngleAxis() const { return convertRotationToAngleAxis(); }
00318
00320 Quaternion convertToQuaternion() const { return convertRotationToQuaternion(); }
00321
00324 void setToSpaceFixed12( const Vec2& q ) { setRotationFromTwoAnglesTwoAxes( SpaceRotationSequence, q[0], XAxis, q[1], YAxis ); }
00325
00329 Vec3 convertToBodyFixed123() const { return convertRotationToBodyFixedXYZ(); }
00330 Vec2 convertToBodyFixed12() const { return convertRotationToBodyFixedXY(); }
00331 Vec2 convertToSpaceFixed12() const { return convertTwoAxesRotationToTwoAngles( SpaceRotationSequence, XAxis, YAxis ); }
00332
00333
00334 public:
00335
00341 static Vec3 convertAngVelToBodyFixed321Dot(const Vec3& q, const Vec3& w_PB_B) {
00342 const Real s1 = std::sin(q[1]), c1 = std::cos(q[1]);
00343 const Real s2 = std::sin(q[2]), c2 = std::cos(q[2]);
00344 const Real ooc1 = Real(1)/c1;
00345 const Real s2oc1 = s2*ooc1, c2oc1 = c2*ooc1;
00346
00347 const Mat33 E( 0, s2oc1 , c2oc1 ,
00348 0, c2 , -s2 ,
00349 1, s1*s2oc1 , s1*c2oc1 );
00350 return E * w_PB_B;
00351 }
00352
00355 static Vec3 convertBodyFixed321DotToAngVel(const Vec3& q, const Vec3& qd) {
00356 const Real s1 = std::sin(q[1]), c1 = std::cos(q[1]);
00357 const Real s2 = std::sin(q[2]), c2 = std::cos(q[2]);
00358 const Real ooc1 = 1/c1;
00359 const Real s2oc1 = s2*ooc1, c2oc1 = c2*ooc1;
00360
00361 const Mat33 Einv( -s1 , 0 , 1 ,
00362 c1*s2 , c2 , 0 ,
00363 c1*c2 , -s2 , 0 );
00364 return Einv*qd;
00365 }
00366
00367
00368
00369 static Vec3 convertAngVelDotToBodyFixed321DotDot
00370 (const Vec3& q, const Vec3& w_PB_B, const Vec3& wdot)
00371 {
00372 const Real s1 = std::sin(q[1]), c1 = std::cos(q[1]);
00373 const Real s2 = std::sin(q[2]), c2 = std::cos(q[2]);
00374 const Real ooc1 = 1/c1;
00375 const Real s2oc1 = s2*ooc1, c2oc1 = c2*ooc1;
00376
00377 const Mat33 E( 0 , s2oc1 , c2oc1 ,
00378 0 , c2 , -s2 ,
00379 1 , s1*s2oc1 , s1*c2oc1 );
00380 const Vec3 qdot = E * w_PB_B;
00381
00382 const Real t = qdot[1]*qdot[2]*s1*ooc1;
00383 const Real a = t*c2oc1;
00384 const Real b = -t*s2oc1;
00385
00386 const Mat33 Edot( 0 , a , b ,
00387 0 , -qdot[2]*s2 , -qdot[2]*c2 ,
00388 0 , s1*a + qdot[1]*s2 , s1*b + qdot[1]*c2 );
00389
00390 return E*wdot + Edot*w_PB_B;
00391 }
00392
00398 static Mat33 calcQBlockForBodyXYZInBodyFrame(const Vec3& q) {
00399 const Real s1 = std::sin(q[1]), c1 = std::cos(q[1]);
00400 const Real s2 = std::sin(q[2]), c2 = std::cos(q[2]);
00401 const Real ooc1 = 1/c1;
00402 const Real s2oc1 = s2*ooc1, c2oc1 = c2*ooc1;
00403
00404 return Mat33( c2oc1 , -s2oc1 , 0,
00405 s2 , c2 , 0,
00406 -s1*c2oc1 , s1*s2oc1, 1 );
00407 }
00408
00412 static Mat33 calcQInvBlockForBodyXYZInBodyFrame(const Vec3& q) {
00413 const Real s1 = std::sin(q[1]), c1 = std::cos(q[1]);
00414 const Real s2 = std::sin(q[2]), c2 = std::cos(q[2]);
00415
00416 return Mat33( c1*c2 , s2 , 0 ,
00417 -c1*s2 , c2 , 0 ,
00418 s1 , 0 , 1 );
00419 }
00420
00426 static Vec3 convertAngVelToBodyFixed123Dot(const Vec3& q, const Vec3& w_PB_B) {
00427 return calcQBlockForBodyXYZInBodyFrame(q)*w_PB_B;
00428 }
00429
00432 static Vec3 convertBodyFixed123DotToAngVel(const Vec3& q, const Vec3& qd) {
00433 return calcQInvBlockForBodyXYZInBodyFrame(q)*qd;
00434 }
00435
00436
00437
00438
00439 static Vec3 convertAngVelDotToBodyFixed123DotDot
00440 (const Vec3& q, const Vec3& w_PB_B, const Vec3& wdot)
00441 {
00442 const Real s1 = std::sin(q[1]), c1 = std::cos(q[1]);
00443 const Real s2 = std::sin(q[2]), c2 = std::cos(q[2]);
00444 const Real ooc1 = 1/c1;
00445 const Real s2oc1 = s2*ooc1, c2oc1 = c2*ooc1;
00446
00447 const Mat33 Q( c2oc1 , -s2oc1 , 0,
00448 s2 , c2 , 0,
00449 -s1*c2oc1 , s1*s2oc1, 1 );
00450 const Vec3 qdot = Q * w_PB_B;
00451
00452 const Real t = qdot[1]*qdot[2]*s1*ooc1;
00453 const Real a = t*c2oc1;
00454 const Real b = -t*s2oc1;
00455
00456 const Mat33 QDot( b , -a , 0,
00457 qdot[2]*c2 , -qdot[2]*s2 , 0,
00458 -s1*b - qdot[1]*c2 , s1*a + qdot[1]*s2 , 0 );
00459
00460 return Q*wdot + QDot*w_PB_B;
00461 }
00462
00467 static Mat43 calcUnnormalizedQBlockForQuaternion(const Vec4& q) {
00468 const Vec4 e = q/2;
00469 return Mat43(-e[1],-e[2],-e[3],
00470 e[0], e[3],-e[2],
00471 -e[3], e[0], e[1],
00472 e[2],-e[1], e[0]);
00473 }
00474
00482 static Mat34 calcUnnormalizedQInvBlockForQuaternion(const Vec4& q) {
00483 const Vec4 e = 2*q;
00484 return Mat34(-e[1], e[0],-e[3], e[2],
00485 -e[2], e[3], e[0],-e[1],
00486 -e[3],-e[2], e[1], e[0]);
00487 }
00488
00489
00493 static Vec4 convertAngVelToQuaternionDot(const Vec4& q, const Vec3& w_PB_P) {
00494 return calcUnnormalizedQBlockForQuaternion(q)*w_PB_P;
00495 }
00496
00499 static Vec3 convertQuaternionDotToAngVel(const Vec4& q, const Vec4& qd) {
00500 return calcUnnormalizedQInvBlockForQuaternion(q)*qd;
00501 }
00502
00504 static Vec4 convertAngVelDotToQuaternionDotDot
00505 (const Vec4& q, const Vec3& w_PB_P, const Vec3& wdot)
00506 {
00507 const Mat43 Q = calcUnnormalizedQBlockForQuaternion(q);
00508 const Vec4 edot = (Q*w_PB_P)/2;
00509 const Mat43 QDot(-edot[1],-edot[2],-edot[3],
00510 edot[0], edot[3],-edot[2],
00511 -edot[3], edot[0], edot[1],
00512 edot[2],-edot[1], edot[0]);
00513
00514 return Q*wdot + QDot*w_PB_P;
00515 }
00516
00517
00518 private:
00519
00520
00521
00522 Rotation( const Real& xx, const Real& xy, const Real& xz,
00523 const Real& yx, const Real& yy, const Real& yz,
00524 const Real& zx, const Real& zy, const Real& zz )
00525 : Mat33( xx,xy,xz, yx,yy,yz, zx,zy,zz ) {}
00526
00527
00528 SimTK_SimTKCOMMON_EXPORT Rotation& setTwoAngleTwoAxesBodyFixedForwardCyclicalRotation( Real cosAngle1, Real sinAngle1, const CoordinateAxis& axis1, Real cosAngle2, Real sinAngle2, const CoordinateAxis& axis2 );
00529 SimTK_SimTKCOMMON_EXPORT Rotation& setThreeAngleTwoAxesBodyFixedForwardCyclicalRotation( Real cosAngle1, Real sinAngle1, const CoordinateAxis& axis1, Real cosAngle2, Real sinAngle2, const CoordinateAxis& axis2, Real cosAngle3, Real sinAngle3 );
00530 SimTK_SimTKCOMMON_EXPORT Rotation& setThreeAngleThreeAxesBodyFixedForwardCyclicalRotation( Real cosAngle1, Real sinAngle1, const CoordinateAxis& axis1, Real cosAngle2, Real sinAngle2, const CoordinateAxis& axis2, Real cosAngle3, Real sinAngle3, const CoordinateAxis& axis3 );
00531
00532
00533 SimTK_SimTKCOMMON_EXPORT Vec2 convertTwoAxesBodyFixedRotationToTwoAngles( const CoordinateAxis& axis1, const CoordinateAxis& axis2 ) const;
00534 SimTK_SimTKCOMMON_EXPORT Vec3 convertTwoAxesBodyFixedRotationToThreeAngles( const CoordinateAxis& axis1, const CoordinateAxis& axis2 ) const;
00535 SimTK_SimTKCOMMON_EXPORT Vec3 convertThreeAxesBodyFixedRotationToThreeAngles( const CoordinateAxis& axis1, const CoordinateAxis& axis2, const CoordinateAxis& axis3 ) const;
00536
00537 };
00538
00539
00544 class InverseRotation : public Mat33::TransposeType {
00545 public:
00546
00547 typedef Mat33::TransposeType BaseMat;
00548
00549
00550
00551 InverseRotation() : BaseMat(1) {}
00552
00553
00554 InverseRotation( const InverseRotation& R ) : BaseMat(R) {}
00555 InverseRotation& operator=( const InverseRotation& R ) { BaseMat::operator=( R.asMat33() ); return *this; }
00556
00557
00558 const Rotation& invert() const { return *reinterpret_cast<const Rotation*>(this); }
00559 Rotation& updInvert() { return *reinterpret_cast<Rotation*>(this); }
00560
00561
00562 const Rotation& transpose() const { return invert(); }
00563 const Rotation& operator~() const { return invert(); }
00564 Rotation& updTranspose() { return updInvert(); }
00565 Rotation& operator~() { return updInvert(); }
00566
00567
00568 typedef UnitVec<BaseMat::RowSpacing> ColType;
00569 typedef UnitRow<BaseMat::ColSpacing> RowType;
00570 const RowType& row( int i ) const { return reinterpret_cast<const RowType&>(asMat33()[i]); }
00571 const ColType& col( int j ) const { return reinterpret_cast<const ColType&>(asMat33()(j)); }
00572 const ColType& x() const { return col(0); }
00573 const ColType& y() const { return col(1); }
00574 const ColType& z() const { return col(2); }
00575 const RowType& operator[]( int i ) const { return row(i); }
00576 const ColType& operator()( int j ) const { return col(j); }
00577
00580 const BaseMat& asMat33() const { return *static_cast<const BaseMat*>(this); }
00581 BaseMat toMat33() const { return asMat33(); }
00582
00583 };
00584
00585
00586 SimTK_SimTKCOMMON_EXPORT std::ostream& operator<<( std::ostream& o, const Rotation& m );
00587
00588 template <int S> inline UnitVec<1> operator*( const Rotation& R, const UnitVec<S>& v ) { return UnitVec<1>(R.asMat33()* v.asVec3(), true); }
00589 template <int S> inline UnitRow<1> operator*( const UnitRow<S>& r, const Rotation& R ) { return UnitRow<1>(r.asRow3() * R.asMat33(), true); }
00590 template <int S> inline UnitVec<1> operator*( const InverseRotation& R, const UnitVec<S>& v ) { return UnitVec<1>(R.asMat33()* v.asVec3(), true); }
00591 template <int S> inline UnitRow<1> operator*( const UnitRow<S>& r, const InverseRotation& R ) { return UnitRow<1>(r.asRow3() * R.asMat33(), true); }
00592
00593 inline Rotation::Rotation( const InverseRotation& R) : Mat33( R.asMat33() ) {}
00594
00595 inline Rotation& Rotation::operator=( const InverseRotation& R ) { static_cast<Mat33&>(*this) = R.asMat33(); return *this; }
00596 inline Rotation& Rotation::operator*=( const Rotation& R ) { static_cast<Mat33&>(*this) *= R.asMat33(); return *this; }
00597 inline Rotation& Rotation::operator/=( const Rotation& R ) { static_cast<Mat33&>(*this) *= (~R).asMat33(); return *this; }
00598 inline Rotation& Rotation::operator*=( const InverseRotation& R ) { static_cast<Mat33&>(*this) *= R.asMat33(); return *this; }
00599 inline Rotation& Rotation::operator/=( const InverseRotation& R ) { static_cast<Mat33&>(*this) *= (~R).asMat33(); return *this; }
00600
00601 inline Rotation operator*( const Rotation& R1, const Rotation& R2 ) { return Rotation(R1) *= R2; }
00602 inline Rotation operator*( const Rotation& R1, const InverseRotation& R2 ) { return Rotation(R1) *= R2; }
00603 inline Rotation operator*( const InverseRotation& R1, const Rotation& R2 ) { return Rotation(R1) *= R2; }
00604 inline Rotation operator*( const InverseRotation& R1, const InverseRotation& R2 ) { return Rotation(R1) *= R2; }
00605
00606 inline Rotation operator/( const Rotation& R1, const Rotation& R2 ) {return Rotation(R1) /= R2;}
00607 inline Rotation operator/( const Rotation& R1, const InverseRotation& R2 ) {return Rotation(R1) /= R2;}
00608 inline Rotation operator/( const InverseRotation& R1, const Rotation& R2 ) {return Rotation(R1) /= R2;}
00609 inline Rotation operator/( const InverseRotation& R1, const InverseRotation& R2 ) {return Rotation(R1) /= R2;}
00610
00611
00612
00613 }
00614
00615
00616 #endif // SIMTK_ROTATION_H_
00617
00618
00619