vcsl_rotation.cxx
Go to the documentation of this file.
1 // This is core/vcsl/vcsl_rotation.cxx
2 #include "vcsl_rotation.h"
3 #include <cassert>
4 #ifdef _MSC_VER
5 # include <vcl_msvc_warnings.h>
6 #endif
7 
8 //---------------------------------------------------------------------------
9 // Are `new_axis' a list of unit axes ?
10 //---------------------------------------------------------------------------
11 bool vcsl_rotation::are_unit_axes(list_of_vectors const& new_axis) const
12 {
13  constexpr double epsilon = 0.001;
14 
15  list_of_vectors::const_iterator i;
16 
17  bool result=true;
18  for (i=new_axis.begin();result&&i!=new_axis.end();++i)
19  result=(((*i).two_norm())-1)<epsilon;
20 
21  return result;
22 }
23 
24 //---------------------------------------------------------------------------
25 // Set the parameters of a static 2D rotation
26 //---------------------------------------------------------------------------
27 void vcsl_rotation::set_static_2d(double new_angle)
28 {
29  mode_2d_=true;
30  angle_.clear(); angle_.push_back(new_angle);
32 }
33 
34 //---------------------------------------------------------------------------
35 // Set the parameters of a static 3D rotation
36 //---------------------------------------------------------------------------
37 void vcsl_rotation::set_static(double new_angle,
38  vnl_vector<double> const& new_axis)
39 {
40  mode_2d_=false;
41  angle_.clear(); angle_.push_back(new_angle);
42  axis_.clear(); axis_.push_back(new_axis);
44 }
45 
46 //---------------------------------------------------------------------------
47 // Set the direction vector variation along the time
48 // REQUIRE: are_unit_axes(new_axis)
49 //---------------------------------------------------------------------------
51 {
52  // require
53  assert(are_unit_axes(new_axis));
54 
55  axis_=new_axis;
56 }
57 
58 //---------------------------------------------------------------------------
59 // Image of `v' by `this'
60 // REQUIRE: is_valid()
61 // REQUIRE: (is_2d()&&v.size()==2)||(is_3d()&&v.size()==3)
62 //---------------------------------------------------------------------------
64  double time) const
65 {
66  // require
67  assert(is_valid());
68  assert((is_2d()&&v.size()==2)||(is_3d()&&v.size()==3));
69 
72  if (mode_2d_)
73  {
74  result.put(0,v.get(0));
75  result.put(1,v.get(1));
76  result.put(2,0);
77  }
78  else
79  result=v;
80  result = q.rotate(result);
81  if (mode_2d_)
82  return vnl_vector<double>(result.data_block(), 2);
83  else
84  return vnl_vector<double>(result.data_block(), 3);
85 }
86 
87 //---------------------------------------------------------------------------
88 // Image of `v' by the inverse of `this'
89 // REQUIRE: is_valid()
90 // REQUIRE: is_invertible(time)
91 // REQUIRE: (is_2d()&&v.size()==2)||(is_3d()&&v.size()==3)
92 //---------------------------------------------------------------------------
94  double time) const
95 {
96  // require
97  assert(is_valid());
98  assert(is_invertible(time));
99  assert((is_2d()&&v.size()==2)||(is_3d()&&v.size()==3));
100 
102 
103  if (mode_2d_)
104  {
105  result.put(0,v.get(0));
106  result.put(1,v.get(1));
107  result.put(2,0);
108  }
109  else
110  result=v;
112  result = q.conjugate().rotate(result);
113  if (mode_2d_)
114  return vnl_vector<double>(result.data_block(), 2);
115  else
116  return vnl_vector<double>(result.data_block(), 3);
117 }
118 
119 //---------------------------------------------------------------------------
120 // Compute the value of the quaternion at time `time'
121 //---------------------------------------------------------------------------
123 {
124  vnl_quaternion<double> result;
125 
126  if (this->duration()==0) // static
127  {
128  if (mode_2d_)
129  {
130  vnl_vector<double> axis_2d(3);
131  axis_2d.put(0,0);
132  axis_2d.put(1,0);
133  axis_2d.put(2,1);
134  result=vnl_quaternion<double>(axis_2d,angle_[0]);
135  }
136  else
137  result=vnl_quaternion<double>(axis_[0],angle_[0]);
138  }
139  else
140  {
141  int i=matching_interval(time);
142  vnl_vector<double> axis_2d(3);
143 
144  if (mode_2d_)
145  {
146  axis_2d.put(0,0);
147  axis_2d.put(1,0);
148  axis_2d.put(2,1);
149  }
150 
151  switch (interpolator_[i])
152  {
153  case vcsl_linear:
154  {
155  vnl_quaternion<double> q0, q1;
156  if (mode_2d_)
157  {
158  q0=vnl_quaternion<double>(axis_2d,angle_[i]);
159  q1=vnl_quaternion<double>(axis_2d,angle_[i+1]);
160  }
161  else
162  {
164  q1=vnl_quaternion<double>(axis_[i+1],angle_[i+1]);
165  }
166  result=lqi(q0,q1,i,time);
167  break;
168  }
169  case vcsl_cubic:
170  assert(!"vcsl_cubic net yet implemented");
171  break;
172  case vcsl_spline:
173  assert(!"vcsl_spline net yet implemented");
174  break;
175  default:
176  assert(!"This is impossible");
177  break;
178  }
179  }
180  return result;
181 }
unsigned int duration() const
Return the time duration.
vnl_vector< double > execute(const vnl_vector< double > &v, double time) const override
Image of ‘v’ by ‘this’.
vnl_quaternion< double > lqi(const vnl_quaternion< double > &v0, const vnl_quaternion< double > &v1, int index, double time) const
Linear interpolation on quaternions.
std::vector< vnl_vector< double > > list_of_vectors
list_of_scalars angle_
Angle variation along the time in radians.
bool mode_2d_
False if ‘this’ is a 3D rotation, true if ‘this’ is a 2D rotation.
list_of_vectors axis_
Direction vector variation along the time.
vnl_vector< double > inverse(const vnl_vector< double > &v, double time) const override
Image of ‘v’ by the inverse of ‘this’.
std::vector< vcsl_interpolator > interpolator_
void set_static()
Empty the time clock and interpolators, thereby making the transf static.
#define v
bool is_invertible(double) const override
Is ‘this’ invertible at time ‘time’?.
Definition: vcsl_rotation.h:47
bool is_2d() const
Is ‘this’ a 2D rotation ?.
Definition: vcsl_rotation.h:60
vnl_quaternion< T > conjugate() const
bool are_unit_axes(list_of_vectors const &new_axis) const
Are ‘new_vector’ a list of unit vectors ?.
T const * data_block() const
void put(size_t i, double const &v)
void set_static_2d(double new_angle)
Set the parameters of a static 2D rotation.
Rotation transformation (either 2D or 3D)
vnl_vector_fixed< T, 3 > rotate(vnl_vector_fixed< T, 3 > const &) const
void set_axis(list_of_vectors const &new_axis)
Set the direction vector variation along the time.
int matching_interval(double time) const
Return the index of the beat inferior or equal to ‘time’.
bool is_3d() const
Is ‘this’ a 3D rotation ?.
Definition: vcsl_rotation.h:63
vnl_quaternion< double > quaternion(double time) const
Compute the value of the quaternion at time ‘time’.
void put(unsigned int i, T const &v)
bool is_valid() const override
Is ‘this’ correctly set ?.
Definition: vcsl_rotation.h:51