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<double> result(3);
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   {
00080     vnl_vector<double> tmp(2);
00081     result.put(0,result.get(0));
00082     result.put(1,result.get(1));
00083     return tmp;
00084   }
00085   else
00086     return result;
00087 }
00088 
00089 //---------------------------------------------------------------------------
00090 // Image of `v' by the inverse of `this'
00091 // REQUIRE: is_valid()
00092 // REQUIRE: is_invertible(time)
00093 // REQUIRE: (is_2d()&&v.size()==2)||(is_3d()&&v.size()==3)
00094 //---------------------------------------------------------------------------
00095 vnl_vector<double> vcsl_rotation::inverse(const vnl_vector<double> &v,
00096                                           double time) const
00097 {
00098   // require
00099   assert(is_valid());
00100   assert(is_invertible(time));
00101   assert((is_2d()&&v.size()==2)||(is_3d()&&v.size()==3));
00102 
00103   vnl_vector<double> result(3);
00104 
00105   if (mode_2d_)
00106   {
00107     result.put(0,v.get(0));
00108     result.put(1,v.get(1));
00109     result.put(2,0);
00110   }
00111   else
00112     result=v;
00113   vnl_quaternion<double> q=quaternion(time);
00114   result = q.conjugate().rotate(result);
00115   if (mode_2d_)
00116   {
00117     vnl_vector<double> tmp(2);
00118     result.put(0,result.get(0));
00119     result.put(1,result.get(1));
00120     return tmp;
00121   }
00122   else
00123     return result;
00124 }
00125 
00126 //---------------------------------------------------------------------------
00127 // Compute the value of the quaternion at time `time'
00128 //---------------------------------------------------------------------------
00129 vnl_quaternion<double> vcsl_rotation::quaternion(double time) const
00130 {
00131   vnl_quaternion<double> result;
00132 
00133   if (this->duration()==0) // static
00134   {
00135     if (mode_2d_)
00136     {
00137       vnl_vector<double> axis_2d(3);
00138       axis_2d.put(0,0);
00139       axis_2d.put(1,0);
00140       axis_2d.put(2,1);
00141       result=vnl_quaternion<double>(axis_2d,angle_[0]);
00142     }
00143     else
00144       result=vnl_quaternion<double>(axis_[0],angle_[0]);
00145   }
00146   else
00147   {
00148     int i=matching_interval(time);
00149     vnl_vector<double> axis_2d(3);
00150 
00151     if (mode_2d_)
00152     {
00153       axis_2d.put(0,0);
00154       axis_2d.put(1,0);
00155       axis_2d.put(2,1);
00156     }
00157 
00158     switch (interpolator_[i])
00159     {
00160      case vcsl_linear:
00161      {
00162       vnl_quaternion<double> q0, q1;
00163       if (mode_2d_)
00164       {
00165         q0=vnl_quaternion<double>(axis_2d,angle_[i]);
00166         q1=vnl_quaternion<double>(axis_2d,angle_[i+1]);
00167       }
00168       else
00169       {
00170         q0=vnl_quaternion<double>(axis_[i],angle_[i]);
00171         q1=vnl_quaternion<double>(axis_[i+1],angle_[i+1]);
00172       }
00173       result=lqi(q0,q1,i,time);
00174       break;
00175      }
00176      case vcsl_cubic:
00177       assert(!"vcsl_cubic net yet implemented");
00178       break;
00179      case vcsl_spline:
00180       assert(!"vcsl_spline net yet implemented");
00181       break;
00182      default:
00183       assert(!"This is impossible");
00184       break;
00185     }
00186   }
00187   return result;
00188 }