namespace R2C2 {
Track::Track(Layout &l, const TrackType &t):
- layout(l),
+ Object(l),
type(t),
block(0),
- rot(0),
slope(0),
flex(false),
turnout_id(0),
layout.remove_track(*this);
}
+Track *Track::clone(Layout *to_layout) const
+{
+ Track *track = new Track((to_layout ? *to_layout : layout), type);
+ track->set_position(position);
+ track->set_rotation(rotation);
+ return track;
+}
+
void Track::set_block(Block *b)
{
if(b && !b->has_track(*this))
void Track::set_position(const Vector &p)
{
- pos = p;
+ position = p;
}
void Track::set_rotation(float r)
{
- rot = r;
- while(rot<0)
- rot += M_PI*2;
- while(rot>M_PI*2)
- rot -= M_PI*2;
+ rotation = r;
+ while(rotation<0)
+ rotation += M_PI*2;
+ while(rotation>M_PI*2)
+ rotation -= M_PI*2;
}
void Track::set_slope(float s)
{
Vector epp0 = links[0]->get_endpoint_position(links[0]->get_endpoint_by_link(*this));
Vector epp1 = links[1]->get_endpoint_position(links[1]->get_endpoint_by_link(*this));
- pos.z = epp0.z;
- slope = epp1.z-pos.z;
+ position.z = epp0.z;
+ slope = epp1.z-position.z;
}
else
{
if(links[0])
{
Vector epp = links[0]->get_endpoint_position(links[0]->get_endpoint_by_link(*this));
- pos.z = epp.z;
+ position.z = epp.z;
}
else if(links[1])
{
Vector epp = links[1]->get_endpoint_position(links[1]->get_endpoint_by_link(*this));
- pos.z = epp.z;
+ position.z = epp.z;
}
}
}
const TrackType::Endpoint &ep = eps[epi];
- float c = cos(rot);
- float s = sin(rot);
+ float c = cos(rotation);
+ float s = sin(rotation);
- Vector p(pos.x+c*ep.pos.x-s*ep.pos.y, pos.y+s*ep.pos.x+c*ep.pos.y, pos.z);
+ Vector p(position.x+c*ep.pos.x-s*ep.pos.y, position.y+s*ep.pos.x+c*ep.pos.y, position.z);
if(eps.size()==2 && epi==1)
p.z += slope;
return p;
const TrackType::Endpoint &ep = eps[epi];
- return rot+ep.dir;
+ return rotation+ep.dir;
}
bool Track::snap_to(Track &other, bool link, float limit)
{
if(!link || (!flex && !other.get_flex()))
{
- set_rotation(other.rot+other_eps[j].dir-eps[i].dir+M_PI);
- Vector p(epp2.x-(eps[i].pos.x*cos(rot)-eps[i].pos.y*sin(rot)),
- epp2.y-(eps[i].pos.y*cos(rot)+eps[i].pos.x*sin(rot)),
+ set_rotation(other.rotation+other_eps[j].dir-eps[i].dir+M_PI);
+ Vector p(epp2.x-(eps[i].pos.x*cos(rotation)-eps[i].pos.y*sin(rotation)),
+ epp2.y-(eps[i].pos.y*cos(rotation)+eps[i].pos.x*sin(rotation)),
epp2.z);
if(eps.size()==2 && i==1)
p.z -= slope;
if(dx*dx+dy*dy<1e-4)
{
pt = epp;
- d = rot+eps[i].dir;
+ d = rotation+eps[i].dir;
return true;
}
}
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);
+ float c = cos(rotation);
+ float s = sin(rotation);
- p.pos = Vector(pos.x+c*p.pos.x-s*p.pos.y, pos.y+s*p.pos.x+c*p.pos.y, pos.z);
- p.dir += rot;
+ p.pos = Vector(position.x+c*p.pos.x-s*p.pos.y, position.y+s*p.pos.x+c*p.pos.y, position.z);
+ p.dir += rotation;
if(type.get_endpoints().size()==2)
{
float len = type.get_path_length(path);
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);
+ Vector local(p.x-position.x, p.y-position.y, p.z-position.z);
+ float c = cos(rotation);
+ float s = sin(rotation);
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;
+ tp.pos = Vector(position.x+tp.pos.x*c-tp.pos.y*s, position.y+tp.pos.y*c+tp.pos.x*s, position.z+tp.pos.z);
+ tp.dir += rotation;
return tp;
}
-bool Track::collide_ray(const Vector &start, const Vector &ray)
+bool Track::collide_ray(const Vector &start, const Vector &ray) const
{
- Vector local_start(start.x-pos.x, start.y-pos.y, start.z-pos.z);
- float c = cos(rot);
- float s = sin(rot);
+ Vector local_start(start.x-position.x, start.y-position.y, start.z-position.z);
+ float c = cos(rotation);
+ float s = sin(rotation);
local_start = Vector(c*local_start.x+s*local_start.y, c*local_start.y-s*local_start.x, local_start.z);
Vector local_ray(c*ray.x+s*ray.y, c*ray.y-s*ray.x, ray.z);
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("position"), position.x, position.y, position.z));
+ st.push_back((DataFile::Statement("rotation"), rotation));
st.push_back((DataFile::Statement("slope"), slope));
if(turnout_id)
st.push_back((DataFile::Statement("turnout_id"), turnout_id));
DataFile::ObjectLoader<Track>(t)
{
add("position", &Loader::position);
- add("rotation", &Track::rot);
+ add("rotation", &Loader::rotation);
add("slope", &Track::slope);
add("turnout_id", &Loader::turnout_id);
add("sensor_id", &Loader::sensor_id);
void Track::Loader::position(float x, float y, float z)
{
- obj.pos = Vector(x, y, z);
+ obj.position = Vector(x, y, z);
+}
+
+void Track::Loader::rotation(float r)
+{
+ obj.rotation = r;
}
void Track::Loader::sensor_id(unsigned id)