9 TrackPart::TrackPart():
20 float TrackPart::get_length() const
23 return abs(radius)*length;
28 TrackPoint TrackPart::get_point(float d) const
37 float rx = radius*sin(dir);
38 float ry = -radius*cos(dir);
39 result.pos = Vector(pos.x+c*rx-s*ry-rx, pos.y+c*ry+s*rx-ry);
44 result.pos = Vector(pos.x+cos(dir)*d, pos.y+sin(dir)*d);
51 TrackPoint TrackPart::get_nearest_point(const Vector &p) const
58 Vector v(p.x-pos.x+radius*s, p.y-pos.y-radius*c);
59 float a = atan2(v.y, v.x)+M_PI/2-dir;
62 while(a<length/2-M_PI)
64 while(a>length/2+M_PI)
66 a = min(max(a, 0.0f), length);
69 tp.pos = Vector(pos.x+radius*(sin(dir+a)-s), pos.y+radius*(c-cos(dir+a)));
74 Vector v(p.x-pos.x, p.y-pos.y);
75 float d = min(max(c*v.x+s*v.y, 0.0f), length);
76 tp.pos = Vector(pos.x+c*d, pos.y+s*d);
82 void TrackPart::check_link(TrackPart &other)
84 unsigned n_eps = (dead_end ? 1 : 2);
85 unsigned n_other_eps = (other.is_dead_end() ? 1 : 2);
86 for(unsigned i=0; i<n_eps; ++i)
88 TrackPoint p1 = get_point(i ? get_length() : 0);
89 for(unsigned j=0; j<n_other_eps; ++j)
91 TrackPoint p2 = other.get_point(j ? other.get_length() : 0);
93 float dx = p2.pos.x-p1.pos.x;
94 float dy = p2.pos.y-p1.pos.y;
96 float da = p2.dir-p1.dir+M_PI*((i+j+1)%2);
102 if(dx*dx+dy*dy<1e-6 && da>=-0.01 && da<=0.01)
105 other.links[j] = this;
112 TrackPart *TrackPart::get_link(unsigned i) const
115 throw out_of_range("TrackPart::get_link");
119 bool TrackPart::collide_ray(const Vector &start, const Vector &ray, float width) const
121 Vector local_start(start.x-pos.x, start.y-pos.y, start.z);
124 local_start = Vector(c*local_start.x+s*local_start.y, c*local_start.y-s*local_start.x, local_start.z);
125 Vector local_ray(c*ray.x+s*ray.y, c*ray.y-s*ray.x, ray.z);
127 float d = -local_start.z/local_ray.z;
131 Vector base(local_start.x+d*local_ray.x, local_start.y+d*local_ray.y);
138 float r = sqrt(base.x*base.x+base.y*base.y)-abs(radius);
139 float a = atan2(base.x, -base.y);
140 return (a>=0 && a<=length && r>=-width/2 && r<=width/2);
143 return (base.x>=0 && base.x<=length && base.y>=-width/2 && base.y<=width/2);
147 TrackPart::Loader::Loader(TrackPart &p):
148 Msp::DataFile::ObjectLoader<TrackPart>(p)
150 add("start", &Loader::start);
151 add("length", &TrackPart::length);
152 add("radius", &TrackPart::radius);
153 add("path", &TrackPart::path);
154 add("dead_end", &TrackPart::dead_end);
157 void TrackPart::Loader::finish()
161 obj.length *= M_PI/180;
172 void TrackPart::Loader::start(float x, float y, float d)
174 obj.pos = Vector(x, y);