样条之贝塞尔(Bezier)

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

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

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

      \mathbf{B}(t)=\sum_{i=0}^n {n\choose i}\mathbf{P}_i(1-t)^{n-i}t^i ={n\choose 0}\mathbf{P}_0(1-t)^nt^{0}+{n\choose 1}\mathbf{P}_1(1-t)^{n-1}t^{1}+\cdots+{n\choose n-1}\mathbf{P}_{n-1}(1-t)^{1}t^{n-1}+{n\choose n}\mathbf{P}_n(1-t)^{0}t^n \mbox{ , } t \in [0,1]

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

关于插值与样条的介绍请看: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

转载于:https://www.cnblogs.com/WhyEngine/p/4020365.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/273570.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设计模式 之 工厂模式

项目源码&#xff1a;https://gitee.com/Jacob-gitee/DesignMode 个人博客&#xff1a;https://jacob.org.cn 女娲造人的故事 东汉《风俗通》记录了一则神话故事&#xff1a;“开天辟地&#xff0c;未有人民&#xff0c;女娲搏黄土做人”&#xff0c;讲述的内容就是大家非常熟…

设计模式 之 单例模式

项目源码&#xff1a;https://gitee.com/Jacob-gitee/DesignMode 个人博客&#xff1a;https://jacob.org.cn 宗旨 Ensure a class has only one instance,and provide a global point of access to it.&#xff08;确保某一个类只有一个实例&#xff0c;而且自行实例化并向整个…

设计模式 之 抽象工厂模式

项目源码&#xff1a;https://gitee.com/Jacob-gitee/DesignMode 个人博客 &#xff1a;https://jacob.org.cn 女娲的失误 工厂模式中讲了女娲造人的故事。人是造出来了&#xff0c;世界也热闹了&#xff0c;可是低头一看&#xff0c;都是清一色的类型&#xff0c;缺少关爱、仇…

设计模式 之 模板模式

项目源码&#xff1a;https://gitee.com/Jacob-gitee/DesignMode 个人博客 &#xff1a;http://jacob.org.cn 女娲的失误 工厂模式中讲了女娲造人的故事。人是造出来了&#xff0c;世界也热闹了&#xff0c;可是低头一看&#xff0c;都是清一色的类型&#xff0c;缺少关爱、仇…

使用Java高速实现进度条

基于有人问到如何做进度条&#xff0c;以下给个简单的做法&#xff1a; 主要是使用JProgressBar&#xff08;Swing内置javax.swing.JProgressBar&#xff09;和SwingWorker&#xff08;Swing内置javax.swing.SwingWorker&#xff09; 有人肯定会说&#xff0c;不是用线程做的吗…

关于js的function.来自百度知道的回答,学习了.

在js中&#xff0c;创建一个函数对象的语法是var myFunction new Function(arg1,…,agrN, body);其中&#xff0c;该函数对象的N个参数放在 函数主体参数body的前面&#xff0c;即函数主体参数必须放在参数列表的最后&#xff0c;也可以无参数new Function(body)。你添加第三个…

fedora20开机启动配置:systemctl

老版fedora中使用chkconfig配置开机启动&#xff0c;fedora20中&#xff0c;使用chkconfig会出现各种问题。使用systemctl配置。 具体表格如下 转载于:https://www.cnblogs.com/hh6plus/p/5548083.html

《Java 高并发》01 高并发基本概念

基本概念 同步和异步 同步和异步通常是用来形容一次方法调用。 同步方法调用一旦开始&#xff0c;调用者必须等到方法返回才能继续执行后续操作。 异步方法调用更像一个消息传递&#xff0c;一旦开始&#xff0c;方法调用就会立即返回&#xff0c;调用者就可以继续后续的操…

Android之Http网络编程(四)

前面几篇博文简单的介绍了一些常见的Http的操作&#xff0c;这些操作几乎都是在新开的线程中进行的网络请求&#xff0c;并在日志中打印出获取到的网络数据。那么&#xff0c;问题来了&#xff01;&#xff08;呃~感觉下一句是蓝翔有木有&#xff1f;&#xff09;如何在把获取到…

mybatis 2 -常用数据操作

1、写入数据并获取自增ID XML配置&#xff1a; <!-- 写入数据获取自增ID --><insert id"insertLog" parameterType"com.mamaguwen.entity.sys_loginlog" useGeneratedKeys"true" keyProperty"logid">insert into sys_…

Docker 搭建 ELK 日志系统,并通过 Kibana 查看日志

Docker 搭建 ELK 日志系统,并通过 Kibana 查看日志 docker-compose.yml version: 3 services:elasticsearch:image: elasticsearch:7.7.0 #镜像container_name: elasticsearch #定义容器名称restart: always #开机启动&#xff0c;失败也会一直重启environment:- "cl…

RabbitMQ Management:Management API returned status code 500

错误显示&#xff1a; 解决方案&#xff1a; 因为是使用docker 容器安装的&#xff0c;所有需要进入容器 docker exec -it rabbitmq /bin/bash进入目录 cd /etc/rabbitmq/conf.d/执行命令 echo management_agent.disable_metrics_collector false > management_agent.dis…

c++ 读取文件 最后一行读取了两次

用ifstream的eof()&#xff0c;竟然读到文件最后了&#xff0c;判断eof还为false。网上查找资料后&#xff0c;终于解决这个问题。 参照文件&#xff1a;http://tuhao.blogbus.com/logs/21306687.html 在使用C/C读文件的时候&#xff0c;一定都使用过eof&#xff08;&#xff0…

java中的io系统详解(转)

Java 流在处理上分为字符流和字节流。字符流处理的单元为 2 个字节的 Unicode 字符&#xff0c;分别操作字符、字符数组或字符串&#xff0c;而字节流处理单元为 1 个字节&#xff0c;操作字节和字节数组。 Java 内用 Unicode 编码存储字符&#xff0c;字符流处理类负责将外部的…

Unity3D Shader入门指南(二)

关于本系列 这是Unity3D Shader入门指南系列的第二篇&#xff0c;本系列面向的对象是新接触Shader开发的Unity3D使用者&#xff0c;因为我本身自己也是Shader初学者&#xff0c;因此可能会存在错误或者疏漏&#xff0c;如果您在Shader开发上有所心得&#xff0c;很欢迎并恳请您…

JVM:如何分析线程堆栈

英文原文&#xff1a;JVM: How to analyze Thread Dump 在这篇文章里我将教会你如何分析JVM的线程堆栈以及如何从堆栈信息中找出问题的根因。在我看来线程堆栈分析技术是Java EE产品支持工程师所必须掌握的一门技术。在线程堆栈中存储的信息&#xff0c;通常远超出你的想象&…

SQLSERVER中如何忽略索引提示

SQLSERVER中如何忽略索引提示 原文:SQLSERVER中如何忽略索引提示SQLSERVER中如何忽略索引提示 当我们想让某条查询语句利用某个索引的时候&#xff0c;我们一般会在查询语句里加索引提示&#xff0c;就像这样 SELECT id,name from TB with (index(IX_xttrace_bal)) where bal…

[016]转--C++拷贝构造函数详解

一. 什么是拷贝构造函数 首先对于普通类型的对象来说&#xff0c;它们之间的复制是很简单的&#xff0c;例如&#xff1a; [c-sharp] view plaincopy int a 100; int b a; 而类对象与普通对象不同&#xff0c;类对象内部结构一般较为复杂&#xff0c;存在各种成员变量。下…

自定义GrildView实现单选功能

首先看实现功能截图&#xff0c;这是一个自定义Dialog,并且里面内容由GrildView 绑定数据源&#xff0c;实现类似单选功能。 首先自定义Dialog&#xff0c;绑定数据源 自定义Dialog弹出框大小方法 最主要实现的就是点击颜色切换的功能&#xff0c;默认GrildView的每一项都是蓝色…

最大权闭合图hdu3996

定义&#xff1a;最大权闭合图&#xff1a;是有向图的一个点集&#xff0c;且该点集的所有出边都指向该集合。即闭合图内任意点的集合也在改闭合图内&#xff0c;给每个点分配一个点权值Pu&#xff0c;最大权闭合图就是使闭合图的点权之和最大。 最小割建边方式&#xff1a;源点…