+ {
+ d -= plen;
+ TrackPart *next = part->get_link(1-part_ep);
+ if(!next)
+ throw InvalidParameterValue("Distance out of range");
+ part_ep = (next->get_link(0)==part ? 0 : 1);
+ part = next;
+ }
+ }
+}
+
+void TrackType::collect_endpoints()
+{
+ endpoints.clear();
+
+ for(vector<TrackPart>::iterator i=parts.begin(); i!=parts.end(); ++i)
+ {
+ for(vector<TrackPart>::iterator j=i; ++j!=parts.end();)
+ i->check_link(*j);
+
+ unsigned n_part_eps = (i->is_dead_end() ? 1 : 2);
+ for(unsigned j=0; j<n_part_eps; ++j)
+ if(!i->get_link(j))
+ {
+ TrackPoint p = i->get_point(j ? i->get_length() : 0);
+ if(j==0)
+ p.dir += M_PI;
+
+ bool found = false;
+ for(vector<Endpoint>::iterator k=endpoints.begin(); k!=endpoints.end(); ++k)
+ {
+ float dx = k->pos.x-p.pos.x;
+ float dy = k->pos.y-p.pos.y;
+
+ float da = k->dir-p.dir;
+ while(da>M_PI)
+ da -= M_PI*2;
+ while(da<-M_PI)
+ da += M_PI*2;
+
+ if(dx*dx+dy*dy<1e-6 && da>-0.01 && da<0.01)
+ {
+ k->paths |= 1<<i->get_path();
+ found = true;
+ break;
+ }
+ }
+
+ if(!found)
+ endpoints.push_back(Endpoint(p.pos.x, p.pos.y, p.dir, 1<<i->get_path()));
+ }