• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

ParametricCurve.h

Go to the documentation of this file.
00001 // GMTL is (C) Copyright 2001-2010 by Allen Bierbaum
00002 // Distributed under the GNU Lesser General Public License 2.1 with an
00003 // addendum covering inlined code. (See accompanying files LICENSE and
00004 // LICENSE.addendum or http://www.gnu.org/copyleft/lesser.txt)
00005 
00006 /********************************************************************
00007 created: 2010/01/14
00008 created: 14:1:2010   22:14
00009 filename:   ParametricCurve.h
00010 author:     Gao Yang
00011 
00012 purpose: Defines a series of parametric curves include linear,
00013       quadratic, Bezier, Hermite, Catmull-Rom, B-Spline. Custom
00014       curve definitions are also possible via user-defined basis
00015       matrices.
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 // --- helper types --- //
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

Generated on Sun Sep 19 2010 14:35:14 for GenericMathTemplateLibrary by  doxygen 1.7.1