? ? ? 我曾經發過兩篇關于貝塞爾的文章:數學圖形(1.47)貝塞爾(Bézier)曲線,數學圖形之貝塞爾(Bézier)曲面。那是使用我自己定義的腳本語言生成貝塞爾圖形。由于我自己定義的腳本語法功能有限,所以最多只能支持5次貝塞爾函數,而這里將實現N次。
? ? ? N階貝塞爾曲線可如下推斷:
? ? ? 給定點P0、P1、…、Pn,其貝塞爾曲線即
? ? ??
看其公式需要先為之生成一套楊輝三角形數組。
關于插值與樣條的介紹請看:http://www.cnblogs.com/WhyEngine/p/4020294.html
.h文件
1 /**************************************************************** 2 3 File name : YcBezierSpline.h 4 Author : 葉峰 5 Version : 2.0 6 Create Date : 2014/08/18 7 Description : Bezier樣條 8 9 *****************************************************************/ 10 11 #ifndef __YcBezierSpline_H__ 12 #define __YcBezierSpline_H__ 13 14 // INCLUDES ----------------------------------------------------------------------------- 15 16 #include "YicSpline.h" 17 18 // -------------------------------------------------------------------------------------- 19 20 #define YD_MAX_BEZIER_CONTROL_VALUE 33 21 22 // -------------------------------------------------------------------------------------- 23 24 class YcBezierSpline : public YicSpline 25 { 26 public: 27 YcBezierSpline(); 28 29 ~YcBezierSpline(); 30 31 // 設置輸出樣條值的數目 32 void SetSplineValuesCount(Yuint count); 33 34 // 獲得輸出樣條值的數目 35 Yuint GetSplineValuesCount() const; 36 37 // 計算樣條數值 38 bool BuildSpline(const void* ctrlValuesPtr, Yuint ctrlStride, Yuint ctrlCount, 39 void* splineValuesPtr, Yuint splineStride) const; 40 41 protected: 42 void ClearPowT(); 43 44 void BuildPowT(); 45 46 Yreal GetValueT(Yint t, Yint p) const 47 { 48 return m_pow_t[YD_MAX_BEZIER_CONTROL_VALUE*t + p]; 49 } 50 51 protected: 52 Yuint m_valuesCount; 53 Yreal* m_pow_t; 54 55 protected: 56 static void BuildYanghuiTriangle(); 57 static Yint m_yanghuiRowIndex[YD_MAX_BEZIER_CONTROL_VALUE]; 58 static Yint m_yanghuiTriangle[(YD_MAX_BEZIER_CONTROL_VALUE+1)*YD_MAX_BEZIER_CONTROL_VALUE/2]; 59 }; 60 61 // -------------------------------------------------------------------------------------- 62 63 #endif
CPP文件
1 /**************************************************************** 2 3 File name : YcBezierSpline.cpp 4 Author : 葉峰 5 Version : 2.0 6 Create Date : 2014/08/18 7 Description : 8 9 *****************************************************************/ 10 11 // INCLUDES ----------------------------------------------------------------------------- 12 13 #include "..\..\YCommon_h\YSpline\YcBezierSpline.h" 14 #include <assert.h> 15 16 // -------------------------------------------------------------------------------------- 17 18 Yint YcBezierSpline::m_yanghuiRowIndex[YD_MAX_BEZIER_CONTROL_VALUE] = {0}; 19 Yint YcBezierSpline::m_yanghuiTriangle[(YD_MAX_BEZIER_CONTROL_VALUE+1)*YD_MAX_BEZIER_CONTROL_VALUE/2] = {0}; 20 21 void YcBezierSpline::BuildYanghuiTriangle() 22 { 23 // 第0行 24 m_yanghuiRowIndex[0] = 0; 25 m_yanghuiTriangle[0] = 1; 26 27 Yint index = 1; 28 Yint t0,t1; 29 Yint* lastRow; 30 for (Yint i = 1; i < YD_MAX_BEZIER_CONTROL_VALUE; i++) 31 { 32 m_yanghuiRowIndex[i] = index; 33 m_yanghuiTriangle[index] = 1; 34 index++; 35 36 for (Yint j = 1; j <= i; j++) 37 { 38 lastRow = m_yanghuiTriangle + m_yanghuiRowIndex[i-1]; 39 t0 = lastRow[j - 1]; 40 t1 = (j < i) ? lastRow[j] : 0; 41 42 m_yanghuiTriangle[index] = t0 + t1; 43 index++; 44 } 45 } 46 47 assert(index == (YD_MAX_BEZIER_CONTROL_VALUE+1)*YD_MAX_BEZIER_CONTROL_VALUE/2); 48 } 49 50 // -------------------------------------------------------------------------------------- 51 52 YcBezierSpline::YcBezierSpline() 53 { 54 if (m_yanghuiTriangle[0] == 0) 55 { 56 BuildYanghuiTriangle(); 57 } 58 59 m_valuesCount = 0; 60 m_pow_t = NULL; 61 62 SetSplineValuesCount(100); 63 } 64 65 YcBezierSpline::~YcBezierSpline() 66 { 67 ClearPowT(); 68 } 69 70 // 設置輸出樣條值的數目 71 void YcBezierSpline::SetSplineValuesCount(Yuint count) 72 { 73 if (count < 2) 74 { 75 count = 2; 76 } 77 78 if (count == m_valuesCount) 79 { 80 return; 81 } 82 m_valuesCount = count; 83 BuildPowT(); 84 } 85 86 // 獲得輸出樣條值的數目 87 Yuint YcBezierSpline::GetSplineValuesCount() const 88 { 89 return m_valuesCount; 90 } 91 92 void YcBezierSpline::ClearPowT() 93 { 94 if (m_pow_t) 95 { 96 free(m_pow_t); 97 m_pow_t = NULL; 98 } 99 } 100 101 void YcBezierSpline::BuildPowT() 102 { 103 ClearPowT(); 104 105 m_pow_t = (Yreal*)malloc(m_valuesCount*YD_MAX_BEZIER_CONTROL_VALUE*sizeof(Yreal)); 106 Yreal t; 107 for (Yuint i = 0; i < m_valuesCount; i++) 108 { 109 t = i/(m_valuesCount - 1.0f); 110 111 m_pow_t[i*YD_MAX_BEZIER_CONTROL_VALUE] = 1.0f; 112 for (Yint j = 1; j < YD_MAX_BEZIER_CONTROL_VALUE; j++) 113 { 114 m_pow_t[i*YD_MAX_BEZIER_CONTROL_VALUE + j] = m_pow_t[i*YD_MAX_BEZIER_CONTROL_VALUE + j - 1]*t; 115 } 116 } 117 } 118 119 // 計算樣條數值 120 bool YcBezierSpline::BuildSpline(const void* ctrlValuesPtr, Yuint ctrlStride, Yuint ctrlCount, 121 void* splineValuesPtr, Yuint splineStride) const 122 { 123 if (ctrlCount < 2 || ctrlCount > YD_MAX_BEZIER_CONTROL_VALUE) 124 { 125 return false; 126 } 127 128 Yreal* destValue; 129 Yreal* srcValue; 130 Yreal v; 131 const Yint* yanghuiRow = m_yanghuiTriangle + m_yanghuiRowIndex[ctrlCount - 1]; 132 133 for (Yuint i = 0; i < m_valuesCount; i++) 134 { 135 v = 0.0f; 136 for (Yuint j = 0; j < ctrlCount; j++) 137 { 138 srcValue = (Yreal*)((char*)ctrlValuesPtr + ctrlStride*j); 139 v += yanghuiRow[j] * (*srcValue) * GetValueT(i, j) * GetValueT(m_valuesCount - 1 - i, ctrlCount - 1 - j); 140 } 141 142 destValue = (Yreal*)((char*)splineValuesPtr + splineStride*i); 143 *destValue = v; 144 } 145 146 return true; 147 } 148 149 // --------------------------------------------------------------------------------------
?圖像:
相關軟件的下載地址為:http://files.cnblogs.com/WhyEngine/TestSpline.zip