vcsl_spatial.cxx
Go to the documentation of this file.
1 // This is core/vcsl/vcsl_spatial.cxx
2 #include "vcsl_spatial.h"
3 #include <cassert>
4 #ifdef _MSC_VER
5 # include <vcl_msvc_warnings.h>
6 #endif
8 #include <vcsl/vcsl_graph.h>
9 
10 //---------------------------------------------------------------------------
11 // Destructor
12 //---------------------------------------------------------------------------
14 {
15  if (graph_)
16  graph_->remove(this);
17 }
18 
19 //---------------------------------------------------------------------------
20 // Is `time' between the two time bounds ?
21 //---------------------------------------------------------------------------
22 bool vcsl_spatial::valid_time(double time) const
23 {
24  if (beat_.size()==0)
25  return true;
26  else
27  return (beat_[0]<=time)&&(time<=beat_[beat_.size()-1]);
28 }
29 
30 //---------------------------------------------------------------------------
31 // Set the list of parent coordinate system along the time
32 //---------------------------------------------------------------------------
33 void vcsl_spatial::set_parent(std::vector<vcsl_spatial_sptr> const& new_parent)
34 {
35  std::vector<vcsl_spatial_sptr>::iterator i, j;
36 
37  if (parent_!=new_parent)
38  {
39  // Erase 'this' from the list of the old parents' potential children
40  for (i=parent_.begin();i!=parent_.end();++i)
41  {
42  std::vector<vcsl_spatial_sptr> children=(*i)->potential_children_;
43  for (j=children.begin(); j!=children.end()&&(*j).ptr()!=this; ++j)
44  ;
45  if ((*j).ptr()==this) children.erase(j);
46  }
47  parent_=new_parent;
48 
49  // Add 'this' to the list of the new parents' potential children
50  for (i=parent_.begin();i!=parent_.end();++i)
51  if (*i)
52  (*i)->potential_children_.emplace_back(this);
53  }
54 }
55 
56 //---------------------------------------------------------------------------
57 // Set the unique parent and the unique motion
58 //---------------------------------------------------------------------------
59 void
61  const vcsl_spatial_transformation_sptr &new_motion)
62 {
63  motion_.clear(); motion_.push_back(new_motion);
64  std::vector<vcsl_spatial_sptr> temp_parent; temp_parent.push_back(new_parent);
65  set_parent(temp_parent);
66  beat_.clear();
67 }
68 
69 //---------------------------------------------------------------------------
70 // Return the index of the beat inferior or equal to `time'
71 // REQUIRE: parent().size()!=0
72 // REQUIRE: valid_time(time)
73 //---------------------------------------------------------------------------
74 int vcsl_spatial::matching_interval(double time) const
75 {
76  // require
77  assert(parent_.size()!=0);
78  assert(valid_time(time));
79 
80  // Dichotomic research of the index
81  int inf=0;
82  int sup=beat_.size()-1;
83  while (sup-inf>1)
84  {
85  int mid=(inf+sup)/2;
86  if (beat_[mid]>time)
87  sup=mid;
88  else
89  inf=mid;
90  }
91  return inf;
92 }
93 
94 //---------------------------------------------------------------------------
95 // Does a path from `this' to `other' exist ?
96 //---------------------------------------------------------------------------
98  double time)
99 {
100  graph_->init_vertices();
101 
102  return recursive_path_from_local_to_cs_exists(other,time);
103 }
104 
105 //---------------------------------------------------------------------------
106 // Does a path from `this' to `other' exist ? Called only by
107 // path_to_cs_exists()
108 //---------------------------------------------------------------------------
110  double time)
111 {
112  bool result;
113  int i = -1; // dummy initialisation to avoid compiler warning
114  std::vector<vcsl_spatial_sptr>::const_iterator child;
115  if (parent_.size()!=0) // If 'this' is not absolute
116  i=matching_interval(time);
117  set_reached(true);
118 
119  // Check if parent of 'this' (if it exists) is 'other'
120  result=!is_absolute(time); // true if 'this' has a parent
121  if (result)
122  result=parent_[i]==other; // true if parent is 'other' (the cs sought)
123 
124  // If 'this' has no parent or its parent is not 'other':
125  if (!result)
126  {
127  // Check if 'other' can be reached through parent
128  if (!is_absolute(time)) // if 'this' has a parent
129  // If parent has not already been checked
130  if (!parent_[i]->reached())
131  // Check if 'other' can be reached from it
132  result=parent_[i]->recursive_path_from_local_to_cs_exists(other, time);
133  // If 'other' not found, check if 'other' can be reached through children of 'this'
134  if (!result)
135  {
136  if (potential_children_.size()!=0)
137  {
138  for (child=potential_children_.begin();
139  !result && child!=potential_children_.end();
140  ++child)
141  {
142  result=!(*child)->reached();
143  if (result)
144  {
145  int j=(*child)->matching_interval(time);
146  result=(*child)->parent_[j].ptr()==this;
147  if (result)
148  result=(*child)->motion_[j]->is_invertible(time);
149  }
150  if (result)
151  {
152  result=(*child)==other;
153  if (!result)
154  result=(*child)->recursive_path_from_local_to_cs_exists(other, time);
155  }
156  }
157  }
158  }
159  }
160  return result;
161 }
162 
163 //---------------------------------------------------------------------------
164 // Find the sequence of transformations from `this' to `other'
165 // REQUIRE: path.size()==0 and sens.size()==0
166 // REQUIRE: path_from_local_to_cs_exists(other,time)
167 //---------------------------------------------------------------------------
169  double time,
170  std::vector<vcsl_spatial_transformation_sptr> &path,
172 {
173  // require
174  assert(path.size()==0);
175  assert(sens.size()==0);
176  assert(path_from_local_to_cs_exists(other,time));
177 
178  //unused bool path_exists;
179 
180  graph_->init_vertices();
181  /*path_exists=*/ recursive_path_from_local_to_cs(other,time,path,sens);
182 }
183 
184 //---------------------------------------------------------------------------
185 // Find the sequence of transformations from `this' to `other'
186 // Called only by path_from_local_to_cs()
187 //---------------------------------------------------------------------------
188 bool
190  double time,
191  std::vector<vcsl_spatial_transformation_sptr> &path,
193 {
194  bool result;
195  int i = -1; // dummy initialisation to avoid compiler warning
196  std::vector<vcsl_spatial_sptr>::const_iterator child;
197 
198  if (parent_.size()!=0)
199  i=matching_interval(time);
200 
201  set_reached(true);
202 
203  result=!is_absolute(time);
204  if (result)
205  result=parent_[i]==other;
206 
207  if (result)
208  {
209  path.push_back(motion_[i]);
210  sens.push_back(false);
211  }
212 
213  if (!result)
214  {
215  if (!is_absolute(time))
216  if (!parent_[i]->reached())
217  {
218  path.push_back(motion_[i]);
219  sens.push_back(false);
220  result=parent_[i]->recursive_path_from_local_to_cs(other,time,path,sens);
221  if (!result)
222  {
223  path.pop_back();
224  sens.pop_back();
225  }
226  }
227  if (!result)
228  {
229  if (potential_children_.size()!=0)
230  {
231  for (child=potential_children_.begin();
232  !result && child!=potential_children_.end();
233  ++child)
234  {
235  result=!(*child)->reached();
236  if (result)
237  {
238  int j=(*child)->matching_interval(time);
239  result=(*child)->parent_[j].ptr()==this;
240  if (result)
241  result=(*child)->motion_[j]->is_invertible(time);
242  if (result)
243  {
244  result=(*child)==other;
245  path.push_back((*child)->motion_[j]);
246  sens.push_back(true);
247  if (!result)
248  {
249  result=(*child)->recursive_path_from_local_to_cs(other,time,
250  path,sens);
251  if (!result)
252  {
253  path.pop_back();
254  sens.pop_back();
255  }
256  }
257  }
258  }
259  }
260  }
261  }
262  }
263 
264  return result;
265 }
266 
267 //---------------------------------------------------------------------------
268 // Is `this' an absolute spatial coordinate system at time `time'?
269 // REQUIRE: valid_time(time)
270 //---------------------------------------------------------------------------
271 bool vcsl_spatial::is_absolute(double time) const
272 {
273  // require
274  assert(valid_time(time));
275 
276  // If list of parents is NULL, 'this' must be absolute
277  if (parent_.size()==0)
278  return true;
279  else
280  {
281  // If parent at given interval is NULL, 'this' must be absolute
282  int i=matching_interval(time);
283  return !parent_[i];
284  }
285 }
286 
287 //---------------------------------------------------------------------------
288 // From a vector `v' expressed in `this',
289 // return a vector expressed in the spatial coordinate system `other'
290 // REQUIRE: path_from_local_to_cs_exists(other,time)
291 //---------------------------------------------------------------------------
294  const vcsl_spatial_sptr &other,
295  double time)
296 {
297  // require
298  assert(path_from_local_to_cs_exists(other,time));
299 
300  std::vector<vcsl_spatial_transformation_sptr> path;
302 
303  std::vector<vcsl_spatial_transformation_sptr>::const_iterator i;
304  VCSL_SPATIAL_VECTOR_BOOL::const_iterator j;
305 
306  path_from_local_to_cs(other,time,path,sens);
307 
309 
310  j=sens.begin();
311 
312  for (i=path.begin();i!=path.end();++i,++j)
313  {
314  if (*j)
315  tmp=(*i)->inverse(tmp,time);
316  else
317  tmp=(*i)->execute(tmp,time);
318  }
319  return other->from_standard_units_to_cs(tmp);
320 }
321 
323 {
324  if (graph_)
325  graph_->remove(this);
326  graph_=new_graph;
327  graph_->put(this);
328 }
virtual bool recursive_path_from_local_to_cs_exists(const vcsl_spatial_sptr &other, double time)
Does a path from ‘this’ to ‘other’ exist ?.
virtual bool path_from_local_to_cs_exists(const vcsl_spatial_sptr &other, double time)
Does a path from ‘this’ to ‘other’ exist ?.
virtual int matching_interval(double time) const
Return the index of the beat inferior or equal to ‘time’.
bool reached() const
Definition: vcsl_spatial.h:142
~vcsl_spatial() override
std::vector< double > beat_
Clock times.
Definition: vcsl_spatial.h:175
Transformation between 2 spatial coordinate systems.
virtual void set_graph(const vcsl_graph_sptr &new_graph)
#define v
#define VCSL_SPATIAL_VECTOR_BOOL
Definition: vcsl_spatial.h:35
virtual void path_from_local_to_cs(const vcsl_spatial_sptr &other, double time, std::vector< vcsl_spatial_transformation_sptr > &path, VCSL_SPATIAL_VECTOR_BOOL &sens)
Find the sequence of transformations from ‘this’ to ‘other’.
Spatial coordinate system transformation graph.
vnl_vector< double > from_cs_to_standard_units(const vnl_vector< double > &v) const
Convert ‘v’, expressed with cs units, to standard units.
bool valid_time(double time) const
Is ‘time’ between the two time bounds ?.
void set_unique(const vcsl_spatial_sptr &new_parent, const vcsl_spatial_transformation_sptr &new_motion)
Set the unique parent and the unique motion.
std::vector< vcsl_spatial_transformation_sptr > motion_
successive transformations from ‘this’ to ‘parent’ along the time.
Definition: vcsl_spatial.h:178
virtual bool recursive_path_from_local_to_cs(const vcsl_spatial_sptr &other, double time, std::vector< vcsl_spatial_transformation_sptr > &path, VCSL_SPATIAL_VECTOR_BOOL &sens)
Find the sequence of transformations from ‘this’ to ‘other’.
vcsl_graph_sptr graph_
List of all the spatial coordinate system of the graph.
Definition: vcsl_spatial.h:184
std::vector< vcsl_spatial_sptr > potential_children_
List of spatial coordinate system that can be child of ‘this’ at a time.
Definition: vcsl_spatial.h:181
void set_parent(std::vector< vcsl_spatial_sptr > const &new_parent)
Set the list of parent coordinate system along the time.
void set_reached(const bool &new_reached)
Definition: vcsl_spatial.h:141
A spatial coordinate system.
virtual vnl_vector< double > from_local_to_cs(const vnl_vector< double > &v, const vcsl_spatial_sptr &other, double time)
Return v but expressed in the spatial coordinate system ‘other’.
virtual bool is_absolute(double time) const
Is ‘this’ an absolute spatial coordinate system at time ‘time’?.
std::vector< vcsl_spatial_sptr > parent_
successive parents of ‘this’ along the time.
Definition: vcsl_spatial.h:172