首页  >  文章  >  web前端  >  简单理解贝塞尔曲线。

简单理解贝塞尔曲线。

王林
王林原创
2024-08-16 11:04:02578浏览

想象一下,如果只能用直线、椭圆、圆,设计一辆线条流畅、外观复杂的汽车不是很困难吗?

1962年,法国工程师Pierre Bézier发表了贝塞尔曲线,最初用于汽车主体设计。

Simply understanding Bézier curves.

贝塞尔曲线可以通过一系列控制点定义一条平滑的曲线。曲线始终经过第一个和最后一个控制点,并受中间控制点形状的影响。此外,贝塞尔曲线具有凸包的性质。

贝塞尔曲线广泛应用于计算机图形和图像建模,例如动画、字体设计和工业设计。

公式

Simply understanding Bézier curves.

让我们了解一下。

P(t) 表示曲线上 t 处的点(t 是分数,值从 0 到 1)。 t 处曲线上的点是什么?常见的曲线描述是:y = f(x),现在让我们将 P(t) 理解为 f(x)。不同的是,P(t)是参数表示(计算结果是[x,y]这样的“向量”),后面会详细解释。

接下来,Pi代表第i个控制点(i从0开始)。以上图为例,有4个控制点,分别是P0、P1、P2、P3。公式中的n是控制点的最后一个索引,即n = 3(注意不是控制点的数量,而是计数减1)。

Bi,n(t) 是 Bernstein 基函数,也称为基函数。对于每个特定的(i,n),都有一个不同的基函数与之对应。如果从加权的角度理解,可以将基函数视为权重函数,表示第i个控制点Pi对t位置处的曲线坐标的“贡献”。

基函数的公式如下:

Simply understanding Bézier curves.

(ni)二项式{n}{i} (in 是组合数(从n中选择i有多少种方法?)。至于为什么基函数是这样的,可以结合De Casteljau算法来理解(见文中后面)

回到P(t)公式, Σi=0nsum_{i=0}^{n} Σ i=0n 为求和符号,表示后续部分( Bi,n(t)Pi B_{i,n}(t) cdot P_iBi,n(t) ⋅Pi ) 将从 i=0 到 i=n 求和。

以上图为例,假设我们要计算P(0.1),该怎么做呢?展开如下:

Simply understanding Bézier curves.

Simply understanding Bézier curves.

代入 t=0.1 得到:

Simply understanding Bézier curves.

曲线的参数表示

这里直接引用了网友的文章(链接)

Simply understanding Bézier curves.

让我们重点关注上面的公式。

如上图所示,我们熟悉的直线可以从另一个角度来理解:用t(即|AP|从点P到已知点(x0,y0)的长度),那么通过上面的三角函数就可以确定P点。

更一般地,可以写成:

Simply understanding Bézier curves.

这里,P0 是向量 [x0,y0],v 也是向量。加在一起后,P(t) 就是向量 [x,y]。

再看一下圆圈:

Simply understanding Bézier curves.

如图所示,圆可以看作有一个已知的圆心,圆上的任意一点都由旋转角度和半径确定。也可以写成:

Simply understanding Bézier curves.

参数方程保持几何不变性,并且可以表示圆形等形状(其中一个 x 对应多个 y 值)。

德卡斯特里奥

De Casteljau 算法是一种在实际应用中用于评估和近似 Bézier 曲线以进行绘图和其他操作的方法。相比之前基于定义的评估方法,速度更快、更稳定,更接近贝塞尔曲线的特性。

这里,我们参考了两篇文章:link1 和 link2

首先定义以下内容:

Simply understanding Bézier curves.

看上面的β。上标和下标有点混乱;你可以用下面的三角递归来理解:

Simply understanding Bézier curves.

上图中三角形的红边是除以t0的两条线段的控制点。为了更形象地理解t0,P(t0)(即 β0(n)beta_0^{(n)} β 0(n) ),两条曲线的控制点,可以参考下图:

Simply understanding Bézier curves.

上图展示了当t=0.5时各点之间的关系。

从“插值”的角度来看,计算过程也可以理解为:

  1. 求每对相邻控制点的中点(因为t=0.5),即b01,b11,b21(请原谅我的记法,用LaTeX写太麻烦了)
  2. 在 b01−b11 上求中点 b02,在 b11-b21 上求中点 b12
  3. 找到 b02−b12 上的中点 b03 ​ 其实De Casteljau算法的本质就是插值和迭代。

基于 De Casteljau 的曲线绘制

目前观察到两种方法。

一种方法涉及以小步增量将 t 从 0 遍历到 1(即0.01)。每次求 P(t) 时,都会使用递归公式来确定 β0(n)beta_0^{(n)} β 0(n) .

另一种方法是求P(t=0.5),然后对两条划分曲线分别求P(t=0.5)...这样的细分一直持续到曲线逼近为止。

执行

光看而不练习总感觉不真实。

所以我自己写了曲线绘制的实现代码,整理成一个工具包:Compilelife的Toolkit

对应的核心代码在这里

以上是简单理解贝塞尔曲线。的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn