00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef _GMTL_PARAMETRIC_CURVE_H_
00019 #define _GMTL_PARAMETRIC_CURVE_H_
00020
00021 #include <gmtl/Matrix.h>
00022 #include <gmtl/MatrixOps.h>
00023 #include <gmtl/Vec.h>
00024 #include <gmtl/VecOps.h>
00025
00026 namespace gmtl
00027 {
00028
00039 template<typename DATA_TYPE, unsigned SIZE, unsigned ORDER>
00040 class ParametricCurve
00041 {
00042 public:
00043 ParametricCurve();
00044 ParametricCurve(const ParametricCurve& other);
00045 ~ParametricCurve();
00046 ParametricCurve& operator=(const ParametricCurve& other);
00047
00048 void setWeights(DATA_TYPE weights[ORDER]);
00049 void setControlPoints(Vec<DATA_TYPE, SIZE> control_points[ORDER]);
00050 void setBasisMatrix(const Matrix<DATA_TYPE, ORDER, ORDER>& basis_matrix);
00051 Vec<DATA_TYPE, SIZE> getInterpolatedValue(DATA_TYPE value) const;
00052 Vec<DATA_TYPE, SIZE> getInterpolatedDerivative(DATA_TYPE value) const;
00053
00054 protected:
00055 DATA_TYPE mWeights[ORDER];
00056 Vec<DATA_TYPE, SIZE> mControlPoints[ORDER];
00057 Matrix<DATA_TYPE, ORDER, ORDER> mBasisMatrix;
00058 };
00059
00060 template<typename DATA_TYPE, unsigned SIZE, unsigned ORDER>
00061 ParametricCurve<DATA_TYPE, SIZE, ORDER>::ParametricCurve()
00062 {
00063 for (unsigned int i = 0; i < ORDER; ++i)
00064 {
00065 mWeights[i] = (DATA_TYPE)1.0;
00066 }
00067 }
00068
00069 template<typename DATA_TYPE, unsigned SIZE, unsigned ORDER>
00070 ParametricCurve<DATA_TYPE, SIZE, ORDER>::
00071 ParametricCurve(const ParametricCurve<DATA_TYPE, SIZE, ORDER>& other)
00072 {
00073 *this = other;
00074 }
00075
00076 template<typename DATA_TYPE, unsigned SIZE, unsigned ORDER>
00077 ParametricCurve<DATA_TYPE, SIZE, ORDER>::~ParametricCurve()
00078 {
00079 }
00080
00081 template<typename DATA_TYPE, unsigned SIZE, unsigned ORDER>
00082 ParametricCurve<DATA_TYPE, SIZE, ORDER>& ParametricCurve<DATA_TYPE, SIZE,
00083 ORDER>::operator=(const ParametricCurve<DATA_TYPE, SIZE, ORDER>& other)
00084 {
00085 for (unsigned int i = 0; i < ORDER; ++i)
00086 {
00087 mWeights[i] = other.mWeights[i];
00088 mControlPoints[i] = other.mControlPoints[i];
00089 }
00090
00091 mBasisMatrix = other.mBasisMatrix;
00092
00093 return *this;
00094 }
00095
00096 template<typename DATA_TYPE, unsigned SIZE, unsigned ORDER>
00097 void ParametricCurve<DATA_TYPE, SIZE, ORDER>::
00098 setWeights(const DATA_TYPE weights[ORDER])
00099 {
00100 for (unsigned int i = 0; i < ORDER; ++i)
00101 {
00102 mWeights[i] = weights[i];
00103 }
00104 }
00105
00106 template<typename DATA_TYPE, unsigned SIZE, unsigned ORDER>
00107 void ParametricCurve<DATA_TYPE, SIZE, ORDER>::
00108 setControlPoints(const Vec<DATA_TYPE, SIZE>& control_points[ORDER])
00109 {
00110 for (unsigned int i = 0; i < ORDER; ++i)
00111 {
00112 mControlPoints[i] = control_points[i];
00113 }
00114 }
00115
00116 template<typename DATA_TYPE, unsigned SIZE, unsigned ORDER>
00117 void ParametricCurve<DATA_TYPE, SIZE, ORDER>::
00118 setBasisMatrix(const Matrix<DATA_TYPE, ORDER, ORDER>& basis_matrix)
00119 {
00120 mBasisMatrix = basis_matrix;
00121 }
00122
00123 template<typename DATA_TYPE, unsigned SIZE, unsigned ORDER>
00124 Vec<DATA_TYPE, SIZE> ParametricCurve<DATA_TYPE, SIZE, ORDER>::
00125 getInterpolatedValue(const DATA_TYPE value) const
00126 {
00127 Vec<DATA_TYPE, SIZE> ret_vec;
00128 DATA_TYPE power_vector[ORDER];
00129 DATA_TYPE exponent;
00130 DATA_TYPE coefficient[ORDER];
00131
00132 for (unsigned int i = 0; i < ORDER; ++i)
00133 {
00134 exponent = (DATA_TYPE)(ORDER - i - 1);
00135 power_vector[i] = Math::pow(value, exponent);
00136 }
00137
00138 for (unsigned int column = 0; column < ORDER; ++column)
00139 {
00140 coefficient[column] = (DATA_TYPE)0.0;
00141
00142 for (unsigned int row = 0; row < ORDER; ++row)
00143 {
00144 coefficient[column] += power_vector[row] * mBasisMatrix[row][column];
00145 }
00146
00147 ret_vec += coefficient[column] * mWeights[column] * mControlPoints[column];
00148 }
00149
00150 return ret_vec;
00151 }
00152
00153 template<typename DATA_TYPE, unsigned SIZE, unsigned ORDER>
00154 Vec<DATA_TYPE, SIZE> ParametricCurve<DATA_TYPE, SIZE, ORDER>::
00155 getInterpolatedDerivative(const DATA_TYPE value) const
00156 {
00157 Vec<DATA_TYPE, SIZE> ret_vec;
00158 DATA_TYPE power_vector[ORDER];
00159 DATA_TYPE exponent;
00160 DATA_TYPE coefficient[ORDER];
00161
00162 for (unsigned int i = 0; i < ORDER; ++i)
00163 {
00164 exponent = static_cast<DATA_TYPE>(ORDER - i - 1);
00165
00166 if (exponent > 0)
00167 {
00168 power_vector[i] = exponent * Math::pow(value, exponent - 1);
00169 }
00170 else
00171 {
00172 power_vector[i] = (DATA_TYPE)0.0;
00173 }
00174 }
00175
00176 for (unsigned int column = 0; column < ORDER; ++column)
00177 {
00178 coefficient[column] = static_cast<DATA_TYPE>(0.0);
00179
00180 for (unsigned int row = 0; row < ORDER; ++row)
00181 {
00182 coefficient[column] += power_vector[row] * mBasisMatrix[row][column];
00183 }
00184
00185 ret_vec += coefficient[column] * mWeights[column] * mControlPoints[column];
00186 }
00187
00188 return ret_vec;
00189 }
00190
00197 template <typename DATA_TYPE, unsigned int SIZE>
00198 class LinearCurve : public ParametricCurve<DATA_TYPE, SIZE, 2>
00199 {
00200 public:
00201 LinearCurve();
00202 LinearCurve(const LinearCurve& other);
00203 ~LinearCurve();
00204 LinearCurve& operator=(const LinearCurve& other);
00205
00206 void makeLerp();
00207 };
00208
00209 template <typename DATA_TYPE, unsigned int SIZE>
00210 LinearCurve<DATA_TYPE, SIZE>::LinearCurve()
00211 {
00212 }
00213
00214 template <typename DATA_TYPE, unsigned int SIZE>
00215 LinearCurve<DATA_TYPE, SIZE>::LinearCurve(const LinearCurve& other)
00216 {
00217 *this = other;
00218 }
00219
00220 template <typename DATA_TYPE, unsigned int SIZE>
00221 LinearCurve<DATA_TYPE, SIZE>::~LinearCurve()
00222 {
00223 }
00224
00225 template <typename DATA_TYPE, unsigned int SIZE>
00226 LinearCurve<DATA_TYPE, SIZE>&
00227 LinearCurve<DATA_TYPE, SIZE>::operator=(const LinearCurve& other)
00228 {
00229 ParametricCurve::operator =(other);
00230
00231 return *this;
00232 }
00233
00234 template <typename DATA_TYPE, unsigned int SIZE>
00235 void LinearCurve<DATA_TYPE, SIZE>::makeLerp()
00236 {
00237 mBasisMatrix.set(
00238 -1.0, 1.0,
00239 1.0, 0.0
00240 );
00241 }
00242
00249 template<typename DATA_TYPE, unsigned SIZE>
00250 class QuadraticCurve : public ParametricCurve<DATA_TYPE, SIZE, 3>
00251 {
00252 public:
00253 QuadraticCurve();
00254 QuadraticCurve(const QuadraticCurve& other);
00255 ~QuadraticCurve();
00256 QuadraticCurve& operator=(const QuadraticCurve& other);
00257
00258 void makeBezier();
00259 };
00260
00261 template<typename DATA_TYPE, unsigned SIZE>
00262 QuadraticCurve<DATA_TYPE, SIZE>::QuadraticCurve()
00263 {
00264 }
00265
00266 template<typename DATA_TYPE, unsigned SIZE>
00267 QuadraticCurve<DATA_TYPE, SIZE>::QuadraticCurve(const QuadraticCurve& other)
00268 {
00269 *this = other;
00270 }
00271
00272 template<typename DATA_TYPE, unsigned SIZE>
00273 QuadraticCurve<DATA_TYPE, SIZE>::~QuadraticCurve()
00274 {
00275 }
00276
00277 template<typename DATA_TYPE, unsigned SIZE>
00278 QuadraticCurve<DATA_TYPE, SIZE>&
00279 QuadraticCurve<DATA_TYPE, SIZE>::operator=(const QuadraticCurve& other)
00280 {
00281 ParametricCurve::operator =(other);
00282
00283 return *this;
00284 }
00285
00286 template<typename DATA_TYPE, unsigned SIZE>
00287 void QuadraticCurve<DATA_TYPE, SIZE>::makeBezier()
00288 {
00289 mBasisMatrix.set(
00290 1.0, -2.0, 1.0,
00291 -2.0, 2.0, 0.0,
00292 1.0, 0.0, 0.0
00293 );
00294 }
00295
00302 template<typename DATA_TYPE, unsigned SIZE>
00303 class CubicCurve : public ParametricCurve<DATA_TYPE, SIZE, 4>
00304 {
00305 public:
00306 CubicCurve();
00307 CubicCurve(const CubicCurve& other);
00308 ~CubicCurve();
00309 CubicCurve& operator=(const CubicCurve& other);
00310
00311 void makeBezier();
00312 void makeCatmullRom();
00313 void makeHermite();
00314 void makeBspline();
00315 };
00316
00317 template<typename DATA_TYPE, unsigned SIZE>
00318 CubicCurve<DATA_TYPE, SIZE>::CubicCurve()
00319 {
00320 }
00321
00322 template<typename DATA_TYPE, unsigned SIZE>
00323 CubicCurve<DATA_TYPE, SIZE>::CubicCurve(const CubicCurve& other)
00324 {
00325 *this = other;
00326 }
00327
00328 template<typename DATA_TYPE, unsigned SIZE>
00329 CubicCurve<DATA_TYPE, SIZE>::~CubicCurve()
00330 {
00331 }
00332
00333 template<typename DATA_TYPE, unsigned SIZE>
00334 CubicCurve<DATA_TYPE, SIZE>&
00335 CubicCurve<DATA_TYPE, SIZE>::operator=(const CubicCurve& other)
00336 {
00337 ParametricCurve::operator =(other);
00338
00339 return *this;
00340 }
00341
00342 template<typename DATA_TYPE, unsigned SIZE>
00343 void CubicCurve<DATA_TYPE, SIZE>::makeBezier()
00344 {
00345 mBasisMatrix.set(
00346 -1.0, 3.0, -3.0, 1.0,
00347 3.0, -6.0, 3.0, 0.0,
00348 -3.0, 3.0, 0.0, 0.0,
00349 1.0, 0.0, 0.0, 0.0
00350 );
00351 }
00352
00353 template<typename DATA_TYPE, unsigned SIZE>
00354 void CubicCurve<DATA_TYPE, SIZE>::makeCatmullRom()
00355 {
00356 mBasisMatrix.set(
00357 -0.5, 1.5, -1.5, 0.5,
00358 1.0, -2.5, 2.0, -0.5,
00359 -0.5, 0.0, 0.5, 0.0,
00360 0.0, 1.0, 0.0, 0.0
00361 );
00362 }
00363
00364 template<typename DATA_TYPE, unsigned SIZE>
00365 void CubicCurve<DATA_TYPE, SIZE>::makeHermite()
00366 {
00367 mBasisMatrix.set(
00368 2.0, -2.0, 1.0, 1.0,
00369 -3.0, 3.0, -2.0, -1.0,
00370 0.0, 0.0, 1.0, 0.0,
00371 1.0, 0.0, 0.0, 0.0
00372 );
00373 }
00374
00375 template<typename DATA_TYPE, unsigned SIZE>
00376 void CubicCurve<DATA_TYPE, SIZE>::makeBspline()
00377 {
00378 mBasisMatrix.set(
00379 -1.0 / 6.0, 0.5, -0.5, 1.0 / 6.0,
00380 0.5, -1.0, 0.5, 0.0,
00381 -0.5, 0.0, 0.5, 0.0,
00382 1.0 / 6.0, 2.0 / 3.0, 1.0 / 6.0, 0.0
00383 );
00384 }
00385
00386
00387 typedef LinearCurve<float, 1> LinearCurve1f;
00388 typedef LinearCurve<float, 2> LinearCurve2f;
00389 typedef LinearCurve<float, 3> LinearCurve3f;
00390 typedef LinearCurve<double, 1> LinearCurve1d;
00391 typedef LinearCurve<double, 2> LinearCurve2d;
00392 typedef LinearCurve<double, 3> LinearCurve3d;
00393 typedef QuadraticCurve<float, 1> QuadraticCurve1f;
00394 typedef QuadraticCurve<float, 2> QuadraticCurve2f;
00395 typedef QuadraticCurve<float, 3> QuadraticCurve3f;
00396 typedef QuadraticCurve<double, 1> QuadraticCurve1d;
00397 typedef QuadraticCurve<double, 2> QuadraticCurve2d;
00398 typedef QuadraticCurve<double, 3> QuadraticCurve3d;
00399 typedef CubicCurve<float, 1> CubicCurve1f;
00400 typedef CubicCurve<float, 2> CubicCurve2f;
00401 typedef CubicCurve<float, 3> CubicCurve3f;
00402 typedef CubicCurve<double, 1> CubicCurve1d;
00403 typedef CubicCurve<double, 2> CubicCurve2d;
00404 typedef CubicCurve<double, 3> CubicCurve3d;
00405
00406 }
00407
00408 #endif