From: Mikko Rasa Date: Thu, 4 Jul 2013 19:13:04 +0000 (+0300) Subject: Introduce a tilt (vertical angle) property to Object X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=107a7f787d406f1f664c4986557f9a896e0845ea;p=r2c2.git Introduce a tilt (vertical angle) property to Object --- diff --git a/source/3d/track.cpp b/source/3d/track.cpp index 9797c4a..92c1574 100644 --- a/source/3d/track.cpp +++ b/source/3d/track.cpp @@ -61,7 +61,7 @@ GL::Matrix Track3D::create_matrix() const GL::Matrix matrix; matrix.translate(track.get_position()); matrix.rotate(track.get_rotation(), 0, 0, 1); - matrix.rotate(track.get_slope()/track.get_type().get_total_length(), 0, -1, 0); + matrix.rotate(track.get_tilt(), 0, -1, 0); return matrix; } diff --git a/source/designer/designer.cpp b/source/designer/designer.cpp index 04e15d3..61f0d9c 100644 --- a/source/designer/designer.cpp +++ b/source/designer/designer.cpp @@ -643,9 +643,8 @@ string Designer::tooltip(int x, int y) string info = format("%d %s", otype.get_article_number(), otype.get_description()); if(Track *track = dynamic_cast(obj)) { - const TrackType &ttype = track->get_type(); - if(mode!=CATALOGUE && abs(track->get_slope())>1e-4) - info += format(" (slope %.1f%%)", abs(track->get_slope()/ttype.get_total_length()*100)); + if(mode!=CATALOGUE && abs(track->get_tilt()).radians()>1e-4) + info += format(" (slope %.1f%%)", abs(tan(track->get_tilt())*100)); if(track->get_turnout_id()) info += format(" (turnout %d)", track->get_turnout_id()); else if(track->get_sensor_id()) diff --git a/source/designer/manipulator.cpp b/source/designer/manipulator.cpp index ba27cae..b61d9a7 100644 --- a/source/designer/manipulator.cpp +++ b/source/designer/manipulator.cpp @@ -101,9 +101,9 @@ void Manipulator::flatten() float z = 0; for(vector::iterator i=objects.begin(); i!=objects.end(); ++i) { - z += i->object->get_position().z; - if(Track *track = dynamic_cast(i->object)) - z += track->get_slope()/2; + unsigned nsn = i->object->get_n_snap_nodes(); + for(unsigned j=0; jobject->get_snap_node(j).position.z/nsn; } z /= static_cast(objects.size()); @@ -112,7 +112,7 @@ void Manipulator::flatten() Vector p = i->object->get_position(); i->object->set_position(Vector(p.x, p.y, z)); if(Track *track = dynamic_cast(i->object)) - track->set_slope(0); + track->set_tilt(Angle::zero()); } update_objects(); @@ -177,27 +177,26 @@ void Manipulator::even_slope(bool smooth) while((end_z-start_z)*dir/total_len>cur_slope+0.025 && order.size()>2) { cur_slope += 0.025; + Angle tilt = Geometry::atan(cur_slope); + + set_slope(order.front(), start_z, tilt); + start_z += order.front().track->get_type().get_path_length(0)*dir*cur_slope; + total_len -= order.front().track->get_type().get_path_length(0); + order.pop_front(); - float dz = order.front().track->get_type().get_total_length()*dir*cur_slope; - set_slope(order.front(), start_z, dz); - start_z += dz; - total_len -= order.front().track->get_type().get_total_length(); - order.erase(order.begin()); - - dz = order.back().track->get_type().get_total_length()*dir*cur_slope; - set_slope(order.back(), end_z-dz, dz); - end_z -= dz; - total_len -= order.back().track->get_type().get_total_length(); - order.erase(--order.end()); + end_z -= order.back().track->get_type().get_path_length(0)*dir*cur_slope; + set_slope(order.back(), end_z, tilt); + total_len -= order.back().track->get_type().get_path_length(0); + order.pop_back(); } } float cur_z = start_z; + Angle tilt = Geometry::atan((end_z-start_z)/total_len); for(list::iterator i=order.begin(); i!=order.end(); ++i) { - float dz = i->track->get_type().get_total_length()*(end_z-start_z)/total_len; - set_slope(*i, cur_z, dz); - cur_z += dz; + set_slope(*i, cur_z, tilt); + cur_z += i->track->get_type().get_path_length(0)*(end_z-start_z)/total_len; } update_objects(); @@ -544,18 +543,19 @@ void Manipulator::update_neighbors() } } -void Manipulator::set_slope(TrackOrder &track, float z, float dz) +void Manipulator::set_slope(TrackOrder &track, float z, const Angle &tilt) { const Vector &p = track.track->get_position(); + float dz = tan(tilt)*track.track->get_type().get_path_length(0); if(track.rev) { track.track->set_position(Vector(p.x, p.y, z+dz)); - track.track->set_slope(-dz); + track.track->set_tilt(-tilt); } else { track.track->set_position(Vector(p.x, p.y, z)); - track.track->set_slope(dz); + track.track->set_tilt(tilt); } } diff --git a/source/designer/manipulator.h b/source/designer/manipulator.h index 1c46af6..d39735f 100644 --- a/source/designer/manipulator.h +++ b/source/designer/manipulator.h @@ -75,7 +75,7 @@ private: void selection_changed(); void update_objects(); void update_neighbors(); - void set_slope(TrackOrder &, float, float); + void set_slope(TrackOrder &, float, const R2C2::Angle &); std::vector create_straight(const R2C2::Vector &, const R2C2::Angle &, float, float); }; diff --git a/source/libr2c2/object.h b/source/libr2c2/object.h index 31eb879..c346b6d 100644 --- a/source/libr2c2/object.h +++ b/source/libr2c2/object.h @@ -15,6 +15,7 @@ protected: Layout &layout; Vector position; Angle rotation; + Angle tilt; Object(Layout &l): layout(l) { } public: @@ -25,8 +26,10 @@ public: Layout &get_layout() const { return layout; } virtual void set_position(const Vector &) = 0; virtual void set_rotation(const Angle &) = 0; + virtual void set_tilt(const Angle &) = 0; const Vector &get_position() const { return position; } const Angle &get_rotation() const { return rotation; } + const Angle &get_tilt() const { return tilt; } virtual Object *get_parent() const { return 0; } virtual unsigned get_n_snap_nodes() const { return 0; } diff --git a/source/libr2c2/signal.h b/source/libr2c2/signal.h index 73f4bb3..2f77f06 100644 --- a/source/libr2c2/signal.h +++ b/source/libr2c2/signal.h @@ -49,6 +49,7 @@ public: void set_address(unsigned); virtual void set_position(const Vector &); virtual void set_rotation(const Angle &); + virtual void set_tilt(const Angle &) { } private: void update_location(); public: diff --git a/source/libr2c2/track.cpp b/source/libr2c2/track.cpp index 71c570c..697e678 100644 --- a/source/libr2c2/track.cpp +++ b/source/libr2c2/track.cpp @@ -69,9 +69,7 @@ Block &Track::get_block() const void Track::set_position(const Vector &p) { position = p; - for(vector::const_iterator i=links.begin(); i!=links.end(); ++i) - if(*i) - (*i)->check_slope(); + propagate_slope(); } void Track::set_rotation(const Angle &r) @@ -79,12 +77,14 @@ void Track::set_rotation(const Angle &r) rotation = wrap_positive(r); } -void Track::set_slope(float s) +void Track::set_tilt(const Angle &t) { if(links.size()!=2) return; - slope = s; + tilt = t; + slope = tan(tilt)*type.get_path_length(0); + propagate_slope(); } void Track::set_flex(bool f) @@ -92,6 +92,13 @@ void Track::set_flex(bool f) flex = f; } +void Track::propagate_slope() +{ + for(vector::const_iterator i=links.begin(); i!=links.end(); ++i) + if(*i) + (*i)->check_slope(); +} + void Track::check_slope() { if(links.size()!=2) @@ -103,6 +110,7 @@ void Track::check_slope() Vector epp1 = links[1]->get_snap_node(links[1]->get_link_slot(*this)).position; position.z = epp0.z; slope = epp1.z-position.z; + tilt = Geometry::atan(slope/type.get_path_length(0)); } else { @@ -164,8 +172,7 @@ TrackPoint Track::get_point(unsigned epi, unsigned path, float d) const p.dir += rotation; if(type.get_endpoints().size()==2) { - float len = type.get_path_length(path); - float grade = slope/len; + float grade = tan(tilt); if(epi==0) { p.pos.z += grade*d; @@ -323,7 +330,7 @@ void Track::save(list &st) const { st.push_back((DataFile::Statement("position"), position.x, position.y, position.z)); st.push_back((DataFile::Statement("rotation"), rotation.radians())); - st.push_back((DataFile::Statement("slope"), slope)); + st.push_back((DataFile::Statement("tilt"), tilt.radians())); if(turnout_id) st.push_back((DataFile::Statement("turnout_id"), turnout_id)); if(sensor_id) @@ -351,10 +358,13 @@ Track::Loader::Loader(Track &t): { add("position", &Loader::position); add("rotation", &Loader::rotation); - add("slope", &Track::slope); + add("tilt", &Loader::tilt); add("turnout_id", &Loader::turnout_id); add("sensor_id", &Loader::sensor_id); add("flex", &Track::flex); + + // deprecated + add("slope", &Loader::slope); } void Track::Loader::position(float x, float y, float z) @@ -372,6 +382,20 @@ void Track::Loader::sensor_id(unsigned id) obj.set_sensor_id(id); } +void Track::Loader::slope(float s) +{ + tilt(atan(s/obj.type.get_path_length(0))); +} + +void Track::Loader::tilt(float t) +{ + if(obj.links.size()!=2) + return; + + obj.tilt = Angle::from_radians(t); + obj.slope = tan(t)*obj.type.get_path_length(0); +} + void Track::Loader::turnout_id(unsigned id) { obj.set_turnout_id(id); diff --git a/source/libr2c2/track.h b/source/libr2c2/track.h index e1349a1..916ea19 100644 --- a/source/libr2c2/track.h +++ b/source/libr2c2/track.h @@ -25,6 +25,8 @@ public: void position(float, float, float); void rotation(float); void sensor_id(unsigned); + void slope(float); + void tilt(float); void turnout_id(unsigned); }; @@ -56,11 +58,11 @@ public: Block &get_block() const; virtual void set_position(const Vector &); virtual void set_rotation(const Angle &); - void set_slope(float); + virtual void set_tilt(const Angle &); void set_flex(bool); - float get_slope() const { return slope; } bool get_flex() const { return flex; } private: + void propagate_slope(); void check_slope(); public: diff --git a/source/libr2c2/vehicle.h b/source/libr2c2/vehicle.h index 616ad36..94ae2b1 100644 --- a/source/libr2c2/vehicle.h +++ b/source/libr2c2/vehicle.h @@ -99,6 +99,7 @@ public: // TODO implement these - should call place() with suitable parameters virtual void set_position(const Vector &) { } virtual void set_rotation(const Angle &) { } + virtual void set_tilt(const Angle &) { } void place(const TrackIter &, float, PlaceMode = CENTER); void unplace(); void advance(float);