+TrackPoint Track::get_point(unsigned epi, unsigned path, float d) const
+{
+ TrackPoint p = type.get_point(epi, path, d);
+ float c = cos(rot);
+ float s = sin(rot);
+
+ p.pos = Point(pos.x+c*p.pos.x-s*p.pos.y, pos.y+s*p.pos.x+c*p.pos.y, 0);
+ p.dir += rot;
+ if(type.get_endpoints().size()==2)
+ {
+ float len = type.get_path_length(path);
+ float grade = slope/len;
+ if(epi==0)
+ {
+ p.pos.z = pos.z+grade*d;
+ p.grade = grade;
+ }
+ else
+ {
+ p.pos.z = pos.z+slope-grade*d;
+ p.grade = -grade;
+ }
+ }
+
+ return p;
+}
+
+TrackPoint Track::get_point(unsigned epi, float d) const
+{
+ return get_point(epi, active_path, d);
+}
+
+void Track::save(list<DataFile::Statement> &st) const
+{
+ st.push_back((DataFile::Statement("position"), pos.x, pos.y, pos.z));
+ st.push_back((DataFile::Statement("rotation"), rot));
+ st.push_back((DataFile::Statement("slope"), slope));
+ if(turnout_id)
+ st.push_back((DataFile::Statement("turnout_id"), turnout_id));
+ if(sensor_id)
+ st.push_back((DataFile::Statement("sensor_id"), sensor_id));
+ if(flex)
+ st.push_back((DataFile::Statement("flex"), true));
+}
+
+void Track::turnout_event(unsigned addr, bool state)
+{
+ if(!turnout_id)
+ return;
+
+ if(addr==turnout_id)
+ active_path = (active_path&2) | (state ? 1 : 0);
+ else if(type.is_double_address() && addr==turnout_id+1)
+ active_path = (active_path&1) | (state ? 2 : 0);