Rotation.cpp

Go to the documentation of this file.
00001 
00011 #include <standard.hpp>
00012 #include <GL/gl.h>
00013 #include "Rotation.hpp"
00014 
00015 Rotation::Rotation() : scaledAxis(3)
00016 {
00017         
00018 }
00019 
00020 
00021 void Rotation::setScaledAxis(const GslVector &axis)
00022 {
00023         if (axis.getNumRows() != 3)
00024                 throw Error("Rotation::setScaledAxis(): axis param must have 3 elements.");
00025 
00026         scaledAxis = axis;
00027 }
00028 
00029 void Rotation::setAxisAndAngleRadians(const GslVector &axis, double angle)
00030 {
00031         if (axis.getNumRows() != 3)
00032                 throw Error("Rotation::setAxisAndAngleRadians(): axis param must have 3 elements.");
00033         scaledAxis = axis;
00034         scaledAxis *= angle;
00035 }
00036 
00037 void Rotation::getAxisAndAngleRadians(GslVector &axis, double &angle) const
00038 {
00039         angle = scaledAxis.getLength();
00040 
00041         axis = scaledAxis;
00042         axis /= angle; // normalize the axis to return
00043 }
00044 
00045 void axisAngleToRotation (const GslVector &axis, double angle, GslMatrix &r)
00046 {
00047         r.resize(3,3);
00048         r.setToIdentity();
00049 
00050         GslMatrix skew(3,3);
00051         skew.setToZero();
00052         skew(0,0) =  0;
00053         skew(0,1) = -axis(2);
00054         skew(0,2) = +axis(1);
00055 
00056         skew(1,0) = +axis(2);
00057         skew(1,1) =  0;
00058         skew(1,2) = -axis(0);
00059 
00060         skew(2,0) = -axis(1);
00061         skew(2,1) = +axis(0);
00062         skew(2,2) =  0;
00063 
00064         r += skew * sin(angle);
00065         r += (skew * skew) * (1-cos(angle));
00066 }
00067 
00068 
00069 void Rotation::getMatrix(GslMatrix & rotationMatrix)
00070 {
00071         GslVector axis;
00072         double angle;
00073 
00074         getAxisAndAngleRadians(axis, angle);
00075         axisAngleToRotation(axis, angle, rotationMatrix);
00076 }
00077 
00078 void orthogonalizeMatrix (GslMatrix &m)
00079 {
00080         assert (m.getNumRows() == 3 && m.getNumCols() == 3);
00081 
00082         GslMatrix u(3,3), v(3,3);
00083         GslVector s(3);
00084 
00085         m.SingularValueDecomposition(u,s,v);
00086         m = u * v.getTranspose();
00087 }
00088 
00089 void rotationMatrixToQuaternion (const GslMatrix &m, double &x, double &y, double &z, double &w)
00090 {
00091         double trace = m.getTrace();
00092         if (trace > 0)
00093         {
00094                 w = sqrt(trace + 1.) / 2.;
00095                 double divisor = 1. / (4. * w);
00096                 x = (m(2,1)-m(1,2)) * divisor;
00097                 y = (m(0,2)-m(2,0)) * divisor;
00098                 z = (m(1,0)-m(0,1)) * divisor;
00099         }
00100         else if (m(0,0) > m(1,1) && m(0,0) > m(2,2))
00101         {
00102                 x = sqrt(m(0,0) - m(1,1) - m(2,2) + 1.) * .5;
00103                 double divisor = 1. / (4. * x);
00104                 y = (m(0,1) + m(1,0)) * divisor;
00105                 z = (m(0,2) + m(2,0)) * divisor;
00106                 w = (m(2,1) - m(1,2)) * divisor;
00107         }
00108         else if (m(1,1) > m(2,2))
00109         {
00110                 y = sqrt(m(1,1) - m(0,0) - m(2,2) + 1.) * .5;
00111                 double divisor = 1. / (4. * y);
00112                 x = (m(0,1) + m(1,0)) * divisor;
00113                 w = (m(0,2) - m(2,0)) * divisor;
00114                 z = (m(1,2) + m(2,1)) * divisor;
00115         }
00116         else
00117         {
00118                 z = sqrt(m(2,2) - m(0,0) - m(1,1) + 1.) * .5;
00119                 double divisor = 1. / (4. * z);
00120                 w = (m(1,0) - m(0,1)) * divisor;
00121                 x = (m(0,2) + m(2,0)) * divisor;
00122                 y = (m(1,2) + m(2,1)) * divisor;
00123         }
00124 }
00125 
00126 void quaternionToAxisAngle (double x, double y, double z, double w, GslVector &axis, double &angle)
00127 {
00128         if (fabs(w) < 1)
00129         {
00130                 angle = 2.*acos(w);
00131                 double divisor = 1./sqrt(1.-w*w);
00132                 axis(0) = x*divisor;
00133                 axis(1) = y*divisor;
00134                 axis(2) = z*divisor;
00135         }
00136         else
00137         {
00138                 axis.setToZero();
00139                 axis(0) = 1;
00140                 angle = 0;
00141         }
00142 }
00143 
00144 
00145 void Rotation::setMatrix(GslMatrix rotationMatrix)
00146 {
00147         if (rotationMatrix.getNumRows() != 3 ||
00148                 rotationMatrix.getNumCols() != 3)
00149         {
00150                 throw Error("Rotation::setMatrix(): rotationMatrix param must be 3x3.");
00151         }
00152 /*
00153  * The rotation matrix may not be orthogonal, so let's straighten it out.
00154  */
00155         orthogonalizeMatrix (rotationMatrix);
00156 
00157 /*
00158  * Convert the rotation matrix into an axis whose length denotes the
00159  * angle in radians.
00160  */
00161         double angle;
00162         double x,y,z,w;
00163         rotationMatrixToQuaternion(rotationMatrix, x, y, z, w);
00164         quaternionToAxisAngle(x,y,z,w,scaledAxis,angle);
00165         scaledAxis *= angle;
00166 }

Generated on Mon May 26 11:19:28 2003 for CamChecker by doxygen1.3