AnimaL |
Tutorial |
Documentation |
#include <animal/vec3.h> #include <animal/quaternion.h> // =============================================== // Start first version: use standard ANIMAL types. // Instanciate the types used in the rest of the program // typedef double Real; typedef animal::Vec3 Vec; // typedef animal::Quaternion<double> Quat; // end first version. using std::cout; using std::cerr; using std::cin; using std::endl; using std::ostream; using std::istream; // =============================================== // Start second version: use your own vector type. // You just have to create the asociated Traits type. //class MyVec //{ // //public: // // MyVec() // { a[0]=0; a[1]=0; a[2]=0; } // // MyVec(double x, double y, double z ) // { a[0]=x; a[1]=y; a[2]=z; } // // double operator[](int i) const { return a[i]; } // double& operator[](int i) { return a[i]; } // // MyVec operator-(const MyVec& m) const // { return MyVec(a[0]-m.a[0], a[1]-m.a[1], a[2]-m.a[2]); } // // friend ostream& operator<<(ostream& str, const MyVec& v) // { str<<v.a[0]<<" "<<v.a[1]<<" "<<v.a[2]; return str; } // // friend istream& operator>>(istream& str, MyVec& v) // { str>>v.a[0]>>v.a[1]>>v.a[2]; return str; } // //private: // // double a[3]; //}; // Create Traits corresponding to your vector types. // Redefine all types and methods of the default Traits class. class My_Quat_Traits { public: typedef double Real; //typedef MyVec Vec3; static Real x(const Vec& v) { return v[0]; } static Real y(const Vec& v) { return v[1]; } static Real z(const Vec& v) { return v[2]; } static void normalize(animal::Vec3& v) { Real nrm = sqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] ); Real tmp = 1.0/nrm; v[0]=v[0]*tmp; v[1]=v[1]*tmp; v[2]=v[2]*tmp; } static Real nullAxis() { return 1.0e-5; } }; // Instanciate the types used in the rest of the program typedef double Real; //typedef MyVec Vec; typedef animal::Quaternion < Real, My_Quat_Traits > Quat; // end second version // =============================================== // Main program. int main() { cout<<"\n============================================================\n"; cout<<"Test program for class Quaternion"<<endl; cout<<"Quaternion is a unit quaternion used to represent a rotation"<<endl; cout<<"============================================================\n"<<endl; // // enter data // cout<<"\n==== enter a quaternion q in the form: axis angle\n(example: 1.0 1.0 1.0 1.5708)" // <<endl; // Quat q; // cin>>q; // cout<<"unit quaternion q: "<<q<<endl; // cout<<"\n==== enter a quaternion q1 in the form: axis angle\n(example: 1.0 1.0 1.0 0.5708)" // <<endl; // Quat q1; // cin>>q1; // cout<<"unit quaternion q1: "<<q1<<endl; // cout<<"\n==== enter a vector v\n(example 1.0 0.0 0.0)"<<endl; // Vec v; // cin>>v; // // // axis, angle // cout<<"\n==== get q axis and angle"<<endl; // Real x,y,z; // Real angle; // q.getAxisAngle(x,y,z, angle); // Vec axis(x,y,z); // cout<<"axis: "<<axis<<endl; // cout<<"angle: "<<angle<<endl; // // q.getAxisAngle(axis, angle); // cout<<"axis (second version): "<<axis<<endl; // cout<<"angle (second version): "<<angle<<endl; // // cout<<"\n==== set q axis and angle"<<endl; // q.setAxisAngle(axis, angle); // Vec ax; Real an; // q.getAxisAngle(ax, an); // cout<<"axis: "<<ax<<endl; // cout<<"angle: "<<an<<endl; // cout<<"difference (correct value is 0 0 0 0): "<<axis-ax<<" "<<angle-an<<endl; // // q.setAxisAngle(x,y,z, angle); // q.getAxisAngle(ax, an); // cout<<"axis(second version): "<<ax<<endl; // cout<<"angle(second version): "<<an<<endl; // cout<<"difference (correct value is 0 0 0 0): "<<axis-ax<<" "<<angle-an<<endl; // // // Interpolation // Real r; // cout<<"\n==== enter a Real r: "; // cin >> r; cout<<endl; // cout<<" q * r = "<< q*r <<endl; // cout<<" q * r * (1/r) / q = (correct value is "<<Quat::identity()<<"): "<< q*r*(1/r) / q <<endl; // // // // Norm // Quat qq = q; // qq.normalize(); // cout<<"\n==== check normalization (correct value is 0.0): " // <<qq.norm() - 1.0<<endl; // // // various rotation models // cout<<"\n==== set q with Euler angles: to be tested in the future!..."<<endl; // // // product to another quaternion: q *= q1, q /= q1 // cout<<"\n==== test products *= and divisions /="<<endl; // cout<<"(q *= q1) = "<<(q *= q1)<<endl; // cout<<"(q /= q1) = "<<(q /= q1)<<endl; // qq = q; // cout<<"q /= q (correct value is 1 0 0 0): "<<(qq /= qq)<<endl; // // // product to another quaternion with creation q*q1, q/q1 // cout<<"\n==== test products * and divisions /"<<endl; // cout<<"q = "<<q<<endl; // cout<<"q*q1 = "<<q*q1<<endl; // cout<<"q*q1/q1 = "<<q*q1/q1<<endl; // cout<<"q*q1/q1/q (correct value is 1 0 0 0) = "<<q*q1/q1/q<<endl; // // // product with its inverse // qq = q; // cout<<"\n==== product of q with its inverse (correct value is 1 0 0 0): "<<(qq*qq.inverse())<<endl; // // // product with a vector // cout<<"\n==== product with q and v:"<<endl; // cout<<"q*v = "<<q*v<<endl; // //cout<<"v*q = "<<v*q<<endl; // //cout<<"(v*q)/q - v (correct value is 0 0 0) = "<<(v*q)/q - v<<endl; // cout<<"q/v = "<<q/v<<endl; // //cout<<"v/q = "<<v/q<<endl; // //cout<<"(v/q)*q - v (correct value is 0 0 0) = "<<(v/q)*q - v<<endl; // // // write rotation matrix // cout<<"\n==== write rotation matrix m corresponding to quaternion q"<<endl; // Real mat[3][3]; // animal::writeRotMatrix(q,mat); // Vec u; // int i, j; // // for (i=0; i<3; i++){ // u[i]=0; // for (j=0; j<3; j++) // u[i] += mat[i][j]*v[j]; // } // // cout<<"product q*v = "<<q*v<<endl; // cout<<"product m*v = "<<u<<endl; // // // write OpenGL rotation matrix // cout<<"\n==== write OpenGL rotation matrix m corresponding to quaternion q"<<endl; // Real matrix[4][4]; // animal::writeOpenGLRotMatrix(q,matrix); // u[0] = 0.0; u[1] = 0.0; u[2] = 0.0; // // for (i=0; i<3; i++) // for (j=0; j<3; j++) // u[i] += matrix[i][j]*v[j]; // // cout<<"product q*v = "<<q*v<<endl; // cout<<"product m*v = "<<u<<endl; // // // Compute Euler increment // Vec omega; // Real dt; // cout<<"\n==== Compute Euler increment"<<endl; // cout<<" >>>>>>> enter an angular velocity and a time step: "; // cin>>omega>>dt; // cout<<endl<<" A angular velocity of "<<omega<<" applied during "<<dt<<" results in the following rotation: "<<Quat::eulerIncrement( omega, dt )<<endl; // // Quat q, q1; // cout<<"\n==== enter a quaternion q1 in the form: axis angle\n(example: 1.0 1.0 1.0 0.5708)" // <<endl; // cin>>q; // cout<<"\n==== enter a quaternion q1 in the form: axis angle\n(example: 1.0 1.0 1.0 0.5708)" // <<endl; // cin >> q1; // q=q*q1; // cout << "calcul de q*q1 " << q << endl; // cout<<"\n==== enter a quaternion q1 in the form: axis angle\n(example: 1.0 1.0 1.0 0.5708)" // <<endl; // cin >> q1; // q=q*q1; // cout << "calcul de q*q1 " << q << endl; Quat q; Real x, y, z; cout << "enter the euler angle : z y x " << endl; cin >> z; cin >> y; cin >> x; q.setEulerXYZ(x,y,z); cout << "en faisant \"setEulerXYZ\"" << endl << q << endl; Quat q1, q2; q1.setAxisAngle(0.0,0.0,1.0,z); q2.setAxisAngle(0.0,1.0,0.0,y); q1=q1*q2; q2.setAxisAngle(1.0,0.0,0.0,x); q1=q1*q2; cout << "en faisant les multiplications " << endl << q1 << endl; return 0; }