计算机图形学十:几何2—贝塞尔曲线(Bézier Curves)与贝塞尔曲面(Bézier Surfaces)
贝塞尔曲线与贝塞尔曲面
- 1 贝塞尔曲线(Bézier Curves)
- 2 贝塞尔曲面(Bézier Surfaces)
- Reference
(本篇文章同步发表于知乎专栏:https://zhuanlan.zhihu.com/p/144399638 欢迎三连关注)
1 贝塞尔曲线(Bézier Curves)
在进入具体原理讲解之前,首先看一下一条实际的贝塞尔曲线长什么样子
其中 p 0 , p 1 , p 2 , p 3 p_0,p_1,p_2,p_3 p0,p1,p2,p3为控制点,蓝色所表示曲线正是非常著名的贝塞尔曲线了,可以从图中观察到,曲线会与初始与终止端点相切,并且经过起点 p 0 p_0 p0与终点 p 3 p_3 p3。那么这样一条曲线究竟是怎么得到的呢?
其实贝塞尔曲线的定义很像参数方程,给定一个参数 t ∈ [ 0 , 1 ] t\in[0,1] t∈[0,1]就能确定贝塞尔曲线上的一点,倘若取完所有t值,就能得到完整的贝塞尔曲线,了解一下大概之后,接下来我们就开始介绍计算曲线的过程。
首先从简单的3个控制点情形出发,示意如何画出曲线。
(n个控制点得到的是n-1次曲线,如图中3个控制点便是2次贝塞尔曲线)
正如一开始所说,第一步选定一个参数 t ∈ [ 0 , 1 ] t\in[0,1] t∈[0,1],在 b 0 b 1 b_0b_1 b0b1线段之上利用t值进行线性插值:
即 b 0 1 = b 0 + t ∗ ( b 1 − b 0 ) b_0^1 = b_0+t*(b_1-b_0) b01=b0+t∗(b1−b0),得到 b 0 1 b_0^1 b01 之后在 b 1 b 2 b_1b_2 b1b2线段上重复做相同的线性插值得到点 b 1 1 b_1^1 b11:
通过给点参数 t t t 计算得到点 b 0 1 , b 1 1 b_0^1,b_1^1 b01,b11之后将两点连接,相信许多读者都能猜到下一步是什么了,没错就是在 b 0 1 b 1 1 b_0^1b_1^1 b01b11线段之上再进行一次线性插值!
如此便成功获得了如图所示的3个控制点之下的2次贝塞尔曲线上的一点 b 0 2 b_0^2 b02 了,那么对所有的 t ∈ [ 0 , 1 ] t\in[0,1] t∈[0,1]都重复上述的过程,就可以得到上图所示的蓝色贝塞尔曲线了。通过这样一个简单的3个控制点的例子,相信很快就能理解贝塞尔曲线的原理,那么对于4个控制点,5个控制点,乃至任意控制点步骤都是类似的。
其核心所在就是多次的线性插值,并在生成的新的顶点所连接构成的线段之上递归的执行这个过程,直到得到最后一个顶点
如下图这样一个4个控制顶点的例子,步骤完全类似:
那么我们为何称由n个控制点的贝塞尔曲线为n-1次呢?同样以一开始的3个控制点为例,将贝塞尔曲线方程完全展开看看
其实看到这就已经非常清楚了,最终得到的贝塞尔曲线方程恰好就是一个关于参数 t 的二次方程,如果细心观察的话,其实可以发现控制点的系数是非常有规律的,很像二项系数,因此可以总结规律得到一个任意控制点组成的贝塞尔曲线的方程如下:
对于这样一个特殊系数其实也有一个多项式与之对应,正是伯恩斯坦多项式,其定义如图中下方所示。
好了至此就是贝塞尔曲线原理的所有内容了,相信显现在对于任意的控制点,都能很快的画出对应的曲线,最后我们对贝塞尔曲线的几点性质做一个概括:
1 必定经过起始与终止控制点
2 必定经与起始与终止线段相切
3 具有仿射变换性质,可以通过移动控制点移动整条曲线
4 凸包性质,曲线一定不会超出所有控制点构成的多边形范围
回想一下PS等具有画图功能的软件中的钢笔工具所运用的便是贝塞尔曲线了,除了这个例子之外许多字体或是矢量图都广泛运用了贝塞尔曲线。但对于高阶贝塞尔曲线它有一个严重的缺陷:
对于上图所示的由11个控制点所得到的10次贝塞尔曲线,由于控制点众多,很难控制局部的贝塞尔曲线形状,因此为了解决该问题,有人提出了分段贝塞尔曲线,即将一条高次曲线分成多条低次曲线的拼接,其中用的最多的便是用很多的3次曲线来拼接,如下图:
(注:上图是一个贝塞尔曲线的网页demo,有兴趣读者可以去玩玩)
如果想要使得拼接的点看起来较为光滑的话,就要满足一些连续条件如一阶连续(连接点导数的左右极限相等),二阶连续等等,这些都是高数的基础知识,在此不多做赘述。
对于本文来说,贝塞尔曲线到这里就已经讲解完毕了,但其实除了贝塞尔曲线之外还有B样条曲线,NURBS曲线等等。简单说两句
B样条曲线相对于贝塞尔曲线可以更好的进行局部控制
NURBS曲线可以得到一些B样条曲线无法精准描述的圆锥曲线,如下图:
相对于贝塞尔曲线来说,这两种曲线更加深入与复杂,读者可以自行收集资料,本文不作过多展开
2 贝塞尔曲面(Bézier Surfaces)
其实在理解了贝塞尔曲线之后,贝塞尔曲面的原理也是十分容易理解的了,无非是一个从2维到3维的过渡。
如果说对于曲线来说只有一个参数 t ∈ [ 0 , 1 ] t\in[0,1] t∈[0,1]那么对于一个面来说,就应该有两个参数,分别设 u ∈ [ 0 , 1 ] u\in[0,1] u∈[0,1], v ∈ [ 0 , 1 ] v\in[0,1] v∈[0,1],具体过程如下图所示:
首先规定一共4x4 = 16个控制点,其水平面位置如图中16个黑点所示(并未表示出高度,防止图形太乱),将这16个点分成4列,图中红色圈中的为一列的具体例子。
第1步 在这4个控制点之下利用第一个参数 u u u 运用第一章的计算贝塞尔曲线的方法得到蓝色点,因为有4列,所以一共可以得到如图所示的4个蓝色点。(灰色曲线分别为每列4个点所对应的贝塞尔曲线)
第2步 在得到4个蓝色顶点之后,在这四个蓝色顶点的基础之下利用第二个参数 v v v 便可以成功得出贝塞尔曲面上的正确一点
第3步 遍历所有的 u,v值就可以成功得到一个贝塞尔曲面
到这里整个几何部分的大部分内容就已经讲解完毕了,做个预告,在下篇笔记也是几何的最后一部分我们会去介绍细分曲面的相关知识
Reference
[1] GAMES101-现代计算机图形学入门-闫令琪
[2] 电子科技大学计算机图形学PPT
计算机图形学十:几何2—贝塞尔曲线(Bézier Curves)与贝塞尔曲面(Bézier Surfaces)相关推荐
- 计算机图形学(几何)
笔记:几何 概述 Implicit(隐式几何) Explicit(显式几何) Implicit(隐式几何)表示方法 Explicit(显式几何)表示方法 Curves(曲线) Bézier Curve ...
- html5贝塞尔曲线,Canvas学习:贝塞尔曲线
在绘制圆和圆弧一节中,了解到在Canvas中可以使用arc()和arcTo()绘制制圆或弧线,但很多时候,仅这两个方法还不能满足我们实际的需求,特别是绘制复杂的曲线.不过值得庆幸的是,在Canvas中 ...
- android贝塞尔曲线实例,android中贝塞尔曲线的应用示例
前言: 贝塞尔曲线又称贝兹曲线,它的主要意义在于无论是直线或曲线都能在数学上予以描述.最初由保罗·德卡斯特里奥(Paul de Casteljau)于1959年运用德卡斯特里奥演算法开发(de Cas ...
- 【XJTUSE计算机图形学】第三章 几何造型技术(1)——参数曲线和曲面
文章目录 [XJTUSE计算机图形学]第三章 几何造型技术(1)--参数曲线和曲面 参数曲线和曲面 曲线曲面参数表示 非参数表示 参数表示 曲线的基本概念 插值.拟合和光顺(掌握概念) 参数化 概念 ...
- 贝塞尔曲线(Bezier Curves)
贝塞尔曲线 空间贝塞尔曲线(Spatial B′ ezier Curves) 当贝塞尔曲线的控制点为三维坐标时,即可得到空间贝塞尔曲线. 空间空间贝塞尔曲线任然满足性质: 端点插值性质: 端点切线定理 ...
- 贝塞尔曲线 三维 拼接 matlab,贝塞尔曲线公式
给出了用 2m-1 次贝塞尔曲线逼 近 2m 次贝塞尔曲线的封闭的计算公式,推广了文献[1]中给出的降一次逼近时 的误差估计公式,并得到了封闭的形式.为 CAD 系统的...... 第9期 机械设计与 ...
- 【HTML 中的二次贝塞尔曲线 和三次贝塞尔曲线】(使用说明详解)
二次 贝塞尔曲线 和三次 贝塞尔曲线 使用说明 1. 二次 贝塞尔曲线 和三次 贝塞尔曲线 1.1 贝塞尔曲线的 基本知识 1.2 贝塞尔曲线 生成动图 1.3 HTML 中 画贝塞尔曲线的 2 种方 ...
- android 贝塞尔曲线_OpenGL 实践之贝塞尔曲线绘制
说到贝塞尔曲线,大家肯定都不陌生,网上有很多关于介绍和理解贝塞尔曲线的优秀文章和动态图. 以下两个是比较经典的动图了. 二阶贝塞尔曲线: 三阶贝塞尔曲线: 由于在工作中经常要和贝塞尔曲线打交道,所以简 ...
- 二次贝塞尔曲线转换为三次贝塞尔曲线
二次贝塞尔曲线转换为三次贝塞尔曲线 在使用cairo绘图的时候,发现cairo不支持二次贝塞尔曲线的绘制,为了与QT实现的canvas的行为一致,cairo必须同样实现二次贝塞尔曲线的绘制.思路是将二 ...
最新文章
- 从ICLR提交论文看机器学习的趋势和风口
- Scala(三):类
- Java实现Runnable接口创建多线程
- 整合spring cloud云架构 - SSO单点登录之OAuth2.0 登出流程(3)
- 由CloudStack项目引起的ESXI嵌套虚拟化引起的二级虚拟机无法被访问
- java 拉取收件箱邮件源码_邮件提醒系统:新邮件识别
- Java-得到 Class 类的几种方式
- thinkPHP伪静态,如何去掉index.php呢?
- 南怀瑾先生说中风急救关键(非常推荐!!)
- 190216每日一句
- C#设置鼠标光标为自定义图片
- Delphi 连接 Excel
- 【NodeJs】NodeJs中base16转码
- python可执行程序必须以管理员_Python实现管理员权限运行CMD指令
- dfuse 发布全新 EOSIO 链迁移工具
- 《三体》里的超级计算机_我们今天能造出来吗?
- unity实现太空场景
- 《Microduino实战》——导读
- 解决 mapping values are not allowed here
- python爬虫--cookie、防盗链、代理