我曾经发过两篇关于贝塞尔的文章:数学图形(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. Django中的ORM关系映射查询方面

    ORM:Object-Relation Mapping:对象-关系映射 在MVC框架中的Model模块中都包括ORM,对于开发人员主要带来了如下好处: 实现了数据模型与数据库的解耦,通过简单的配置就可 ...

  2. 一个关于react-native的demo,详细请转GitHub

    react native 0 介绍 支持ios和android两个平台 下载:git clone https://github.com/chunlei36/react-native-full-exam ...

  3. [ 转载 ] Python Web 框架:Django、Flask 与 Tornado 的性能对比

    本文的数据涉及到我面试时遇到过的问题,大概一次 http 请求到收到响应需要多少时间.这个问题在实际工作中与框架有比较大的关系,因此特别就框架的性能做了一次分析. 这里使用 2016 年 6 月 9 ...

  4. HDU 5628 Clarke and math dp+数学

    Clarke and math 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5628 Description Clarke is a patient ...

  5. bzoj4001: [TJOI2015]概率论

    题目链接 bzoj4001: [TJOI2015]概率论 题解 生成函数+求导 设\(g(n)\)表示有\(n\)个节点的二叉树的个数,\(g(0) = 1\) 设\(f(x)\)表示\(n\)个节点 ...

  6. SPFA算法 O(kE)

    主要思想是:     初始时将起点加入队列.每次从队列中取出一个元素,并对所有与它相邻的点进行修改,若某个相邻的点修改成功,则将其入队.直到队列为空时算法结束.     这个算法,简单的说就是队列优化 ...

  7. hdu 2710 水题

    题意:判断一些数里有最大因子的数 水题,省赛即将临近,高效的代码风格需要养成,为了简化代码,以后可能会更多的使用宏定义,但是通常也只是快速拿下第一道水题,涨自信.大部分的代码还是普通的形式,实际上能简 ...

  8. 注册Goole 账户 成功注册

    注册谷歌邮箱等Google帐号时提示:此电话号码无法用于进行验证怎么办? 相信很多网友在注册Google帐号的时候需要手机号码验证,比如在遇到过注册Google Gmail到最后一步“验证您的帐号” ...

  9. spring-boot 速成(10) -【个人邮箱/企业邮箱】发送邮件

    发邮件是一个很常见的功能,代码本身并不复杂,有坑的地方主要在于各家邮件厂家的设置,下面以qq个人邮箱以及腾讯企业邮箱为例,讲解如何用spring-boot发送邮件: 一.添加依赖项 compile ' ...

  10. BrowserLog——使用Chrome控制台作为Log查看器

    Chrome控制台是十分强大的,即使将它作为一个log查看器也是非常强大的,BrowserLog就是一个.net下的把Chrome作为log输出的程序包. 原理非常简单,server端将log数据通过 ...