+ if(epi>=endpoints.size())
+ throw InvalidParameterValue("Endpoint index out of range");
+
+ const TrackPart *part = 0;
+ unsigned part_ep = 0;
+ for(vector<TrackPart>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
+ {
+ if((endpoints[epi].paths&(1<<path)) && i->get_path()!=path)
+ continue;
+
+ unsigned n_part_eps = (i->is_dead_end() ? 1 : 2);
+ for(unsigned j=0; j<n_part_eps; ++j)
+ {
+ TrackPoint p = i->get_point(j ? i->get_length() : 0);
+ float dx = p.pos.x-endpoints[epi].pos.x;
+ float dy = p.pos.y-endpoints[epi].pos.y;
+ if(dx*dx+dy*dy<1e-6)
+ {
+ part = &*i;
+ part_ep = j;
+ }
+ }
+ }
+
+ if(!part)
+ throw Exception("Internal error (endpoint does not match any part)");
+
+ while(1)
+ {
+ float plen = part->get_length();
+ if(d<=plen)
+ {
+ if(part_ep==1)
+ d = plen-d;
+ TrackPoint p = part->get_point(d);
+ if(part_ep==1)
+ p.dir += M_PI;
+ return p;
+ }
+ else
+ {
+ 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;
+ }
+ }