core/vcsl/vcsl_rotation.cxx
Go to the documentation of this file.
00001 // This is core/vcsl/vcsl_rotation.cxx
00002 #include "vcsl_rotation.h"
00003 #include <vcl_cassert.h>
00004 
00005 //---------------------------------------------------------------------------
00006 // Are `new_axis' a list of unit axes ?
00007 //---------------------------------------------------------------------------
00008 bool vcsl_rotation::are_unit_axes(list_of_vectors const& new_axis) const
00009 {
00010   const double epsilon=0.001;
00011 
00012   list_of_vectors::const_iterator i;
00013 
00014   bool result=true;
00015   for (i=new_axis.begin();result&&i!=new_axis.end();++i)
00016     result=(((*i).two_norm())-1)<epsilon;
00017 
00018   return result;
00019 }
00020 
00021 //---------------------------------------------------------------------------
00022 // Set the parameters of a static 2D rotation
00023 //---------------------------------------------------------------------------
00024 void vcsl_rotation::set_static_2d(double new_angle)
00025 {
00026   mode_2d_=true;
00027   angle_.clear(); angle_.push_back(new_angle);
00028   vcsl_spatial_transformation::set_static();
00029 }
00030 
00031 //---------------------------------------------------------------------------
00032 // Set the parameters of a static 3D rotation
00033 //---------------------------------------------------------------------------
00034 void vcsl_rotation::set_static(double new_angle,
00035                                vnl_vector<double> const& new_axis)
00036 {
00037   mode_2d_=false;
00038   angle_.clear(); angle_.push_back(new_angle);
00039   axis_.clear(); axis_.push_back(new_axis);
00040   vcsl_spatial_transformation::set_static();
00041 }
00042 
00043 //---------------------------------------------------------------------------
00044 // Set the direction vector variation along the time
00045 // REQUIRE: are_unit_axes(new_axis)
00046 //---------------------------------------------------------------------------
00047 void vcsl_rotation::set_axis(list_of_vectors const& new_axis)
00048 {
00049   // require
00050   assert(are_unit_axes(new_axis));
00051 
00052   axis_=new_axis;
00053 }
00054 
00055 //---------------------------------------------------------------------------
00056 // Image of `v' by `this'
00057 // REQUIRE: is_valid()
00058 // REQUIRE: (is_2d()&&v.size()==2)||(is_3d()&&v.size()==3)
00059 //---------------------------------------------------------------------------
00060 vnl_vector<double> vcsl_rotation::execute(const vnl_vector<double> &v,
00061                                           double time) const
00062 {
00063   // require
00064   assert(is_valid());
00065   assert((is_2d()&&v.size()==2)||(is_3d()&&v.size()==3));
00066 
00067   vnl_quaternion<double> q=quaternion(time);
00068   vnl_vector_fixed<double,3> result;
00069   if (mode_2d_)
00070   {
00071     result.put(0,v.get(0));
00072     result.put(1,v.get(1));
00073     result.put(2,0);
00074   }
00075   else
00076     result=v;
00077   result = q.rotate(result);
00078   if (mode_2d_)
00079     return vnl_vector<double>(result.data_block(), 2);
00080   else
00081     return vnl_vector<double>(result.data_block(), 3);
00082 }
00083 
00084 //---------------------------------------------------------------------------
00085 // Image of `v' by the inverse of `this'
00086 // REQUIRE: is_valid()
00087 // REQUIRE: is_invertible(time)
00088 // REQUIRE: (is_2d()&&v.size()==2)||(is_3d()&&v.size()==3)
00089 //---------------------------------------------------------------------------
00090 vnl_vector<double> vcsl_rotation::inverse(const vnl_vector<double> &v,
00091                                           double time) const
00092 {
00093   // require
00094   assert(is_valid());
00095   assert(is_invertible(time));
00096   assert((is_2d()&&v.size()==2)||(is_3d()&&v.size()==3));
00097 
00098   vnl_vector_fixed<double,3> result;
00099 
00100   if (mode_2d_)
00101   {
00102     result.put(0,v.get(0));
00103     result.put(1,v.get(1));
00104     result.put(2,0);
00105   }
00106   else
00107     result=v;
00108   vnl_quaternion<double> q=quaternion(time);
00109   result = q.conjugate().rotate(result);
00110   if (mode_2d_)
00111     return vnl_vector<double>(result.data_block(), 2);
00112   else
00113     return vnl_vector<double>(result.data_block(), 3);
00114 }
00115 
00116 //---------------------------------------------------------------------------
00117 // Compute the value of the quaternion at time `time'
00118 //---------------------------------------------------------------------------
00119 vnl_quaternion<double> vcsl_rotation::quaternion(double time) const
00120 {
00121   vnl_quaternion<double> result;
00122 
00123   if (this->duration()==0) // static
00124   {
00125     if (mode_2d_)
00126     {
00127       vnl_vector<double> axis_2d(3);
00128       axis_2d.put(0,0);
00129       axis_2d.put(1,0);
00130       axis_2d.put(2,1);
00131       result=vnl_quaternion<double>(axis_2d,angle_[0]);
00132     }
00133     else
00134       result=vnl_quaternion<double>(axis_[0],angle_[0]);
00135   }
00136   else
00137   {
00138     int i=matching_interval(time);
00139     vnl_vector<double> axis_2d(3);
00140 
00141     if (mode_2d_)
00142     {
00143       axis_2d.put(0,0);
00144       axis_2d.put(1,0);
00145       axis_2d.put(2,1);
00146     }
00147 
00148     switch (interpolator_[i])
00149     {
00150      case vcsl_linear:
00151      {
00152       vnl_quaternion<double> q0, q1;
00153       if (mode_2d_)
00154       {
00155         q0=vnl_quaternion<double>(axis_2d,angle_[i]);
00156         q1=vnl_quaternion<double>(axis_2d,angle_[i+1]);
00157       }
00158       else
00159       {
00160         q0=vnl_quaternion<double>(axis_[i],angle_[i]);
00161         q1=vnl_quaternion<double>(axis_[i+1],angle_[i+1]);
00162       }
00163       result=lqi(q0,q1,i,time);
00164       break;
00165      }
00166      case vcsl_cubic:
00167       assert(!"vcsl_cubic net yet implemented");
00168       break;
00169      case vcsl_spline:
00170       assert(!"vcsl_spline net yet implemented");
00171       break;
00172      default:
00173       assert(!"This is impossible");
00174       break;
00175     }
00176   }
00177   return result;
00178 }