bezier([5,10,15,20,25],[0 8 10 9 1])
function [X,Y]=bezier(x,y) %定义这个子函数,可以被main调用,这里我们直接坐标赋值
x=[5,10,15,20,25]
y=[0 8 10 9 1]
n=length(x); %获取输入的坐标点的个数,例如:测试的X坐标[5,10,15,20,25]为作业要求4次曲线
t=linspace(0,1); % 改变式中的t值,则点就会在空间移动
xx=0; %初始化X
yy=0; %初始化Y
for k=0:n-1 %伯恩斯坦的一般形式,我们输入了5个坐标,因此是四次贝塞尔曲线
tmp=nchoosek(n-1,k)*t.^k.*(1-t).^(n-1-k); % nchoosek 来实现二项式系数或所有组合语法: C = nchoosek(n,k)
xx=xx+tmp*x(k+1); % X轴坐标
yy=yy+tmp*y(k+1); % Y轴坐标
end
if nargout==2 %输出参数的个是为2个时
X=xx;Y=yy;
end
h=plot(xx,yy); %画四次贝塞尔曲线
hold on %保留本曲线
m=plot(x,y); %画原始点
一个常量,可由一个点唯一确定
一条直线,可由两个点唯一确定
一条抛物线,可由三个点唯一确定
一条三次曲线,可由四个点唯一确定,并且它拥有一个拐点。
三次曲线是多项式曲线中拥有拐点的最高项次数最小的曲线。
拐点使它拥有非常有意义的作用,可以用它将多个点平滑地连接起来。
一条三次曲线,需要由四个系数的多项式来描述:
a+bx+cx2+dx3=y
a+bx+cx2+dx3=y
由已知的四个点,可以构造四个方程,解这四个方程即可求出四个系数。可由矩阵的逆运算得到:
Ma=y⇒a=M−1y
Ma=y⇒a=M−1y
矩阵运算使得用计算机求解非常容易。
边界条件
两个相邻曲线段在公共边界(控制点)处有相同的一阶和二阶导数,即自然三次样条具有二阶导数连续性
主要缺点
任意一个控制点发生了变动,则整条曲线都将受到影响。这样,自然三次样条不允许“局部控制”,因此不给出完整的新控制点集,则不可能构造曲线的一部分。
复杂的曲线,可以由多个三次曲线连续起来成形。(得益于拐点)
于是我们可以将曲线以每两点进行分段,分别求出两点间的三次曲线。
为了使这些三次曲线平滑地相连,我们约束连接点处必须是连续的,并且一次导数和二次导数都是连续的。于是通过两个点和两个约束,我们就有了四个方程,可解出该多项式的四个系数,同时保证它与相邻的三次曲线是连续的。(由于起始端点和结束端点没有导数,所以我们需要人工指定两个斜率)
将多段曲线同时置入一个矩阵,即可一次性求出全部系数。
到目前为止,我们已经了解了控制点序列如何使用三次方函数定义控制点之间的曲线段并在段连接处执行各种连续性级别,从而定义分段多项式曲线。 特别:
•C0连续性,表示两个线段匹配联接处的值。
•C1连续性,表示它们与连接处的斜率匹配。
•C2连续性,表示它们与连接处的曲率匹配
上面的方法得到的都是基于x轴的曲线,这并不好用。我们希望每段曲线都通过参数t描述:
f i ( t i ) = a i + b i t i + c i t i 2 + d i t i 3 ( 0 ⩽ t ⩽ 1 ) f_i(t_i)=a_i+b_it_i+c_it^2_i+d_it^3_i (0⩽t⩽1) fi(ti)=ai+biti+citi2+diti3(0⩽t⩽1)
在示例中,两条曲线是相同的,但是描述它们的方程式是不同的。 在右侧的参数形式中,我们定义了参数t0,t1和t2,它们在控制点之间沿x轴移动时在0和1之间变化。 我们可以写方程式:
关联t的原始x坐标。 导数表示每个t在我们沿x方向移动时有多快变化
Now we specify each curve segment by a parametric cubic curve
重要的是,这些量应在空间(即x)中而不是在参数坐标中计算,因为我们希望曲线在空间中平滑连接,而不是相对于我们的任意参数化而言
回顾之前的示例,我们没有进行参数化,因此可以重写所有方程式以及必须求解的最终线性系统。
这种方法的最大优势在于,因为我们已经知道所有系数的值,所以我们为每个控制点从矩阵中减少了一行和一列。
一旦您了解了分段参数化的概念,其余部分将以一种直接的方式进行。
将参数化后的曲线分别应用的两个坐标轴上,我们可以在2维平面上构造任意曲线!使其头尾相连,可形成环。
分类方法
给定一组控制点,有两种方式选取分段连续参数多项式函数:
插值样条:曲线经过控制点。
逼近样条:曲线不经过控制点。
所谓样条曲线(Spline Curves)是指给定一组控制点而得到一条曲线,曲线的大致形状由这些点予以控制,一般可分为插值样条和逼近样条两种,插值样条通常用于数字化绘图或动画的设计,逼近样条一般用来构造物体的表面。
样条插值是一种工业设计中常用的、得到平滑曲线的一种插值方法,三次样条又是其中用的较为广泛的一种
虽然多项式曲线已经这么牛逼,但是它使用一个矩阵来计算整个曲线,所以当用户调整其中的一个点的时候,会影响整个曲线的形状。这对造形来说是一个灾难,我们希望能够局部修改曲线。
为了实现这个需求,我们可以将多项式的两个约束改为用户指定每个分段两个端点的斜率,这样就可以将单点变化的影响缩小到局部了。多项式曲线变成了 Hemiter 曲线。
Hermite插值不仅满足在结点上与原函数相等,且各阶导数也相等。
在分段低次插值时候,可以选择分段线性插值和分段Hermite插值的方法,采用后者得到的结果即为Hermite样条。
与自然三次样条不同,Hermite样条可以局部调整,因为每个曲线端仅依赖于端点约束。
主要缺点
只有当被插值函数在所有插值点处的函数值和导数都已知的前提下才能使用,而且在内节点处,其二阶导数一般不连续。基于Hermite样条的改进方法是Cardinal样条和Kochenek-Bartels样条。
Hemiter 曲线要求用户提供每个点的斜率,并不是那么方便。 Catmul-Rom 提供了一种自动设置斜率的方法:每个点的斜率由前后两个点决定。
ti=12(pi+1−pi−1)ti+1=12(pi+2−pi)
Cardinal样条
类似于Hermite样条,Cardinal样条也是插值分段三次曲线,并且每条曲线的端点位置均指定切线。
与Hermite不同的是,Cardinal样条不一定要给出端点的切线值。
在cardinal样条中,一个控制点的斜率值可以由两个相邻控制点的坐标进行计算。
Cardinal 曲线为 Catmul-Rom 的斜率生成提供了一个可选参数t。当t=0时,Cardinal 曲线即为 Catmul-Rom 曲线。当 t>0 时,得到绷紧后的 Catmul-Rom 曲线。反之 t<0 时,得到松跨后的 Catmul-Rom 曲线。
ti=12(1−t)(pi+1−pi−1) ti+1=12(1−t)(pi+2−pi)
这是cardinal样条的扩展。将两个附加参数引入到约束方程中,可以得到Kochanek-Bartels样条,从而为调整曲线段形状提供更多方便。需要注意的是,导数在线段边界处不一定连续,因为 本样条的设计是为了模拟动画路径,特别是当对象运动有突变时。
Bezier曲线是BSpline的特例,虽然它也是分段多项式,但是Bezier多项式的次数并不是三,而是由将逼近控制点数量及相关位置决定。
特性
B样条曲线会经过每个型值点(型值点vs控制点),但是不经过控制点,也即是说,型值点是B样条曲线所经过的点,而控制点则是控制其形状的点。
优点
缺点
分类
B样条是一般化的beta样条,它是在beta样条的一阶和二阶导数上加上几何条件而形成的。
有理函数是两个多项式之比,因此有理样条是两个样条函数之比,例如有理B样条。
有理样条和非有理样条比,有两个重要的优点:
它们各有特点:
应用:在游戏中,常常给定一些坐标点,让角色逐一通过。角色在运动的时候,沿着这些点平滑地移动。所以我们需要有一些方法能求出通过给点坐标集合的曲线。
https://blog.csdn.net/while0/article/details/51513485
https://blog.csdn.net/weixin_34392435/article/details/86184081
http://blog.leanote.com/post/simon88/%E6%A0%B7%E6%9D%A1%E6%9B%B2%E7%BA%BF#title
教材:http://www.ae.metu.edu.tr/~ae464/splines.pdf