/* $Id$
This file is part of the MSP Märklin suite
-Copyright © 2006-2009 Mikkosoft Productions, Mikko Rasa
+Copyright © 2006-2010 Mikkosoft Productions, Mikko Rasa
Distributed under the GPL
*/
#include "trackpart.h"
using namespace std;
+using namespace Msp;
namespace Marklin {
dir(0),
length(0),
radius(0),
- route(0),
+ path(0),
dead_end(false)
-{ }
-
-void TrackPart::collect_endpoints(vector<Endpoint> &eps) const
{
- eps.push_back(Endpoint(pos.x, pos.y, dir+M_PI, 1<<route));
+ links[0] = 0;
+ links[1] = 0;
+}
- if(dead_end)
- ;
- else if(radius)
- {
- float a = ((radius<0) ? -length : length);
- Point p = get_point(length*abs(radius));
- eps.push_back(Endpoint(p.x, p.y, dir+a, 1<<route));
- }
+float TrackPart::get_length() const
+{
+ if(radius)
+ return abs(radius)*length;
else
- eps.push_back(Endpoint(pos.x+cos(dir)*length, pos.y+sin(dir)*length, dir, 1<<route));
+ return length;
}
-Point TrackPart::get_point(float d) const
+TrackPoint TrackPart::get_point(float d) const
{
+ TrackPoint result;
+
if(radius)
{
float a = d/radius;
float s = sin(a);
float rx = radius*sin(dir);
float ry = -radius*cos(dir);
- return Point(pos.x+c*rx-s*ry-rx, pos.y+c*ry+s*rx-ry);
+ result.pos = Point(pos.x+c*rx-s*ry-rx, pos.y+c*ry+s*rx-ry);
+ result.dir = dir+a;
}
else
- return Point(pos.x+cos(dir)*d, pos.y+sin(dir)*d);
+ {
+ result.pos = Point(pos.x+cos(dir)*d, pos.y+sin(dir)*d);
+ result.dir = dir;
+ }
+
+ return result;
+}
+
+void TrackPart::check_link(TrackPart &other)
+{
+ unsigned n_eps = (dead_end ? 1 : 2);
+ unsigned n_other_eps = (other.is_dead_end() ? 1 : 2);
+ for(unsigned i=0; i<n_eps; ++i)
+ {
+ TrackPoint p1 = get_point(i ? get_length() : 0);
+ for(unsigned j=0; j<n_other_eps; ++j)
+ {
+ TrackPoint p2 = other.get_point(j ? other.get_length() : 0);
+
+ float dx = p2.pos.x-p1.pos.x;
+ float dy = p2.pos.y-p1.pos.y;
+
+ float da = p2.dir-p1.dir+M_PI*((i+j+1)%2);
+ 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)
+ {
+ links[i] = &other;
+ other.links[j] = this;
+ return;
+ }
+ }
+ }
+}
+
+TrackPart *TrackPart::get_link(unsigned i) const
+{
+ if(i>=2)
+ throw InvalidParameterValue("Index out of range");
+ return links[i];
}
add("start", &Loader::start);
add("length", &TrackPart::length);
add("radius", &TrackPart::radius);
- add("route", &TrackPart::route);
+ add("path", &TrackPart::path);
add("dead_end", &TrackPart::dead_end);
}