Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlCore/CatmullRomInterpolator.hpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.visualizationlibrary.org                                               */
00005 /*                                                                                    */
00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
00007 /*  All rights reserved.                                                              */
00008 /*                                                                                    */
00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
00010 /*  are permitted provided that the following conditions are met:                     */
00011 /*                                                                                    */
00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
00013 /*  list of conditions and the following disclaimer.                                  */
00014 /*                                                                                    */
00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
00017 /*  other materials provided with the distribution.                                   */
00018 /*                                                                                    */
00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
00029 /*                                                                                    */
00030 /**************************************************************************************/
00031 
00032 #ifndef CatmullRomInterpolator_INCLUDE_ONCE
00033 #define CatmullRomInterpolator_INCLUDE_ONCE
00034 
00035 #include <vlCore/Interpolator.hpp>
00036 
00037 namespace vl
00038 {
00045   template<typename T>
00046   class CatmullRomInterpolator: public Object
00047   {
00048     VL_INSTRUMENT_CLASS(vl::CatmullRomInterpolator<typename T>, Object)
00049 
00050   public:
00051     CatmullRomInterpolator() 
00052     {
00053       VL_DEBUG_SET_OBJECT_NAME()
00054     }
00055 
00056     CatmullRomInterpolator(const std::vector<T>& path): mPath(path) {}
00057 
00059     void setupEndPoints(bool is_loop)
00060     {
00061       VL_CHECK(mPath.size()>=2)
00062       if (mPath.size()<2)
00063         return;
00064 
00065       mCatmullRomSpline = mPath;
00066 
00067       /*
00068        D-------C
00069        .       |
00070        .       |
00071        .       |
00072        A-------B
00073       */
00074 
00075       if (is_loop)
00076       {
00077         T a = mCatmullRomSpline[0];
00078         T b = mCatmullRomSpline[1];
00079         T d = mCatmullRomSpline[mCatmullRomSpline.size()-1];
00080 
00081         mCatmullRomSpline.insert(mCatmullRomSpline.begin(),d);
00082         mCatmullRomSpline.push_back(a);
00083         mCatmullRomSpline.push_back(b);
00084       }
00085       else
00086       {
00087         T a = mCatmullRomSpline[0] + (mCatmullRomSpline[0] - mCatmullRomSpline[1]);
00088         T b = mCatmullRomSpline[mCatmullRomSpline.size()-1] + (mCatmullRomSpline[mCatmullRomSpline.size()-1] - mCatmullRomSpline[mCatmullRomSpline.size()-2]);
00089         mCatmullRomSpline.insert(mCatmullRomSpline.begin(),a);
00090         mCatmullRomSpline.push_back(b);
00091       }
00092 
00093     }
00094 
00096     T computePoint(float t) const
00097     {
00098       VL_CHECK(mCatmullRomSpline.size() >= 4)
00099       size_t size = mCatmullRomSpline.size()-2;
00100       t = clamp(t, 0.0f, 1.0f);
00101       if (t == 0.0f)
00102         return mCatmullRomSpline[1];
00103       else
00104       if (t == 1.0f)
00105         return mCatmullRomSpline[ mCatmullRomSpline.size()-1-1 ];
00106       else
00107       {
00108         int i    = 1 + (int)((size-1)*t);
00109         int i0 = i-1;
00110         int i1 = i;
00111         int i2 = i+1;
00112         int i3 = i+2;
00113         VL_CHECK(i3<(int)mCatmullRomSpline.size())
00114         float tt = (size-1)*t - int((size-1)*t); // frac generates rounding errors
00115         T p0 = mCatmullRomSpline[i0];
00116         T p1 = mCatmullRomSpline[i1];
00117         T p2 = mCatmullRomSpline[i2];
00118         T p3 = mCatmullRomSpline[i3];
00119         T p  = ( (p1 * 2.0f) + (-p0 + p2)          * tt +
00120                ( p0*2.0f - p1*5.0f + p2*4.0f - p3) * tt*tt +
00121                ( p0*-1 + p1*3.0f - p2*3.0f + p3)   * tt*tt*tt ) * 0.5f;
00122         return p;
00123       }
00124     }
00125 
00130     void setPath(const std::vector<T>& path) { mPath = path; }
00131     
00133     const std::vector<T>& path() const { return mPath; }
00134     
00136     std::vector<T>& path() { return mPath; }
00137 
00138   protected:
00139     std::vector<T> mPath;
00140     std::vector<T> mCatmullRomSpline;
00141   };
00142 
00143   typedef CatmullRomInterpolator<float>     CatmullRomInterpolatorFloat_T;
00144   typedef CatmullRomInterpolator<fvec2> CatmullRomInterpolatorFVec2_T;
00145   typedef CatmullRomInterpolator<fvec3> CatmullRomInterpolatorFVec3_T;
00146   typedef CatmullRomInterpolator<fvec4> CatmullRomInterpolatorFVec4_T;
00147   typedef CatmullRomInterpolator<double>    CatmullRomInterpolatorDouble_T;
00148   typedef CatmullRomInterpolator<dvec2> CatmullRomInterpolatorDVec2_T;
00149   typedef CatmullRomInterpolator<dvec3> CatmullRomInterpolatorDVec3_T;
00150   typedef CatmullRomInterpolator<dvec4> CatmullRomInterpolatorDVec4_T;
00151 
00153   class CatmullRomInterpolatorFVec4: public InterpolatorFVec4
00154   {
00155     VL_INSTRUMENT_CLASS(vl::CatmullRomInterpolatorFVec4, InterpolatorFVec4)
00156   public:
00157     CatmullRomInterpolatorFVec4(): mInterpolator( new CatmullRomInterpolatorFVec4_T ) {}
00158     CatmullRomInterpolatorFVec4(const std::vector<fvec4>& path): mInterpolator( new CatmullRomInterpolatorFVec4_T(path) ) {}
00159     fvec4 computePoint(float t) const { return interpolator()->computePoint(t); }
00160     CatmullRomInterpolatorFVec4_T* interpolator() { return mInterpolator.get(); }
00161     const CatmullRomInterpolatorFVec4_T* interpolator() const { return mInterpolator.get(); }
00162     void setInterpolator(CatmullRomInterpolatorFVec4_T* interpolator) { mInterpolator = interpolator; }
00163   protected:
00164     ref<CatmullRomInterpolatorFVec4_T> mInterpolator;
00165   };
00167   class CatmullRomInterpolatorFVec3: public InterpolatorFVec3
00168   {
00169     VL_INSTRUMENT_CLASS(vl::CatmullRomInterpolatorFVec3, InterpolatorFVec3)
00170   public:
00171     CatmullRomInterpolatorFVec3(): mInterpolator( new CatmullRomInterpolatorFVec3_T ) {}
00172     CatmullRomInterpolatorFVec3(const std::vector<fvec3>& path): mInterpolator( new CatmullRomInterpolatorFVec3_T(path) ) {}
00173     fvec3 computePoint(float t) const { return interpolator()->computePoint(t); }
00174     CatmullRomInterpolatorFVec3_T* interpolator() { return mInterpolator.get(); }
00175     const CatmullRomInterpolatorFVec3_T* interpolator() const { return mInterpolator.get(); }
00176     void setInterpolator(CatmullRomInterpolatorFVec3_T* interpolator) { mInterpolator = interpolator; }
00177   protected:
00178     ref<CatmullRomInterpolatorFVec3_T> mInterpolator;
00179   };
00181   class CatmullRomInterpolatorFVec2: public InterpolatorFVec2
00182   {
00183     VL_INSTRUMENT_CLASS(vl::CatmullRomInterpolatorFVec2, InterpolatorFVec2)
00184   public:
00185     CatmullRomInterpolatorFVec2(): mInterpolator( new CatmullRomInterpolatorFVec2_T ) {}
00186     CatmullRomInterpolatorFVec2(const std::vector<fvec2>& path): mInterpolator( new CatmullRomInterpolatorFVec2_T(path) ) {}
00187     fvec2 computePoint(float t) const { return interpolator()->computePoint(t); }
00188     CatmullRomInterpolatorFVec2_T* interpolator() { return mInterpolator.get(); }
00189     const CatmullRomInterpolatorFVec2_T* interpolator() const { return mInterpolator.get(); }
00190     void setInterpolator(CatmullRomInterpolatorFVec2_T* interpolator) { mInterpolator = interpolator; }
00191   protected:
00192     ref<CatmullRomInterpolatorFVec2_T> mInterpolator;
00193   };
00195   class CatmullRomInterpolatorFloat: public InterpolatorFloat
00196   {
00197     VL_INSTRUMENT_CLASS(vl::CatmullRomInterpolatorFloat, InterpolatorFloat)
00198   public:
00199     CatmullRomInterpolatorFloat(): mInterpolator( new CatmullRomInterpolatorFloat_T ) {}
00200     CatmullRomInterpolatorFloat(const std::vector<float>& path): mInterpolator( new CatmullRomInterpolatorFloat_T(path) ) {}
00201     float computePoint(float t) const { return interpolator()->computePoint(t); }
00202     CatmullRomInterpolatorFloat_T* interpolator() { return mInterpolator.get(); }
00203     const CatmullRomInterpolatorFloat_T* interpolator() const { return mInterpolator.get(); }
00204     void setInterpolator(CatmullRomInterpolatorFloat_T* interpolator) { mInterpolator = interpolator; }
00205   protected:
00206     ref<CatmullRomInterpolatorFloat_T> mInterpolator;
00207   };
00209   class CatmullRomInterpolatorDVec4: public InterpolatorDVec4
00210   {
00211     VL_INSTRUMENT_CLASS(vl::CatmullRomInterpolatorDVec4, InterpolatorDVec4)
00212   public:
00213     CatmullRomInterpolatorDVec4(): mInterpolator( new CatmullRomInterpolatorDVec4_T ) {}
00214     CatmullRomInterpolatorDVec4(const std::vector<dvec4>& path): mInterpolator( new CatmullRomInterpolatorDVec4_T(path) ) {}
00215     dvec4 computePoint(float t) const { return interpolator()->computePoint(t); }
00216     CatmullRomInterpolatorDVec4_T* interpolator() { return mInterpolator.get(); }
00217     const CatmullRomInterpolatorDVec4_T* interpolator() const { return mInterpolator.get(); }
00218     void setInterpolator(CatmullRomInterpolatorDVec4_T* interpolator) { mInterpolator = interpolator; }
00219   protected:
00220     ref<CatmullRomInterpolatorDVec4_T> mInterpolator;
00221   };
00223   class CatmullRomInterpolatorDVec3: public InterpolatorDVec3
00224   {
00225     VL_INSTRUMENT_CLASS(vl::CatmullRomInterpolatorDVec3, InterpolatorDVec3)
00226   public:
00227     CatmullRomInterpolatorDVec3(): mInterpolator( new CatmullRomInterpolatorDVec3_T ) {}
00228     CatmullRomInterpolatorDVec3(const std::vector<dvec3>& path): mInterpolator( new CatmullRomInterpolatorDVec3_T(path) ) {}
00229     dvec3 computePoint(float t) const { return interpolator()->computePoint(t); }
00230     CatmullRomInterpolatorDVec3_T* interpolator() { return mInterpolator.get(); }
00231     const CatmullRomInterpolatorDVec3_T* interpolator() const { return mInterpolator.get(); }
00232     void setInterpolator(CatmullRomInterpolatorDVec3_T* interpolator) { mInterpolator = interpolator; }
00233   protected:
00234     ref<CatmullRomInterpolatorDVec3_T> mInterpolator;
00235   };
00237   class CatmullRomInterpolatorDVec2: public InterpolatorDVec2
00238   {
00239     VL_INSTRUMENT_CLASS(vl::CatmullRomInterpolatorDVec2, InterpolatorDVec2)
00240   public:
00241     CatmullRomInterpolatorDVec2(): mInterpolator( new CatmullRomInterpolatorDVec2_T ) {}
00242     CatmullRomInterpolatorDVec2(const std::vector<dvec2>& path): mInterpolator( new CatmullRomInterpolatorDVec2_T(path) ) {}
00243     dvec2 computePoint(float t) const { return interpolator()->computePoint(t); }
00244     CatmullRomInterpolatorDVec2_T* interpolator() { return mInterpolator.get(); }
00245     const CatmullRomInterpolatorDVec2_T* interpolator() const { return mInterpolator.get(); }
00246     void setInterpolator(CatmullRomInterpolatorDVec2_T* interpolator) { mInterpolator = interpolator; }
00247   protected:
00248     ref<CatmullRomInterpolatorDVec2_T> mInterpolator;
00249   };
00251   class CatmullRomInterpolatorDouble: public InterpolatorDouble
00252   {
00253     VL_INSTRUMENT_CLASS(vl::CatmullRomInterpolatorDouble, InterpolatorDouble)
00254   public:
00255     CatmullRomInterpolatorDouble(): mInterpolator( new CatmullRomInterpolatorDouble_T ) {}
00256     CatmullRomInterpolatorDouble(const std::vector<double>& path): mInterpolator( new CatmullRomInterpolatorDouble_T(path) ) {}
00257     double computePoint(float t) const { return interpolator()->computePoint(t); }
00258     CatmullRomInterpolatorDouble_T* interpolator() { return mInterpolator.get(); }
00259     const CatmullRomInterpolatorDouble_T* interpolator() const { return mInterpolator.get(); }
00260     void setInterpolator(CatmullRomInterpolatorDouble_T* interpolator) { mInterpolator = interpolator; }
00261   protected:
00262     ref<CatmullRomInterpolatorDouble_T> mInterpolator;
00263   };
00264 }
00265 
00266 #endif

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:28.
Permission is granted to use this page to write and publish articles regarding Visualization Library.