样条之贝塞尔(Bezier)
2014-10-13 18:24
113 查看
我曾经发过两篇关于贝塞尔的文章:数学图形(1.47)贝塞尔(Bézier)曲线,数学图形之贝塞尔(Bézier)曲面。那是使用我自己定义的脚本语言生成贝塞尔图形。由于我自己定义的脚本语法功能有限,所以最多只能支持5次贝塞尔函数,而这里将实现N次。
N阶贝塞尔曲线可如下推断:
给定点P0、P1、…、Pn,其贝塞尔曲线即
看其公式需要先为之生成一套杨辉三角形数组。
关于插值与样条的介绍请看:/article/4891792.html
.h文件
CPP文件
图像:
相关软件的下载地址为:http://files.cnblogs.com/WhyEngine/TestSpline.zip
N阶贝塞尔曲线可如下推断:
给定点P0、P1、…、Pn,其贝塞尔曲线即
看其公式需要先为之生成一套杨辉三角形数组。
关于插值与样条的介绍请看:/article/4891792.html
.h文件
/**************************************************************** File name : YcBezierSpline.h Author : 叶峰 Version : 2.0 Create Date : 2014/08/18 Description : Bezier样条 *****************************************************************/ #ifndef __YcBezierSpline_H__ #define __YcBezierSpline_H__ // INCLUDES ----------------------------------------------------------------------------- #include "YicSpline.h" // -------------------------------------------------------------------------------------- #define YD_MAX_BEZIER_CONTROL_VALUE 33 // -------------------------------------------------------------------------------------- class YcBezierSpline : public YicSpline { public: YcBezierSpline(); ~YcBezierSpline(); // 设置输出样条值的数目 void SetSplineValuesCount(Yuint count); // 获得输出样条值的数目 Yuint GetSplineValuesCount() const; // 计算样条数值 bool BuildSpline(const void* ctrlValuesPtr, Yuint ctrlStride, Yuint ctrlCount, void* splineValuesPtr, Yuint splineStride) const; protected: void ClearPowT(); void BuildPowT(); Yreal GetValueT(Yint t, Yint p) const { return m_pow_t[YD_MAX_BEZIER_CONTROL_VALUE*t + p]; } protected: Yuint m_valuesCount; Yreal* m_pow_t; protected: static void BuildYanghuiTriangle(); static Yint m_yanghuiRowIndex[YD_MAX_BEZIER_CONTROL_VALUE]; static Yint m_yanghuiTriangle[(YD_MAX_BEZIER_CONTROL_VALUE+1)*YD_MAX_BEZIER_CONTROL_VALUE/2]; }; // -------------------------------------------------------------------------------------- #endif
CPP文件
/**************************************************************** File name : YcBezierSpline.cpp Author : 叶峰 Version : 2.0 Create Date : 2014/08/18 Description : *****************************************************************/ // INCLUDES ----------------------------------------------------------------------------- #include "..\..\YCommon_h\YSpline\YcBezierSpline.h" #include <assert.h> // -------------------------------------------------------------------------------------- Yint YcBezierSpline::m_yanghuiRowIndex[YD_MAX_BEZIER_CONTROL_VALUE] = {0}; Yint YcBezierSpline::m_yanghuiTriangle[(YD_MAX_BEZIER_CONTROL_VALUE+1)*YD_MAX_BEZIER_CONTROL_VALUE/2] = {0}; void YcBezierSpline::BuildYanghuiTriangle() { // 第0行 m_yanghuiRowIndex[0] = 0; m_yanghuiTriangle[0] = 1; Yint index = 1; Yint t0,t1; Yint* lastRow; for (Yint i = 1; i < YD_MAX_BEZIER_CONTROL_VALUE; i++) { m_yanghuiRowIndex[i] = index; m_yanghuiTriangle[index] = 1; index++; for (Yint j = 1; j <= i; j++) { lastRow = m_yanghuiTriangle + m_yanghuiRowIndex[i-1]; t0 = lastRow[j - 1]; t1 = (j < i) ? lastRow[j] : 0; m_yanghuiTriangle[index] = t0 + t1; index++; } } assert(index == (YD_MAX_BEZIER_CONTROL_VALUE+1)*YD_MAX_BEZIER_CONTROL_VALUE/2); } // -------------------------------------------------------------------------------------- YcBezierSpline::YcBezierSpline() { if (m_yanghuiTriangle[0] == 0) { BuildYanghuiTriangle(); } m_valuesCount = 0; m_pow_t = NULL; SetSplineValuesCount(100); } YcBezierSpline::~YcBezierSpline() { ClearPowT(); } // 设置输出样条值的数目 void YcBezierSpline::SetSplineValuesCount(Yuint count) { if (count < 2) { count = 2; } if (count == m_valuesCount) { return; } m_valuesCount = count; BuildPowT(); } // 获得输出样条值的数目 Yuint YcBezierSpline::GetSplineValuesCount() const { return m_valuesCount; } void YcBezierSpline::ClearPowT() { if (m_pow_t) { free(m_pow_t); m_pow_t = NULL; } } void YcBezierSpline::BuildPowT() { ClearPowT(); m_pow_t = (Yreal*)malloc(m_valuesCount*YD_MAX_BEZIER_CONTROL_VALUE*sizeof(Yreal)); Yreal t; for (Yuint i = 0; i < m_valuesCount; i++) { t = i/(m_valuesCount - 1.0f); m_pow_t[i*YD_MAX_BEZIER_CONTROL_VALUE] = 1.0f; for (Yint j = 1; j < YD_MAX_BEZIER_CONTROL_VALUE; j++) { m_pow_t[i*YD_MAX_BEZIER_CONTROL_VALUE + j] = m_pow_t[i*YD_MAX_BEZIER_CONTROL_VALUE + j - 1]*t; } } } // 计算样条数值 bool YcBezierSpline::BuildSpline(const void* ctrlValuesPtr, Yuint ctrlStride, Yuint ctrlCount, void* splineValuesPtr, Yuint splineStride) const { if (ctrlCount < 2 || ctrlCount > YD_MAX_BEZIER_CONTROL_VALUE) { return false; } Yreal* destValue; Yreal* srcValue; Yreal v; const Yint* yanghuiRow = m_yanghuiTriangle + m_yanghuiRowIndex[ctrlCount - 1]; for (Yuint i = 0; i < m_valuesCount; i++) { v = 0.0f; for (Yuint j = 0; j < ctrlCount; j++) { srcValue = (Yreal*)((char*)ctrlValuesPtr + ctrlStride*j); v += yanghuiRow[j] * (*srcValue) * GetValueT(i, j) * GetValueT(m_valuesCount - 1 - i, ctrlCount - 1 - j); } destValue = (Yreal*)((char*)splineValuesPtr + splineStride*i); *destValue = v; } return true; } // --------------------------------------------------------------------------------------
图像:
相关软件的下载地址为:http://files.cnblogs.com/WhyEngine/TestSpline.zip
相关文章推荐
- 多控制点生成贝塞尔(Bezier-Curve)样条 C语言版
- 样条之贝塞尔(Bezier)
- 计算机图形学(七)Bezier(贝塞尔)曲线讲解与源代码
- 【iOS-Cocos2d游戏开发之十三】CCSprite利用Bezier(贝塞尔)做抛物线动作并让CCSprite同时播放两个Action动作!
- 数学图形之贝塞尔(Bézier)曲面
- 计算机图形学-实验5-掌握Bezier样条曲面生成思想、复习基本图元绘制、交互操作和几何变换相关内容
- 【iOS-Cocos2d游戏开发之十三】CCSprite利用Bezier(贝塞尔)做抛物线动作并让CCSprite同时播放两个Action动作!
- CCSprite利用Bezier(贝塞尔)做抛物线动作并让CCSprite同时播放两个Action动作!
- 【Cocos2d游戏开发之十三】CCSprite利用Bezier(贝塞尔)做抛物线动作并让CCSprite同时播放两个Action动作!
- 【iOS-Cocos2d游戏开发之十三】CCSprite利用Bezier(贝塞尔)抛物线并同时播放两个Action动作!
- 【Cocos2d游戏开发之十三】CCSprite利用Bezier(贝塞尔)做抛物线动作并让CCSprite同时播放两个Action动作!
- 【iOS-Cocos2d游戏开发之十三】CCSprite利用Bezier(贝塞尔)抛物线并同时播放两个Action动作!
- 【iOS-Cocos2d游戏开发之十三】CCSprite利用Bezier(贝塞尔)做抛物线动作并让CCSprite同时播放两个Action动作!
- 【iOS-Cocos2d游戏开发之十三】CCSprite利用Bezier(贝塞尔)抛物线并同时播放两个Action动作! 推荐
- 数学图形(1.47)贝塞尔(Bézier)曲线
- CCSprite利用Bezier(贝塞尔)做抛物线动作
- Bezier Patch
- 程序5-4 Bezier
- bezier 曲线
- 贝塞尔曲面的绘制