if(layout.has_driver())
layout.get_driver().signal_turnout.connect(sigc::mem_fun(this, &Track::turnout_event));
+
+ for(unsigned paths = type.get_paths(); !(paths&1); ++active_path, paths>>=1) ;
}
Track::~Track()
void Track::set_slope(float s)
{
- if(links.size()!=2) return;
+ if(links.size()!=2)
+ return;
slope = s;
}
turnout_id = i;
layout.create_blocks(*this);
if(layout.has_driver() && turnout_id)
+ {
layout.get_driver().add_turnout(turnout_id);
+ if(type.is_double_address())
+ layout.get_driver().add_turnout(turnout_id+1);
+ }
}
void Track::set_sensor_id(unsigned i)
throw Exception("Track endpoint did not have a counterpart");
}
-Point Track::get_point(unsigned epi, unsigned path, float d) const
+TrackPoint Track::get_point(unsigned epi, unsigned path, float d) const
{
- const vector<Endpoint> &eps = type.get_endpoints();
- if(epi>=eps.size())
- throw InvalidParameterValue("Endpoint index out of range");
+ TrackPoint p = type.get_point(epi, path, d);
+ float c = cos(rot);
+ float s = sin(rot);
- float x = eps[epi].pos.x;
- float y = eps[epi].pos.y;
- float z = 0;
- float slope_norm = 0;
- if(eps.size()==2)
+ p.pos = Point(pos.x+c*p.pos.x-s*p.pos.y, pos.y+s*p.pos.x+c*p.pos.y, 0);
+ if(type.get_endpoints().size()==2)
{
- slope_norm = slope/type.get_total_length();
- if(epi==1)
+ float len = type.get_path_length(path);
+ float grade = slope/len;
+ if(epi==0)
{
- z = slope;
- slope_norm = -slope_norm;
+ p.pos.z = pos.z+grade*d;
+ p.grade = grade;
}
- }
-
- const vector<TrackPart> &parts = type.get_parts();
- const TrackPart *last_part = 0;
- while(1)
- {
- for(vector<TrackPart>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
+ else
{
- if((eps[epi].paths&(1<<path)) && i->path!=path)
- continue;
- if(&*i==last_part)
- continue;
-
- vector<Endpoint> part_eps;
- i->collect_endpoints(part_eps);
- for(unsigned j=0; j<part_eps.size(); ++j)
- {
- float dx = part_eps[j].pos.x-x;
- float dy = part_eps[j].pos.y-y;
- if(dx*dx+dy*dy<1e-6)
- {
- float plen = i->length;
- if(i->radius)
- plen *= abs(i->radius);
- if(d<plen)
- {
- z += d*slope_norm;
- if(j==1)
- d = plen-d;
- Point p = i->get_point(d);
- float c = cos(rot);
- float s = sin(rot);
- return Point(pos.x+c*p.x-s*p.y, pos.y+c*p.y+s*p.x, pos.z+z);
- }
- else if(part_eps.size()>1)
- {
- d -= plen;
- x = part_eps[1-j].pos.x;
- y = part_eps[1-j].pos.y;
- z += plen*slope_norm;
- last_part = &*i;
- i = parts.begin();
- break;
- }
- else
- return pos;
- }
- }
+ p.pos.z = pos.z+slope-grade*d;
+ p.grade = -grade;
}
-
- if(!last_part)
- throw Exception("Internal error (Endpoint does not match any part)");
- else
- return pos;
}
+
+ return p;
}
void Track::save(list<DataFile::Statement> &st) const