我曾经发过两篇关于贝塞尔的文章:数学图形(1.47)贝塞尔(Bézier)曲线数学图形之贝塞尔(Bézier)曲面。那是使用我自己定义的脚本语言生成贝塞尔图形。由于我自己定义的脚本语法功能有限,所以最多只能支持5次贝塞尔函数,而这里将实现N次。

N阶贝塞尔曲线可如下推断:

给定点P0P1、…、Pn,其贝塞尔曲线即

看其公式需要先为之生成一套杨辉三角形数组。

关于插值与样条的介绍请看:http://www.cnblogs.com/WhyEngine/p/4020294.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+)*YD_MAX_BEZIER_CONTROL_VALUE/];
}; // -------------------------------------------------------------------------------------- #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] = {};
Yint YcBezierSpline::m_yanghuiTriangle[(YD_MAX_BEZIER_CONTROL_VALUE+)*YD_MAX_BEZIER_CONTROL_VALUE/] = {}; void YcBezierSpline::BuildYanghuiTriangle()
{
// 第0行
m_yanghuiRowIndex[] = ;
m_yanghuiTriangle[] = ; Yint index = ;
Yint t0,t1;
Yint* lastRow;
for (Yint i = ; i < YD_MAX_BEZIER_CONTROL_VALUE; i++)
{
m_yanghuiRowIndex[i] = index;
m_yanghuiTriangle[index] = ;
index++; for (Yint j = ; j <= i; j++)
{
lastRow = m_yanghuiTriangle + m_yanghuiRowIndex[i-];
t0 = lastRow[j - ];
t1 = (j < i) ? lastRow[j] : ; m_yanghuiTriangle[index] = t0 + t1;
index++;
}
} assert(index == (YD_MAX_BEZIER_CONTROL_VALUE+)*YD_MAX_BEZIER_CONTROL_VALUE/);
} // -------------------------------------------------------------------------------------- YcBezierSpline::YcBezierSpline()
{
if (m_yanghuiTriangle[] == )
{
BuildYanghuiTriangle();
} m_valuesCount = ;
m_pow_t = NULL; SetSplineValuesCount();
} YcBezierSpline::~YcBezierSpline()
{
ClearPowT();
} // 设置输出样条值的数目
void YcBezierSpline::SetSplineValuesCount(Yuint count)
{
if (count < )
{
count = ;
} 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 = ; i < m_valuesCount; i++)
{
t = i/(m_valuesCount - 1.0f); m_pow_t[i*YD_MAX_BEZIER_CONTROL_VALUE] = 1.0f;
for (Yint j = ; 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 - ]*t;
}
}
} // 计算样条数值
bool YcBezierSpline::BuildSpline(const void* ctrlValuesPtr, Yuint ctrlStride, Yuint ctrlCount,
void* splineValuesPtr, Yuint splineStride) const
{
if (ctrlCount < || ctrlCount > YD_MAX_BEZIER_CONTROL_VALUE)
{
return false;
} Yreal* destValue;
Yreal* srcValue;
Yreal v;
const Yint* yanghuiRow = m_yanghuiTriangle + m_yanghuiRowIndex[ctrlCount - ]; for (Yuint i = ; i < m_valuesCount; i++)
{
v = 0.0f;
for (Yuint j = ; j < ctrlCount; j++)
{
srcValue = (Yreal*)((char*)ctrlValuesPtr + ctrlStride*j);
v += yanghuiRow[j] * (*srcValue) * GetValueT(i, j) * GetValueT(m_valuesCount - - i, ctrlCount - - j);
} destValue = (Yreal*)((char*)splineValuesPtr + splineStride*i);
*destValue = v;
} return true;
} // --------------------------------------------------------------------------------------

图像:

相关软件的下载地址为:http://files.cnblogs.com/WhyEngine/TestSpline.zip

样条之贝塞尔(Bezier)的更多相关文章

  1. [摘抄] Bezier曲线、B样条和NURBS

    Bezier曲线.B样条和NURBS,NURBS是Non-Uniform Rational B-Splines的缩写,都是根据控制点来生成曲线的,那么他们有什么区别了?简单来说,就是: Bezier曲 ...

  2. 3D中的OBJ文件格式详解

    常见到的*.obj文件有两种:第一种是基于COFF(Common Object File Format)格式的OBJ文件(也称目标文件),这种格式用于编译应用程序:第二种是Alias|Wavefron ...

  3. SAP C/4HANA与人工智能和增强现实(AR)技术结合的又一个创新案例

    今天这篇迟到的文章,来自我的同事Aviva. 去年SAP C/4HANA发布之后,SAP的从业者们可能或多或少都读过一些来自SAP官方渠道,比如微信公众号"SAP天天事"发布的一些 ...

  4. 3D中OBJ文件格式详解

    常见到的*.obj文件有两种:第一种是基于COFF(Common Object File Format)格式的OBJ文件(也称目标文件),这种格式用于编译应用程序:第二种是Alias|Wavefron ...

  5. OpenCASCADE Conic to BSpline Curves-Circle

    OpenCASCADE Conic to BSpline Curves-Circle eryar@163.com Abstract. The conic sections and circles pl ...

  6. OpenCascade B-Spline Basis Function

    OpenCascade B-Spline Basis Function eryar@163.com Abstract. B-splines are quite a bit more flexible ...

  7. B样条曲线曲面(附代码)

    1 B样条曲线 1.1 B样条曲线方程 B样条方法具有表示与设计自由型曲线曲面的强大功能,是形状数学描述的主流方法之一,另外B样条方法是目前工业产品几何定义国际标准——有理B样条方法 (NURBS)的 ...

  8. C#----Graphics中部分方法的使用和理解

    1.DrawArc(Pen, Rectangle, Single, Single) 说明:绘制一段弧线,弧线是椭圆的一部分,椭圆是矩形Rectangle的内切椭圆. 参数:Pen是画弧线使用的画笔:R ...

  9. 【GDI+编程】--从三问开始

    一. GDI+三问 1.1 GDI+是什么? GDI+是GDI(Graphics Device Interface)的后继者,是一种图形设备的接口,它构成了Win XP操作系统的子系统的API. 1. ...

随机推荐

  1. 什么是新生代 GC 和老年代 GC

    GC 经常发生的区域是堆区,堆区还可以细分为新生代.老年代 jvm堆示意图 新生代 一个 Eden 区 两个 Survivor 区 老年代 默认 新生代(Young)与老年代(Old)的比例的值为 1 ...

  2. [转]状态压缩dp(状压dp)

    状态压缩动态规划(简称状压dp)是另一类非常典型的动态规划,通常使用在NP问题的小规模求解中,虽然是指数级别的复杂度,但速度比搜索快,其思想非常值得借鉴. 为了更好的理解状压dp,首先介绍位运算相关的 ...

  3. C# listbox DataSource数据绑定--一年半以前的bug

    listbox使用DataSource进行数据绑定和删除,大家肯定都会, 写这个随笔只是因为....这是一年半以前刚进公司的我遗留的bug,现在看看当时竟然没有解决 - - 现在写个测试程序,写个随笔 ...

  4. 手动搭建ABP2.1.3 Zero——基础框架

    一.基础层搭建 二.PM.Core 三.PM.EntityFramework 四.PM.Application 五.PM.WebApi 六.PM.Web(MPA) 七.PM.Web(SPA) 八.单元 ...

  5. netbeans启动后一会崩溃处理

    由于netbeans 默认不支持amd cpu渲染,故需要修改默认配置文件,修改后netbeans没有问题. http://stackoverflow.com/questions/34560485/n ...

  6. hdu 4452 37届金华赛区 K题

    题意:给一个n*n的格子,1在左上角,2在右下角,每个人有一个初始速度和方向,若遇到边缘,则朝相反方向前进,若两个人相遇则交换方向(注意方向改变后,人仍然需要移动),同时,每个人每过t1,t2时间就会 ...

  7. MongoDB简单使用 —— 基本操作

    本身MongoDB直接支持的是Bson文档,Bson文档在C#的官方驱动中对应的是BsonDocument类: var bsonDoc = new BsonDocument(){    [" ...

  8. HDU 4790 Just Random (2013成都J题)

    Just Random Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  9. How to detect the types of executable files

    How to detect the types of executable files type { IMAGE_DOS_HEADER: DOS .EXE header. } IMAGE_DOS_HE ...

  10. VS2015 Offline Help Content is now available in 10 more languages!

    https://blogs.msdn.microsoft.com/devcontentloc/2015/10/21/vs2015-offline-help-content-is-now-availab ...