00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef SIMGEAR_BEZIERCURVE_HXX
00023 #define SIMGEAR_BEZIERCURVE_HXX 1
00024
00025 #include <list>
00026 using std::list;
00027
00028 namespace simgear
00029 {
00030 template<class T>
00031 class BezierCurve {
00032 public:
00033 typedef list<T> PointList;
00034
00035 BezierCurve() : mMaxSubdiv( 3 ) {}
00036 BezierCurve( size_t aMaxSubdiv )
00037 : mMaxSubdiv( aMaxSubdiv ) {}
00038 BezierCurve( const T &p1, const T &p2, const T &p3, size_t aMaxSubdiv = 3 )
00039 : mMaxSubdiv( aMaxSubdiv ) {
00040 subdivide( p1, p2, p3 );
00041 }
00042 BezierCurve( const T &p1, const T &p2, const T &p3, const T &p4, size_t aMaxSubdiv = 3 )
00043 : mMaxSubdiv( aMaxSubdiv ) {
00044 subdivide( p1, p2, p3, p4 );
00045 }
00046
00047 void subdivide( const T &p1, const T &p2, const T &p3 ) {
00048 mPointList.clear();
00049 mPointList.push_back( p1 );
00050 recursiveSubdivide( p1, p2, p3, 1 );
00051 mPointList.push_back( p3 );
00052 }
00053
00054 void subdivide( const T &p1, const T &p2, const T &p3, const T &p4 ) {
00055 mPointList.clear();
00056 mPointList.push_back( p1 );
00057 recursiveSubdivide( p1, p2, p3, p4, 1 );
00058 mPointList.push_back( p4 );
00059 }
00060
00061 void setMaxSubdiv( size_t aMaxSubdiv ) { mMaxSubdiv = aMaxSubdiv; }
00062 void getMaxSubdiv() const { return mMaxSubdiv; }
00063 PointList &pointList() { return mPointList; }
00064 const PointList &pointList() const { return mPointList; }
00065
00066 private:
00067 T midPoint( const T &p1, const T &p2 ) {
00068 return ( p1 + p2 ) / 2;
00069 }
00070 bool recursiveSubdivide( const T &p1, const T &p2, const T &p3, size_t l ) {
00071 if ( l > mMaxSubdiv )
00072 return false;
00073
00074 T p12 = midPoint( p1, p2 ),
00075 p23 = midPoint( p2, p3 ),
00076 p123 = midPoint( p12, p23 );
00077 recursiveSubdivide( p1, p12, p123, l + 1 );
00078 mPointList.push_back( p123 );
00079 recursiveSubdivide( p123, p23, p3, l + 1 );
00080 return true;
00081 }
00082
00083 bool recursiveSubdivide( const T &p1, const T &p2, const T &p3, const T &p4, size_t l ) {
00084 if ( l > mMaxSubdiv )
00085 return false;
00086
00087 T p12 = midPoint( p1, p2 ),
00088 p23 = midPoint( p2, p3 ),
00089 p34 = midPoint( p3, p4 ),
00090 p123 = midPoint( p12, p23 ),
00091 p234 = midPoint( p23, p34 ),
00092 p1234 = midPoint( p123, p234 );
00093 recursiveSubdivide( p1, p12, p123, p1234, l + 1 );
00094 mPointList.push_back( p1234 );
00095 recursiveSubdivide( p1234, p234, p34, p4, l + 1 );
00096 return true;
00097 }
00098
00099
00100 PointList mPointList;
00101 size_t mMaxSubdiv;
00102 };
00103 }
00104
00105 #endif