unsigned n_vertices = profile.get_n_vertices();
for(unsigned i=0; i<=nsegs; ++i)
{
- TrackPoint basep = part.get_point(i*plen/nsegs);
- Transform trans = Transform::rotation(basep.dir, Vector(0, 0, 1));
+ OrientedPoint basep = part.get_point(i*plen/nsegs);
+ Transform trans = Transform::rotation(basep.rotation, Vector(0, 0, 1));
for(unsigned j=0; j<n_vertices; ++j)
{
Vector p(0, -v.pos.x, v.pos.y);
if(mirror)
p.y = -p.y;
- p = basep.pos+trans.transform(offset+p);
+ p = basep.position+trans.transform(offset+p);
Vector n(0, -v.normal.x, v.normal.y);
if(mirror)
const vector<TrackPart> &parts = type.get_parts();
for(vector<TrackPart>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
{
- TrackPoint start = i->get_point(0);
- TrackPoint end = i->get_point(i->get_length());
+ OrientedPoint start = i->get_point(0);
+ OrientedPoint end = i->get_point(i->get_length());
if(i->is_curved())
{
xmlpp::Element *elem = group.add_child("path");
elem->set_attribute("class", "rail");
- Vector delta1 = rotated_vector(Vector(0, (gauge+rail_width)*0.5, 0), start.dir);
- Vector delta2 = rotated_vector(Vector(0, (gauge+rail_width)*0.5, 0), end.dir);
+ Vector delta1 = rotated_vector(Vector(0, (gauge+rail_width)*0.5, 0), start.rotation);
+ Vector delta2 = rotated_vector(Vector(0, (gauge+rail_width)*0.5, 0), end.rotation);
// Largely an educated guess, but seems to be accurate enough
float clen = i->get_length()*1000/2.9;
- Vector ctrl1 = rotated_vector(Vector(clen, 0, 0), start.dir);
- Vector ctrl2 = rotated_vector(Vector(clen, 0, 0), end.dir);
+ Vector ctrl1 = rotated_vector(Vector(clen, 0, 0), start.rotation);
+ Vector ctrl2 = rotated_vector(Vector(clen, 0, 0), end.rotation);
string data = format("M %.3f %.3f C %.3f %.3f %.3f %.3f %.3f %.3f")
- (start.pos.x*1000+delta1.x)(-start.pos.y*1000-delta1.y)
- (start.pos.x*1000+delta1.x+ctrl1.x)(-start.pos.y*1000-delta1.y-ctrl1.y)
- (end.pos.x*1000+delta2.x-ctrl2.x)(-end.pos.y*1000-delta2.y+ctrl2.y)
- (end.pos.x*1000+delta2.x)(-end.pos.y*1000-delta2.y).str();
+ (start.position.x*1000+delta1.x)(-start.position.y*1000-delta1.y)
+ (start.position.x*1000+delta1.x+ctrl1.x)(-start.position.y*1000-delta1.y-ctrl1.y)
+ (end.position.x*1000+delta2.x-ctrl2.x)(-end.position.y*1000-delta2.y+ctrl2.y)
+ (end.position.x*1000+delta2.x)(-end.position.y*1000-delta2.y).str();
data += format(" M %.3f %.3f C %.3f %.3f %.3f %.3f %.3f %.3f")
- (start.pos.x*1000-delta1.x)(-start.pos.y*1000+delta1.y)
- (start.pos.x*1000-delta1.x+ctrl1.x)(-start.pos.y*1000+delta1.y-ctrl1.y)
- (end.pos.x*1000-delta2.x-ctrl2.x)(-end.pos.y*1000+delta2.y+ctrl2.y)
- (end.pos.x*1000-delta2.x)(-end.pos.y*1000+delta2.y).str();
+ (start.position.x*1000-delta1.x)(-start.position.y*1000+delta1.y)
+ (start.position.x*1000-delta1.x+ctrl1.x)(-start.position.y*1000+delta1.y-ctrl1.y)
+ (end.position.x*1000-delta2.x-ctrl2.x)(-end.position.y*1000+delta2.y+ctrl2.y)
+ (end.position.x*1000-delta2.x)(-end.position.y*1000+delta2.y).str();
elem->set_attribute("d", data);
}
else
xmlpp::Element *elem = group.add_child("path");
elem->set_attribute("class", "rail");
- Vector delta = rotated_vector(Vector(0, (gauge+rail_width)*0.5, 0), start.dir);
+ Vector delta = rotated_vector(Vector(0, (gauge+rail_width)*0.5, 0), start.rotation);
string data = format("M %.3f %.3f L %.3f %.3f",
- start.pos.x*1000+delta.x, -start.pos.y*1000-delta.y,
- end.pos.x*1000+delta.x, -end.pos.y*1000-delta.y);
+ start.position.x*1000+delta.x, -start.position.y*1000-delta.y,
+ end.position.x*1000+delta.x, -end.position.y*1000-delta.y);
data += format(" M %.3f %.3f L %.3f %.3f",
- start.pos.x*1000-delta.x, -start.pos.y*1000+delta.y,
- end.pos.x*1000-delta.x, -end.pos.y*1000+delta.y);
+ start.position.x*1000-delta.x, -start.position.y*1000+delta.y,
+ end.position.x*1000-delta.x, -end.position.y*1000+delta.y);
elem->set_attribute("d", data);
}
}
- TrackPoint label_pt = parts.front().get_point(parts.front().get_length()/2);
+ OrientedPoint label_pt = parts.front().get_point(parts.front().get_length()/2);
- label_pt.dir.wrap_with_base(-Angle::quarter_turn());
- if(label_pt.dir>Angle::quarter_turn())
- label_pt.dir -= Angle::half_turn();
+ label_pt.rotation.wrap_with_base(-Angle::quarter_turn());
+ if(label_pt.rotation>Angle::quarter_turn())
+ label_pt.rotation -= Angle::half_turn();
- label_pt.pos *= 1000;
- label_pt.pos += rotated_vector(Vector(0, -gauge*0.25, 0), label_pt.dir);
+ label_pt.position *= 1000;
+ label_pt.position += rotated_vector(Vector(0, -gauge*0.25, 0), label_pt.rotation);
xmlpp::Element *elem = group.add_child("text");
elem->set_attribute("class", "artnr");
elem->set_attribute("transform", format("translate(%.3f %.3f) rotate(%.3f)",
- label_pt.pos.x, -label_pt.pos.y, -label_pt.dir.degrees()));
+ label_pt.position.x, -label_pt.position.y, -label_pt.rotation.degrees()));
elem->set_child_text(track.get_type().get_article_number().str());
}
if(track)
{
- TrackPoint tp = track.point();
- position = tp.pos;
- rotation = tp.dir;
+ OrientedPoint p = track.point();
+ position = p.position;
+ rotation = p.rotation;
}
}
const vector<TrackPart> &parts = type.get_parts();
for(vector<TrackPart>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
{
- TrackPoint start = i->get_point(0);
- TrackPoint end = i->get_point(i->get_length());
- if(abs(end.dir-start.dir).radians()<0.01)
+ OrientedPoint start = i->get_point(0);
+ OrientedPoint end = i->get_point(i->get_length());
+ if(abs(end.rotation-start.rotation).radians()<0.01)
{
- (end.dir>start.dir ? left : right) = true;
+ (end.rotation>start.rotation ? left : right) = true;
straight &= ~(1<<i->get_path());
}
- else if(abs(start.dir).radians()>0.01)
+ else if(abs(start.rotation).radians()>0.01)
cross = true;
}
typedef Msp::Geometry::Ray<float, 3> Ray;
typedef Msp::Geometry::BoundingBox<float, 3> BoundingBox;
-struct TrackPoint
+struct OrientedPoint
{
- Vector pos;
- Angle dir;
- float grade;
-
- TrackPoint(): grade(0) { }
+ Vector position;
+ Angle rotation;
+ Angle tilt;
};
} // namespace R2C2
layout.get_driver().set_turnout(turnout_id, p);
}
-TrackPoint Track::get_point(unsigned epi, unsigned path, float d) const
+OrientedPoint Track::get_point(unsigned epi, unsigned path, float d) const
{
- TrackPoint p = type.get_point(epi, path, d);
+ OrientedPoint p = type.get_point(epi, path, d);
- p.pos = position+rotated_vector(p.pos, rotation);
- p.dir += rotation;
+ p.position = position+rotated_vector(p.position, rotation);
+ p.rotation += rotation;
if(type.get_endpoints().size()==2)
{
- float grade = tan(tilt);
+ float dz = tan(tilt)*d;
if(epi==0)
{
- p.pos.z += grade*d;
- p.grade = grade;
+ p.position.z += dz;
+ p.tilt = tilt;
}
else
{
- p.pos.z += slope-grade*d;
- p.grade = -grade;
+ p.position.z += slope-dz;
+ p.tilt = -tilt;
}
}
return p;
}
-TrackPoint Track::get_point(unsigned epi, float d) const
+OrientedPoint Track::get_point(unsigned epi, float d) const
{
return get_point(epi, active_path, d);
}
{
Vector local = rotated_vector(sn.position-position, -rotation);
- TrackPoint tp = type.get_nearest_point(local);
- Vector span = local-tp.pos;
+ OrientedPoint np = type.get_nearest_point(local);
+ Vector span = local-np.position;
if(dot(span, span)<=limit*limit)
{
- sn.position = position+rotated_vector(tp.pos, rotation);
- sn.rotation = tp.dir+rotation;
+ sn.position = position+rotated_vector(np.position, rotation);
+ sn.rotation = np.rotation+rotation;
return true;
}
}
unsigned get_active_path() const { return active_path; }
bool is_path_changing() const { return path_changing; }
- TrackPoint get_point(unsigned, unsigned, float) const;
- TrackPoint get_point(unsigned, float) const;
+ OrientedPoint get_point(unsigned, unsigned, float) const;
+ OrientedPoint get_point(unsigned, float) const;
virtual unsigned get_n_snap_nodes() const;
virtual Snap get_snap_node(unsigned) const;
float offs = min(dist, trk->get_type().get_path_length(0));
while(1)
{
- TrackPoint tp = trk->get_point(trk.entry(), offs);
- float diff = dist-distance(epp, tp.pos);
+ OrientedPoint p = trk->get_point(trk.entry(), offs);
+ float diff = dist-distance(epp, p.position);
if(abs(diff)<margin)
break;
offs += diff;
return _track.block_iter();
}
-TrackPoint TrackOffsetIter::point() const
+OrientedPoint TrackOffsetIter::point() const
{
if(!_track)
- return TrackPoint();
+ return OrientedPoint();
if(_path>=0)
return _track->get_point(_track.entry(), _path, _offset);
BlockIter block_iter() const;
float offset() const { return _offset; }
- TrackPoint point() const;
+ OrientedPoint point() const;
TrackOffsetIter next() const;
TrackOffsetIter next(unsigned) const;
return length;
}
-TrackPoint TrackPart::get_point(float d) const
+OrientedPoint TrackPart::get_point(float d) const
{
- TrackPoint result;
+ OrientedPoint result;
Transform dir_trans = Transform::rotation(dir, Vector(0, 0, 1));
if(radius)
{
Angle a = Angle::from_radians(d/radius);
Vector r = dir_trans.transform(Vector(0, -radius, 0));
- result.pos = pos-r+Transform::rotation(a, Vector(0, 0, 1)).transform(r);
- result.dir = dir+a;
+ result.position = pos-r+Transform::rotation(a, Vector(0, 0, 1)).transform(r);
+ result.rotation = dir+a;
}
else
{
- result.pos = pos+dir_trans.transform(Vector(d, 0, 0));
- result.dir = dir;
+ result.position = pos+dir_trans.transform(Vector(d, 0, 0));
+ result.rotation = dir;
}
return result;
}
-TrackPoint TrackPart::get_nearest_point(const Vector &p) const
+OrientedPoint TrackPart::get_nearest_point(const Vector &p) const
{
- TrackPoint tp;
+ OrientedPoint result;
Transform dir_trans = Transform::rotation(dir, Vector(0, 0, 1));
if(radius)
{
a = min(max(a, Angle::zero()), Angle::from_radians(length));
if(radius<0)
a = -a;
- tp.pos = pos-r+Transform::rotation(a, Vector(0, 0, 1)).transform(r);
- tp.dir = dir+a;
+ result.position = pos-r+Transform::rotation(a, Vector(0, 0, 1)).transform(r);
+ result.rotation = dir+a;
}
else
{
Vector v = p-pos;
Vector dir_vec = dir_trans.transform(Vector(1, 0, 0));
float d = min(max(dot(dir_vec, v), 0.0f), length);
- tp.pos = pos+dir_vec*d;
- tp.dir = dir;
+ result.position = pos+dir_vec*d;
+ result.rotation = dir;
}
- return tp;
+ return result;
}
void TrackPart::check_link(TrackPart &other)
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);
+ OrientedPoint 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);
+ OrientedPoint p2 = other.get_point(j ? other.get_length() : 0);
- Vector span = p2.pos-p1.pos;
+ Vector span = p2.position-p1.position;
- Angle da = wrap_balanced(p2.dir-p1.dir+Angle::half_turn()*float((i+j+1)%2));
+ Angle da = wrap_balanced(p2.rotation-p1.rotation+Angle::half_turn()*float((i+j+1)%2));
if(dot(span, span)<1e-6 && abs(da).radians()<=0.01)
{
float get_length() const;
bool is_curved() const { return radius; }
- TrackPoint get_point(float) const;
- TrackPoint get_nearest_point(const Vector &) const;
+ OrientedPoint get_point(float) const;
+ OrientedPoint get_nearest_point(const Vector &) const;
unsigned get_path() const { return path; }
bool is_dead_end() const { return dead_end; }
void check_link(TrackPart &);
return endpoints[i];
}
-TrackPoint TrackType::get_point(unsigned epi, unsigned path, float d) const
+OrientedPoint TrackType::get_point(unsigned epi, unsigned path, float d) const
{
if(epi>=endpoints.size())
throw out_of_range("TrackType::get_point");
unsigned n_part_eps = (i->is_dead_end() ? 1 : 2);
for(unsigned j=0; j<n_part_eps; ++j)
{
- TrackPoint p = i->get_point(j ? i->get_length() : 0);
- Vector span = p.pos-endpoints[epi].pos;
+ OrientedPoint p = i->get_point(j ? i->get_length() : 0);
+ Vector span = p.position-endpoints[epi].pos;
if(dot(span, span)<1e-6)
{
part = &*i;
{
if(part_ep==1)
d = plen-d;
- TrackPoint p = part->get_point(d);
+ OrientedPoint p = part->get_point(d);
if(part_ep==1)
- p.dir += Angle::half_turn();
+ p.rotation += Angle::half_turn();
return p;
}
else
}
}
-TrackPoint TrackType::get_nearest_point(const Vector &p) const
+OrientedPoint TrackType::get_nearest_point(const Vector &p) const
{
- TrackPoint result;
+ OrientedPoint result;
float dist = -1;
for(vector<TrackPart>::const_iterator i=parts.begin(); i!=parts.end(); ++i)
{
- TrackPoint n = i->get_nearest_point(p);
- float d = distance(n.pos, p);
+ OrientedPoint n = i->get_nearest_point(p);
+ float d = distance(n.position, p);
if(d<dist || dist<0)
{
result = n;
for(unsigned j=0; j<n_part_eps; ++j)
if(!i->get_link(j))
{
- TrackPoint p = i->get_point(j ? i->get_length() : 0);
+ OrientedPoint p = i->get_point(j ? i->get_length() : 0);
if(j==0)
- p.dir += Angle::half_turn();
+ p.rotation += Angle::half_turn();
bool found = false;
for(vector<Endpoint>::iterator k=endpoints.begin(); k!=endpoints.end(); ++k)
{
- Vector d = k->pos-p.pos;
+ Vector d = k->pos-p.position;
- Angle da = wrap_balanced(k->dir-p.dir);
+ Angle da = wrap_balanced(k->dir-p.rotation);
if(dot(d, d)<1e-6 && abs(da).radians()<0.01)
{
}
if(!found)
- endpoints.push_back(Endpoint(p.pos.x, p.pos.y, p.dir, 1<<i->get_path()));
+ endpoints.push_back(Endpoint(p.position.x, p.position.y, p.rotation, 1<<i->get_path()));
}
}
}
const std::vector<TrackPart> &get_parts() const { return parts; }
const std::vector<Endpoint> &get_endpoints() const { return endpoints; }
const Endpoint &get_endpoint(unsigned) const;
- TrackPoint get_point(unsigned, unsigned, float) const;
- TrackPoint get_nearest_point(const Vector &) const;
+ OrientedPoint get_point(unsigned, unsigned, float) const;
+ OrientedPoint get_nearest_point(const Vector &) const;
private:
void collect_endpoints();
void Vehicle::update_position()
{
- TrackPoint tp;
+ OrientedPoint p;
if(axles.size()>=2)
{
float wheelbase = axles.front().type->position-axles.back().type->position;
- tp = get_point(track, wheelbase, -axles.back().type->position/wheelbase);
+ p = get_point(track, wheelbase, -axles.back().type->position/wheelbase);
}
else if(bogies.size()>=2)
{
const vector<Axle> &front_axles = bogies.front().axles;
float wheelbase = front_axles.front().type->position-front_axles.back().type->position;
- TrackPoint front_point = get_point(front, wheelbase, -front_axles.back().type->position/wheelbase);
+ OrientedPoint front_point = get_point(front, wheelbase, -front_axles.back().type->position/wheelbase);
const vector<Axle> &back_axles = bogies.back().axles;
wheelbase = back_axles.front().type->position-back_axles.back().type->position;
- TrackPoint back_point = get_point(back, wheelbase, -back_axles.back().type->position/wheelbase);
+ OrientedPoint back_point = get_point(back, wheelbase, -back_axles.back().type->position/wheelbase);
- tp = get_point(front_point.pos, back_point.pos, -bogies.back().type->position/bogie_spacing);
+ p = get_point(front_point.position, back_point.position, -bogies.back().type->position/bogie_spacing);
- bogies.front().direction = front_point.dir-tp.dir;
- bogies.back().direction = back_point.dir-tp.dir;
+ bogies.front().direction = front_point.rotation-p.rotation;
+ bogies.back().direction = back_point.rotation-p.rotation;
}
else
- tp = track.point();
+ p = track.point();
if(!prev)
check_sensor(type.get_front_axle_offset(), front_sensor);
if(!next)
check_sensor(type.get_back_axle_offset(), back_sensor);
- position = tp.pos;
+ position = p.position;
position.z += layout.get_catalogue().get_rail_elevation();
- rotation = tp.dir;
+ rotation = p.rotation;
signal_moved.emit();
}
int adjust_dir = 0;
while(1)
{
- Vector front_point = front.point().pos;
- Vector back_point = back.point().pos;
+ Vector front_point = front.point().position;
+ Vector back_point = back.point().position;
float dist = distance(front_point, back_point);
}
}
-TrackPoint Vehicle::get_point(const Vector &front, const Vector &back, float ratio) const
+OrientedPoint Vehicle::get_point(const Vector &front, const Vector &back, float ratio) const
{
Vector span = front-back;
- TrackPoint tp;
- tp.pos = back+span*ratio;
- tp.dir = Geometry::atan2(span.y, span.x);
+ OrientedPoint p;
+ p.position = back+span*ratio;
+ p.rotation = Geometry::atan2(span.y, span.x);
- return tp;
+ return p;
}
-TrackPoint Vehicle::get_point(const TrackOffsetIter &iter, float tdist, float ratio) const
+OrientedPoint Vehicle::get_point(const TrackOffsetIter &iter, float tdist, float ratio) const
{
TrackOffsetIter front = iter.advance(tdist*(1-ratio));
TrackOffsetIter back = iter.advance(-tdist*ratio);
adjust_for_distance(front, back, tdist, ratio);
- return get_point(front.point().pos, back.point().pos, ratio);
+ return get_point(front.point().position, back.point().position, ratio);
}
unsigned Vehicle::get_n_link_slots() const
void update_rods();
void adjust_for_distance(TrackOffsetIter &, TrackOffsetIter &, float, float = 0.5) const;
- TrackPoint get_point(const Vector &, const Vector &, float = 0.5) const;
- TrackPoint get_point(const TrackOffsetIter &, float, float = 0.5) const;
+ OrientedPoint get_point(const Vector &, const Vector &, float = 0.5) const;
+ OrientedPoint get_point(const TrackOffsetIter &, float, float = 0.5) const;
public:
virtual unsigned get_n_link_slots() const;