基于MATLAB的B样条曲线插值算法

问题

​ 给定 5 5 5个数据点 Q 0 = ( − 2 , 1 ) , Q 1 = ( 0 , 0 ) , Q 2 = ( 1 , 0 ) , Q 3 = ( 3 , 5 ) , Q 4 = ( 4 , 2 ) \boldsymbol Q_0=(-2,1), \boldsymbol Q_1=(0,0),\boldsymbol Q_2=(1,0), \boldsymbol Q_3=(3,5), \boldsymbol Q_4=(4,2) Q0=(2,1),Q1=(0,0),Q2=(1,0),Q3=(3,5),Q4=(4,2), 结合累加弦长参数化方法及 3 3 3次样条插值方法给出一条 3 3 3次B样条曲线通过这 5 5 5个点.

工具

​ 为了解决上述问题, 我们采用MATLAB样条工具箱中的spapi​函数进行B样条曲线插值. 下面对需要用到的样条工具箱中的函数进行一个简要的说明, 关于样条工具箱更多的功能介绍可翻看之前的博客Matlab样条工具箱及曲线拟合_matlab 拟合工具箱_Daytoy Studio的博客-CSDN博客

名称功能
spapi插值生成B样条函数
fnval计算某点处样条函数的值
fnder求样条函数的导数
fnplt画样条曲线图

算法步骤

  • 将输入数据点进行累加弦长参数化, 假设有 m m m个点 { Q i } i = 1 m \{Q_i\}_{i=1}^{m} {Qi}i=1m, 则有

t 1 = 0 , t m = 1 , t i = t i − 1 + ∥ Q i − Q i − 1 ∥ / ∑ j = 1 m ∥ Q j − Q j − 1 ∥ , i = 2 , . . . , m − 1. t_1=0,t_m=1,t_i=t_{i-1}+\| Q_i-Q_{i-1}\|/\sum_{j=1}^m\|Q_j-Q_{j-1}\|,i=2,...,m-1. t1=0,tm=1,ti=ti1+QiQi1∥/j=1mQjQj1,i=2,...,m1.

累加弦长法是目前最常用的参数化方法, 它反映了数据点按弦长的分布情况, 其它参数化方法还包括均匀参数化, 向心参数化等.

  • 利用工具箱函数spapi进行 3 3 3次B样条插值, 并可以画出图像验证生成的曲线是否严格经过已知数据点;
  • 为了便于后续的应用, 这里增加了一步求导数, 并将其以切矢的形式画出验证是否与曲线相切.

实验结果

Binterpolation

至此, 上述一个简单的B样条曲线插值问题得以解决, 这里主要是为了给后续的工程应用进行一个铺垫, 下面给出具体的代码.

Code

function [T] = CumuPara(P)

%累加弦长参数化
%P输入数据点, 以列向量组成的矩阵, T累加弦长参数化得到的参数

m=size(P,2);%数据点个数
T=zeros(1,m);
sum_chord=0;
for j=1:m-1
    sum_chord=sum_chord + norm(P(:,j+1)-P(:,j),2);
end
chord=0;
for i=2:m-1
    chord=chord+norm(P(:,i)-P(:,i-1),2);
    T(i)=chord/sum_chord;
end
T(m)=1;
end
% 输入数据点
P=[-2,0,1,3,4;...
    1,0,0,5,2];
figure;
scatter(P(1,:),P(2,:),'bo');
hold on

% 累加弦长参数化
T=CumuPara(P);

% B样条阶数
k=4;

% 3次B样条插值
sp=spapi(k,T,P);

% 画图
fnplt(sp,'r-');
hold on

% 计算导数值
dsp=fnder(sp,1);
dp=fnval(dsp,T);

% 切矢画图
len=size(T,2);

for i=1:len
    dir=dp(:,i)/norm(dp(:,i));
    plot([P(1,i),P(1,i)+dir(1)],[P(2,i),P(2,i)+dir(2)],'k'); % 切矢
    hold on
end

Reference

@book{王仁宏2008计算几何教程,
  title={计算几何教程},
  author={王仁宏 and 李崇君 and 朱春钢},
  publisher={计算几何教程},
  year={2008},
}
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值