]> git.tdb.fi Git - r2c2.git/blobdiff - source/libr2c2/profile.cpp
Don't crash if a train has no router
[r2c2.git] / source / libr2c2 / profile.cpp
index b44ee3606c6018ccf9918e9d4b32cfe263c12488..907da8adf791fb12a068dc3a318e13dde108429b 100644 (file)
@@ -1,10 +1,3 @@
-/* $Id$
-
-This file is part of R²C²
-Copyright © 2010 Mikkosoft Productions, Mikko Rasa
-Distributed under the GPL
-*/
-
 #include <cmath>
 #include "profile.h"
 
@@ -13,10 +6,35 @@ using namespace Msp;
 
 namespace R2C2 {
 
-void Profile::append_point(const Point &p)
+void Profile::append_vertex(const Vector &p, bool smooth)
 {
-       points.push_back(p);
-       if(points.size()==1)
+       if(vertices.size()>1 && !vertices.back().smooth)
+               vertices.push_back(vertices.back());
+
+       Vertex v;
+       v.pos = p;
+       v.smooth = (!vertices.empty() && smooth);
+
+       if(!vertices.empty())
+       {
+               Vector span = p-vertices.back().pos;
+               span.normalize();
+               v.normal.x = span.y;
+               v.normal.y = -span.x;
+
+               if(vertices.back().smooth)
+               {
+                       Vector &n = vertices.back().normal;
+                       n += v.normal;
+                       n.normalize();
+               }
+               else
+                       vertices.back().normal = v.normal;
+       }
+
+       vertices.push_back(v);
+
+       if(vertices.size()==1)
        {
                min_coords = p;
                max_coords = p;
@@ -30,21 +48,11 @@ void Profile::append_point(const Point &p)
        }
 }
 
-const Point &Profile::get_point(unsigned i) const
-{
-       if(i>=points.size())
-               throw InvalidParameterValue("Index out of range");
-       return points[i];
-}
-
-Point Profile::get_edge_normal(unsigned i) const
+const Profile::Vertex &Profile::get_vertex(unsigned i) const
 {
-       if(i+1>=points.size())
-               throw InvalidParameterValue("Index out of range");
-       float dx = points[i+1].x-points[i].x;
-       float dy = points[i+1].y-points[i].y;
-       float len = sqrt(dx*dx+dy*dy);
-       return Point(dy/len, -dx/len);
+       if(i>=vertices.size())
+               throw out_of_range("Profile::get_vertex");
+       return vertices[i];
 }
 
 
@@ -52,11 +60,17 @@ Profile::Loader::Loader(Profile &p):
        DataFile::ObjectLoader<Profile>(p)
 {
        add("point", &Loader::point);
+       add("smooth_point", &Loader::smooth_point);
 }
 
 void Profile::Loader::point(float x, float y)
 {
-       obj.append_point(Point(x/1000, y/1000));
+       obj.append_vertex(Vector(x/1000, y/1000, 0), false);
+}
+
+void Profile::Loader::smooth_point(float x, float y)
+{
+       obj.append_vertex(Vector(x/1000, y/1000, 0), true);
 }
 
 } // namespace R2C2