1 // Vamos Automotive Simulator 2 // Copyright (C) 2001--2004 Sam Varner 3 // 4 // This program is free software; you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation; either version 2 of the License, or 7 // (at your option) any later version. 8 // 9 // This program is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with this program; if not, write to the Free Software 16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 18 #ifndef _SPLINE_H_ 19 #define _SPLINE_H_ 20 21 #include "Interpolator.h" 22 #include "Three_Vector.h" 23 #include "Two_Vector.h" 24 25 #include <vector> 26 27 namespace Vamos_Geometry 28 { 29 class Spline : public Interpolator 30 { 31 public: 32 // Construct an empty curve. 33 Spline (); 34 Spline (double first_slope, double last_slope); 35 36 // Construct a cuvre from an array of points. 37 Spline (const std::vector <Two_Vector>& points); 38 Spline (const std::vector <Two_Vector>& points, 39 double first_slope, 40 double last_slope); 41 42 // Add a point to the curve. 43 virtual void load (const Two_Vector& point); load(double x,double y)44 virtual void load (double x, double y) { load (Two_Vector (x, y)); } 45 46 // Add multiple points to the curve. 47 virtual void load (const std::vector <Two_Vector>& points); 48 49 // Replace all points on the curve. replace(const std::vector<Two_Vector> & points)50 virtual void replace (const std::vector <Two_Vector>& points) 51 { 52 clear (); 53 load (points); 54 } 55 56 // Remove all points from the curve. 57 virtual void clear (); 58 59 void set_periodic (double period_end); 60 61 // Remove points with x > LIMIT. 62 virtual void remove_greater (double limit); 63 64 // Scale all of the x values by FACTOR. 65 virtual void scale (double factor); 66 67 // Return the y value at the x value DIST 68 virtual double interpolate (double dist) const; 69 70 double slope (double distance) const; 71 72 double second_derivative (double distance) const; 73 74 // Return the normal to the tanget at DIST. 75 virtual Two_Vector normal (double dist) const; 76 77 // Add 'delta' to all points. 78 virtual void shift (double delta); 79 80 // Return the number of control points. size()81 virtual size_t size () const { return m_points.size (); } 82 83 virtual Two_Vector& operator [] (size_t i) { return m_points [i]; } 84 virtual const Two_Vector& operator [] (size_t i) const { return m_points [i]; } 85 86 private: 87 // The array of calculated second derivatives. 88 mutable std::vector <double> m_second_deriv; 89 90 // The first derivative of the spline at the first point. 91 double m_first_slope; 92 bool m_first_slope_is_set; 93 94 // The first derivative of the spline at the last point. 95 double m_last_slope; 96 bool m_last_slope_is_set; 97 98 // True if the second derivatives have been calculated. 99 mutable bool m_calculated; 100 101 // The 1st and 2nd derivatives at the interpolated point 102 // calculated during the last call to interpolate(). 103 mutable double m_slope; 104 mutable double m_second_derivative; 105 106 // Calculate the coefficients for interpolation. 107 void calculate () const; 108 109 // The segment index from the previous interpolation. 110 mutable size_t m_last_index; 111 112 double m_period_end; 113 bool m_periodic; 114 115 void check (double* a, double* b, double* r) const; 116 }; 117 118 class Parametric_Spline 119 { 120 public: 121 Parametric_Spline (); 122 123 Parametric_Spline (double first_x_slope, double last_x_slope, 124 double first_y_slope, double last_y_slope); 125 126 // Add a point to the curve. 127 void load (double parameter, const Two_Vector& point); load(double parameter,double x,double y)128 void load (double parameter, double x, double y) 129 { load (parameter, Two_Vector (x, y)); } 130 131 // Remove all points from the curve. 132 void clear (); 133 134 void set_periodic (double period_end); 135 136 // Return the point at PARAMETER. 137 Two_Vector interpolate (double parameter) const; 138 139 // Return the number of control points. 140 size_t size () const; 141 142 Two_Vector operator [] (size_t i) const; 143 144 double parameter (size_t i) const; 145 146 private: 147 Spline m_x; 148 Spline m_y; 149 }; 150 151 class Vector_Spline 152 { 153 public: 154 Vector_Spline (); 155 Vector_Spline (double first_x_slope, double last_x_slope, 156 double first_y_slope, double last_y_slope, 157 double first_z_slope, double last_z_slope); 158 159 // Add a point to the curve. 160 void load (double parameter, const Vamos_Geometry::Three_Vector& point); load(double parameter,double x,double y,double z)161 void load (double parameter, double x, double y, double z) 162 { load (parameter, Three_Vector (x, y, z)); } 163 164 // Remove all points from the curve. 165 void clear (); 166 167 void set_periodic (double period_end); 168 169 // Return the point at PARAMETER. 170 Vamos_Geometry::Three_Vector interpolate (double parameter) const; 171 172 // Return the number of control points. 173 size_t size () const; 174 175 Vamos_Geometry::Three_Vector operator [] (size_t i) const; 176 177 double parameter (size_t i) const; 178 179 private: 180 Spline m_x; 181 Spline m_y; 182 Spline m_z; 183 }; 184 } 185 186 #endif 187