三次B样条拟合及一阶导、二阶导、曲率计算

1.三次钳位B样条拟合

公式如下图:
在这里插入图片描述
展开结果为:
r(u)=[(1-3u+3u2-u3)Pi + (4-6u2+3u3)Pi+1 + (1+3u+3u2-3u3)Pi+2 + (u3)Pi+3 ]/6
其中u取值范围为0到1,将4个控制点的坐标带入上式之后,生成的是Pi+1到Pi+2之间的一段平滑曲线。如果希望某个点必须出现在拟合后的曲线上,则需要让该点在控制点集中连续出现三次。
比如第一个点(0,0),使P0P1P2都为(0,0),后续的点正常排列。则使用上述参数化方程可得到通过这一系列点的拟合曲线,且该曲线必定通过第一个点。
拟合结果:

在这里插入图片描述
在这里插入图片描述

2.参数方程求切线、法线

以上式B样条参数方程为目标曲线,其一阶导和二阶导为:
r’(u)=[(-1+2u-u2)Pi + (-4u+3u2)Pi+1 + (1+2u-3u2)Pi+2 + (u2)Pi+3 ]/2
r’’(u)=[(1-u)Pi + (-2+3u)Pi+1 + (1-3u)Pi+2 + (u)Pi+3 ]
则dy/dx,d2y/dx2为:
f’=y’(u)/x’(u)
f’’=(x’y’’-x’’y’)/(x’)3
f曲率=(x’y’’-x’’y’)/(x’2+y’2)3/2
f’垂线=-1/y’
其中x(u)、y(u)将控制点的x、y坐标带入可得
在这里插入图片描述
最开始的代码没有保存,后来算曲率什么的改了很多,比较乱

% function [  ] = B_Spline( x,y )
%三次钳位B样条拟合
close all;
clear all;
clc;
x=[0.5,3,5,6,4,2];
y=[0.5,0,2,4,5,4];
% x=[0,1,2,3,4,5];
% y=[0,1,1,1,1,1];
plot(x,y,'o');
hold on;

x=[x(1),x(1),x(1),x(2:end),x(end),x(end)];%对起始点和结尾点进行重复处理,同一个点需重复出现3次,拟合后的曲线必定经过该点
y=[y(1),y(1),y(1),y(2:end),y(end),y(end)];

u=linspace(0,1,5);%参数u的取值范围为[0,1],5等分即表示会取两个原始点之间的拟合曲线上的5个点。
final_x=x(1);
final_y=y(1);
r1=[];
r=[];
for i=1:(length(x)-3)%通过B样条参数方程计算拟合后曲线的离散点
    px=(1-3.*u+3.*u.^2-u.^3).*x(i) + (4-6.*u.^2+3.*u.^3).*x(i+1) + (1+3.*u+3.*u.^2-3.*u.^3).*x(i+2) + u.^3.*x(i+3);
    py=(1-3.*u+3.*u.^2-u.^3).*y(i) + (4-6.*u.^2+3.*u.^3).*y(i+1) + (1+3.*u+3.*u.^2-3.*u.^3).*y(i+2) + u.^3.*y(i+3);
    px=px/6;
    py=py/6;
    final_x=[final_x,px];
    final_y=[final_y,py];
%     plot(px,py);
%     hold on;
    
    px1=(-1+2.*u-u.^2).*x(i) + (-4.*u+3.*u.^2).*x(i+1) + (1+2.*u-3.*u.^2).*x(i+2) + u.^2.*x(i+3);%B样条参数方程的一阶导
    py1=(-1+2.*u-u.^2).*y(i) + (-4.*u+3.*u.^2).*y(i+1) + (1+2.*u-3.*u.^2).*y(i+2) + u.^2.*y(i+3);
    px1=px1/2;
    py1=py1/2;
    px2=(1-u).*x(i) + (-2+3.*u).*x(i+1) + (1-3.*u).*x(i+2) + (u).*x(i+3);
    py2=(1-u).*y(i) + (-2+3.*u).*y(i+1) + (1-3.*u).*y(i+2) + (u).*y(i+3);
    tmpr1=abs(px1.*py2 + px2.*py1)./(px1.^2 + py1.^2).^1.5
    tmpr=1./(abs(px1.*py2 + px2.*py1)./(px1.^2 + py1.^2).^1.5)
    r1=[r1,tmpr1];
    r=[r,tmpr];
    
%     for j=1:length(px)%求拟合后曲线上每个点的垂线
%         k=-px1(j)/py1(j);0
%         lx=px(j)-0.1:0.1:px(j)+0.1;
%         ly=k.*(lx-px(j))+py(j);
%         plot(lx,ly);
%         hold on;
%     end
end

    plot(final_x,final_y);
    hold on;
    figure(2);
    plot(r);
    hold on;

% for i=1:(length(x))
%     plot(x(i),y(i));
%     hold on;
% end
% end
  • 11
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值