我曾经发过两篇关于贝塞尔的文章:数学图形(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