Go to the documentation of this file.00001
00002 #include "vcsl_spatial.h"
00003 #include <vcl_cassert.h>
00004 #include <vcsl/vcsl_spatial_transformation.h>
00005 #include <vcsl/vcsl_graph.h>
00006
00007
00008
00009
00010 vcsl_spatial::~vcsl_spatial()
00011 {
00012 if (graph_)
00013 graph_->remove(this);
00014 }
00015
00016
00017
00018
00019 bool vcsl_spatial::valid_time(double time) const
00020 {
00021 if (beat_.size()==0)
00022 return true;
00023 else
00024 return (beat_[0]<=time)&&(time<=beat_[beat_.size()-1]);
00025 }
00026
00027
00028
00029
00030 void vcsl_spatial::set_parent(vcl_vector<vcsl_spatial_sptr> const& new_parent)
00031 {
00032 vcl_vector<vcsl_spatial_sptr>::iterator i, j;
00033
00034 if (parent_!=new_parent)
00035 {
00036
00037 for (i=parent_.begin();i!=parent_.end();++i)
00038 {
00039 vcl_vector<vcsl_spatial_sptr> children=(*i)->potential_children_;
00040 for (j=children.begin(); j!=children.end()&&(*j).ptr()!=this; ++j)
00041 ;
00042 if ((*j).ptr()==this) children.erase(j);
00043 }
00044 parent_=new_parent;
00045
00046
00047 for (i=parent_.begin();i!=parent_.end();++i)
00048 if (*i)
00049 (*i)->potential_children_.push_back(this);
00050 }
00051 }
00052
00053
00054
00055
00056 void
00057 vcsl_spatial::set_unique(const vcsl_spatial_sptr &new_parent,
00058 const vcsl_spatial_transformation_sptr &new_motion)
00059 {
00060 motion_.clear(); motion_.push_back(new_motion);
00061 vcl_vector<vcsl_spatial_sptr> temp_parent; temp_parent.push_back(new_parent);
00062 set_parent(temp_parent);
00063 beat_.clear();
00064 }
00065
00066
00067
00068
00069
00070
00071 int vcsl_spatial::matching_interval(double time) const
00072 {
00073
00074 assert(parent_.size()!=0);
00075 assert(valid_time(time));
00076
00077
00078 int inf=0;
00079 int sup=beat_.size()-1;
00080 while (sup-inf>1)
00081 {
00082 int mid=(inf+sup)/2;
00083 if (beat_[mid]>time)
00084 sup=mid;
00085 else
00086 inf=mid;
00087 }
00088 return inf;
00089 }
00090
00091
00092
00093
00094 bool vcsl_spatial::path_from_local_to_cs_exists(const vcsl_spatial_sptr &other,
00095 double time)
00096 {
00097 graph_->init_vertices();
00098
00099 return recursive_path_from_local_to_cs_exists(other,time);
00100 }
00101
00102
00103
00104
00105
00106 bool vcsl_spatial::recursive_path_from_local_to_cs_exists(const vcsl_spatial_sptr &other,
00107 double time)
00108 {
00109 bool result;
00110 int i = -1;
00111 vcl_vector<vcsl_spatial_sptr>::const_iterator child;
00112 if (parent_.size()!=0)
00113 i=matching_interval(time);
00114 set_reached(true);
00115
00116
00117 result=!is_absolute(time);
00118 if (result)
00119 result=parent_[i]==other;
00120
00121
00122 if (!result)
00123 {
00124
00125 if (!is_absolute(time))
00126
00127 if (!parent_[i]->reached())
00128
00129 result=parent_[i]->recursive_path_from_local_to_cs_exists(other, time);
00130
00131 if (!result)
00132 {
00133 if (potential_children_.size()!=0)
00134 {
00135 for (child=potential_children_.begin();
00136 !result && child!=potential_children_.end();
00137 ++child)
00138 {
00139 result=!(*child)->reached();
00140 if (result)
00141 {
00142 int j=(*child)->matching_interval(time);
00143 result=(*child)->parent_[j].ptr()==this;
00144 if (result)
00145 result=(*child)->motion_[j]->is_invertible(time);
00146 }
00147 if (result)
00148 {
00149 result=(*child)==other;
00150 if (!result)
00151 result=(*child)->recursive_path_from_local_to_cs_exists(other, time);
00152 }
00153 }
00154 }
00155 }
00156 }
00157 return result;
00158 }
00159
00160
00161
00162
00163
00164
00165 void vcsl_spatial::path_from_local_to_cs(const vcsl_spatial_sptr &other,
00166 double time,
00167 vcl_vector<vcsl_spatial_transformation_sptr> &path,
00168 VCSL_SPATIAL_VECTOR_BOOL &sens)
00169 {
00170
00171 assert(path.size()==0);
00172 assert(sens.size()==0);
00173 assert(path_from_local_to_cs_exists(other,time));
00174
00175
00176
00177 graph_->init_vertices();
00178 recursive_path_from_local_to_cs(other,time,path,sens);
00179 }
00180
00181
00182
00183
00184
00185 bool
00186 vcsl_spatial::recursive_path_from_local_to_cs(const vcsl_spatial_sptr &other,
00187 double time,
00188 vcl_vector<vcsl_spatial_transformation_sptr> &path,
00189 VCSL_SPATIAL_VECTOR_BOOL &sens)
00190 {
00191 bool result;
00192 int i = -1;
00193 vcl_vector<vcsl_spatial_sptr>::const_iterator child;
00194
00195 if (parent_.size()!=0)
00196 i=matching_interval(time);
00197
00198 set_reached(true);
00199
00200 result=!is_absolute(time);
00201 if (result)
00202 result=parent_[i]==other;
00203
00204 if (result)
00205 {
00206 path.push_back(motion_[i]);
00207 sens.push_back(false);
00208 }
00209
00210 if (!result)
00211 {
00212 if (!is_absolute(time))
00213 if (!parent_[i]->reached())
00214 {
00215 path.push_back(motion_[i]);
00216 sens.push_back(false);
00217 result=parent_[i]->recursive_path_from_local_to_cs(other,time,path,sens);
00218 if (!result)
00219 {
00220 path.pop_back();
00221 sens.pop_back();
00222 }
00223 }
00224 if (!result)
00225 {
00226 if (potential_children_.size()!=0)
00227 {
00228 for (child=potential_children_.begin();
00229 !result && child!=potential_children_.end();
00230 ++child)
00231 {
00232 result=!(*child)->reached();
00233 if (result)
00234 {
00235 int j=(*child)->matching_interval(time);
00236 result=(*child)->parent_[j].ptr()==this;
00237 if (result)
00238 result=(*child)->motion_[j]->is_invertible(time);
00239 if (result)
00240 {
00241 result=(*child)==other;
00242 path.push_back((*child)->motion_[j]);
00243 sens.push_back(true);
00244 if (!result)
00245 {
00246 result=(*child)->recursive_path_from_local_to_cs(other,time,
00247 path,sens);
00248 if (!result)
00249 {
00250 path.pop_back();
00251 sens.pop_back();
00252 }
00253 }
00254 }
00255 }
00256 }
00257 }
00258 }
00259 }
00260
00261 return result;
00262 }
00263
00264
00265
00266
00267
00268 bool vcsl_spatial::is_absolute(double time) const
00269 {
00270
00271 assert(valid_time(time));
00272
00273
00274 if (parent_.size()==0)
00275 return true;
00276 else
00277 {
00278
00279 int i=matching_interval(time);
00280 return !parent_[i];
00281 }
00282 }
00283
00284
00285
00286
00287
00288
00289 vnl_vector<double>
00290 vcsl_spatial::from_local_to_cs(const vnl_vector<double> &v,
00291 const vcsl_spatial_sptr &other,
00292 double time)
00293 {
00294
00295 assert(path_from_local_to_cs_exists(other,time));
00296
00297 vcl_vector<vcsl_spatial_transformation_sptr> path;
00298 VCSL_SPATIAL_VECTOR_BOOL sens;
00299
00300 vcl_vector<vcsl_spatial_transformation_sptr>::const_iterator i;
00301 VCSL_SPATIAL_VECTOR_BOOL::const_iterator j;
00302
00303 path_from_local_to_cs(other,time,path,sens);
00304
00305 vnl_vector<double> tmp=from_cs_to_standard_units(v);
00306
00307 j=sens.begin();
00308
00309 for (i=path.begin();i!=path.end();++i,++j)
00310 {
00311 if (*j)
00312 tmp=(*i)->inverse(tmp,time);
00313 else
00314 tmp=(*i)->execute(tmp,time);
00315 }
00316 return other->from_standard_units_to_cs(tmp);
00317 }
00318
00319 void vcsl_spatial::set_graph(const vcsl_graph_sptr &new_graph)
00320 {
00321 if (graph_)
00322 graph_->remove(this);
00323 graph_=new_graph;
00324 graph_->put(this);
00325 }