return get_point(epi, active_path, d);
}
+TrackPoint Track::get_nearest_point(const Vector &p) const
+{
+ Vector local(p.x-pos.x, p.y-pos.y, p.z-pos.z);
+ float c = cos(rot);
+ float s = sin(rot);
+ local = Vector(c*local.x+s*local.y, c*local.y-s*local.x, local.z);
+
+ TrackPoint tp = type.get_nearest_point(local);
+ tp.pos = Vector(pos.x+tp.pos.x*c-tp.pos.y*s, pos.y+tp.pos.y*c+tp.pos.x*s, pos.z+tp.pos.z);
+ tp.dir += rot;
+ return tp;
+}
+
bool Track::collide_ray(const Vector &start, const Vector &ray)
{
Vector local_start(start.x-pos.x, start.y-pos.y, start.z-pos.z);
Track *get_link(unsigned) const;
TrackPoint get_point(unsigned, unsigned, float) const;
TrackPoint get_point(unsigned, float) const;
+ TrackPoint get_nearest_point(const Vector &) const;
bool collide_ray(const Vector &, const Vector &);
return result;
}
+TrackPoint TrackPart::get_nearest_point(const Vector &p) const
+{
+ TrackPoint tp;
+ float c = cos(dir);
+ float s = sin(dir);
+ if(radius)
+ {
+ Vector v(p.x-pos.x+radius*s, p.y-pos.y-radius*c);
+ float a = atan2(v.y, v.x)+M_PI/2-dir;
+ if(radius<0)
+ a = M_PI-a;
+ while(a<length/2-M_PI)
+ a += M_PI*2;
+ while(a>length/2+M_PI)
+ a -= M_PI*2;
+ a = min(max(a, 0.0f), length);
+ if(radius<0)
+ a = -a;
+ tp.pos = Vector(pos.x+radius*(sin(dir+a)-s), pos.y+radius*(c-cos(dir+a)));
+ tp.dir = dir+a;
+ }
+ else
+ {
+ Vector v(p.x-pos.x, p.y-pos.y);
+ float d = min(max(c*v.x+s*v.y, 0.0f), length);
+ tp.pos = Vector(pos.x+c*d, pos.y+s*d);
+ tp.dir = dir;
+ }
+ return tp;
+}
+
void TrackPart::check_link(TrackPart &other)
{
unsigned n_eps = (dead_end ? 1 : 2);
float get_length() const;
bool is_curved() const { return radius; }
TrackPoint get_point(float) const;
+ TrackPoint get_nearest_point(const Vector &) const;
unsigned get_path() const { return path; }
bool is_dead_end() const { return dead_end; }
void check_link(TrackPart &);
}
}
+TrackPoint TrackType::get_nearest_point(const Vector &p) const
+{
+ TrackPoint result;
+ float dist = -1;
+
+ for(vector<TrackPart>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
+ {
+ TrackPoint n = i->get_nearest_point(p);
+ float d = distance(n.pos, p);
+ if(d<dist || dist<0)
+ {
+ result = n;
+ dist = d;
+ }
+ }
+
+ return result;
+}
+
bool TrackType::collide_ray(const Vector &start, const Vector &dir, float width) const
{
for(vector<TrackPart>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
const std::vector<Endpoint> &get_endpoints() const { return endpoints; }
const Endpoint &get_endpoint(unsigned) const;
TrackPoint get_point(unsigned, unsigned, float) const;
+ TrackPoint get_nearest_point(const Vector &) const;
bool collide_ray(const Vector &, const Vector &, float) const;
private: