样条之贝塞尔(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,一经查实,立即删除!

相关文章

TCollector

TCollector tcollector is a client-side process that gathers data from local collectors and pushes the data to OpenTSDB. You run it on all your hosts, and it does the work of sending each hosts data to the TSD. tcollector是client-side&#xff08;客户端&…

设计模式 之 工厂模式

项目源码&#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;而且自行实例化并向整个…

如何实现滑动scrollview上下隐藏

问题描述现在有一个需求&#xff0c;就是一个界面如下ABCA固定在顶部&#xff0c;C固定在底部其中B是一个scrollview(也可能是listview)&#xff0c;要实现&#xff0c;在向上滑动B的时候&#xff0c;A平滑的往上滑&#xff0c;同时C平滑的往下滑&#xff0c;直到消失&#xff…

设计模式 之 抽象工厂模式

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

strip 命令的使用方法

用途 通过除去绑定程序和符号调试程序使用的信息&#xff0c;降低扩展公共对象文件格式&#xff08;XCOFF&#xff09;的对象文件的大小。 语法 strip [ -V ] [ -r [ -l ] | -x [ -l ] | -t | -H | -e | -E ] [ -X {32 |64 |32_64 }] [ -- ] File ... 描…

设计模式 之 模板模式

项目源码&#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;不是用线程做的吗…

Linux 安装JDK

个人博客 &#xff1a;https://www.siyuan.run CSDN&#xff1a;https://blog.csdn.net/siyuan 微信小程序&#xff1a;思远Y 安装时使用到的命令&#xff1a; cd&#xff1a;切换目录。 eg&#xff1a;cd / mkdir&#xff1a;创建目录。 eg&#xff1a;mkdir jacob 创建单极目…

Css导航

<div> <ul> <li><a></a></li> <li><a></a></li> <li><a></a></li> .. </ul> </div> <li>中也可包含 <ul> <a></a> <li><a></a>&…

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

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

Ribbon 支持的9大负载均衡策略

个人博客 &#xff1a;https://www.siyuan.run CSDN&#xff1a;https://blog.csdn.net/siyuan 微信小程序&#xff1a;思远Y 线性轮询策略&#xff1a; RoundRibbonRule BaseLoadBalancer 负载均衡器默认采用线性负载轮询负载均衡策略。 工作流程&#xff1a; RoundRibbonRule…

fedora20开机启动配置:systemctl

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

Mysql 字符操作函数相关

常用的字符串函数&#xff1a; 函数说明CONCAT(s1,s2&#xff0c;...)返回一个或多个待拼接的内容&#xff0c;任意一个为NULL则返回值为NULL。CONCAT_WS(x,s1,s2,...)返回多个字符串拼接之后的字符串&#xff0c;每个字符串之间有一个x。SUBSTRING(s,n,len)、MID(s,n,len)两个…

“cvSnakeImage”: 找不到标识符

1>g:\project\opencv\helloopencv\helloopencv\helloopencv.cpp(74) : error C2065: “CV_VALUE”: 未声明的标识符1>g:\project\opencv\helloopencv\helloopencv\helloopencv.cpp(74) : error C3861: “cvSnakeImage”: 找不到标识符 增加头文件 #include <opencv2/l…

Shell 快速入门

个人博客 &#xff1a;https://www.siyuan.run CSDN&#xff1a;https://blog.csdn.net/siyuan 微信小程序&#xff1a;思远Y 概述 Shell 是一个用 C 语言编写的程序&#xff0c;它是用户使用 Linux 的桥梁。Shell 既是一种命令语言&#xff0c;又是一种程序设计语言。 Shell…

Andriod开发 --插件安装、环境配置、问题集锦

1.用Eclipse搭建Android开发环境和创建第一个Android项目&#xff08;Windows平台&#xff09; 链接阅读http://www.cnblogs.com/allenzheng/archive/2012/11/10/2762379.html 搭建环境中的不同之处&#xff1a; &#xff08;1&#xff09;我在安装过程中&#xff0c;在安装ADT…

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

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

Android之Http网络编程(四)

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

《Java 高并发》02 多线程的特性

多线程的三大特性&#xff1a;原子性、可见性和有序性。 原子性 原子性是指一个操作或者多个操作&#xff0c;一旦开始就不会被其他线程干扰&#xff0c;即使是在多个线程一起执行的情况下也不会被干扰。或者不执行。 原子性主要是为了保证数据一致&#xff0c;线程安全问题…