]> git.tdb.fi Git - r2c2.git/commitdiff
Introduce a tilt (vertical angle) property to Object
authorMikko Rasa <tdb@tdb.fi>
Thu, 4 Jul 2013 19:13:04 +0000 (22:13 +0300)
committerMikko Rasa <tdb@tdb.fi>
Thu, 4 Jul 2013 19:13:04 +0000 (22:13 +0300)
source/3d/track.cpp
source/designer/designer.cpp
source/designer/manipulator.cpp
source/designer/manipulator.h
source/libr2c2/object.h
source/libr2c2/signal.h
source/libr2c2/track.cpp
source/libr2c2/track.h
source/libr2c2/vehicle.h

index 9797c4a67369c90a7e6d05b07495171fd7afdcfe..92c15744e42f23fba386287146fa9a81336206e5 100644 (file)
@@ -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;
 }
index 04e15d34c5e5a023d0b3cc514c70f8faff95f800..61f0d9c00fb495ca08b98ec6654858a2c550d0b4 100644 (file)
@@ -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<Track *>(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())
index ba27cae58fd88906cb3d620e75568b234ac799b7..b61d9a7ae5e28642344554f01b001f9887480c12 100644 (file)
@@ -101,9 +101,9 @@ void Manipulator::flatten()
        float z = 0;
        for(vector<MObject>::iterator i=objects.begin(); i!=objects.end(); ++i)
        {
-               z += i->object->get_position().z;
-               if(Track *track = dynamic_cast<Track *>(i->object))
-                       z += track->get_slope()/2;
+               unsigned nsn = i->object->get_n_snap_nodes();
+               for(unsigned j=0; j<nsn; ++j)
+                       z += i->object->get_snap_node(j).position.z/nsn;
        }
        z /= static_cast<int>(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<Track *>(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<TrackOrder>::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);
        }
 }
 
index 1c46af6b6fd4c4eeae53bd197c87a198723f9acc..d39735fb86fedf40a2e561b838a269a45741d84d 100644 (file)
@@ -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<R2C2::Track *> create_straight(const R2C2::Vector &, const R2C2::Angle &, float, float);
 };
 
index 31eb879228d0076fa0bc47dad32b6ce01567ebca..c346b6de0c9b010199d11dd95bd9b9921e215934 100644 (file)
@@ -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; }
index 73f4bb34098f9356fb9a6ab5dee6eae75cc39b66..2f77f0627b11ec8ba46d82f6f8382ab73cd93c56 100644 (file)
@@ -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:
index 71c570cee86ccd251d6269c080b1c619bac18054..697e67843080ec68fba6898e3ad3eae81d3d60d4 100644 (file)
@@ -69,9 +69,7 @@ Block &Track::get_block() const
 void Track::set_position(const Vector &p)
 {
        position = p;
-       for(vector<Track *>::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<Track *>::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<DataFile::Statement> &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);
index e1349a1ff8be919f7fced788ce823227dfa7f4c0..916ea1966183c8ce5a87ec97a0c2297570a29c4a 100644 (file)
@@ -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:
index 616ad366d2de5ce2973a48848e2e33fb2d169719..94ae2b1683e648cc8f07cb9edfc1ff56d107ecdf 100644 (file)
@@ -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);