当前位置: 首页 > news >正文

B样条曲线计算

1、B样条基本概念

1.1 B样条表示

其中,为控制顶点(共n+1个控制点),控制点对应的参数序列即节点矢量

根据节点矢量的节点分布情况不同,可分为均匀B样条曲线(节点矢量中节点沿参数轴等距分布,所有节点区间长度),准均匀B样条曲线(两端节点重复度k+1,内节点均匀分布),一般非均匀B样条曲线(节点矢量任意分布,只需要在数学上成立,节点序列非递减,两端节点重复度≤k+1,内节点重复度≤k,节点个数n+k+2)。

对于开曲线,一般把两端节点取重复度k+1,即。剩下只需确定内节点值,共n-k个。

1.2 节点向量设置

确定内节点值的Hartley-Judd算法

其中,为控制多边形的边长,,于是得到节点值:

2、B样条曲线求值和求导的德布尔算法

理论:

给定控制顶点、次数k、节点矢量后,就定义了一条k次B样条曲线。若给出曲线定义域内一参数值,可以用德布尔递推方法计算出曲线上对应的点

德布尔算法的几何意义:从控制多边形开始进行k-1层割角。如下图所示。

求值公式为:(这里的r是重复度)

求r阶导矢:

先递推计算r阶导矢下的控制点,再按照k-r阶曲线求值。经过r级递推,计算出第r级的k-r+1个中间顶点,然后计算这些顶点与相关节点所定义的k-r次B样条曲线上参数为u的点。

代码实现:

function [px, py] = GetBPr(r, k, u, xVertex, yVertex, aNode, KnotMark) %------------------------------------------------------------ % 用德布尔算法求k次平面B样条曲线上参数u处的r阶导矢 % % 输入: % r - 导矢阶数 % k - B样条次数 % u - 参数 % xVertex - 控制点x坐标 % yVertex - 控制点y坐标 % aNode - 节点矢量 % KnotMark - 节点导矢选择 % 0: 右导矢 % 1: 左导矢 % % 输出: % px,py - u处r阶导矢 % %------------------------------------------------------------ %% 1. 判断阶数 if r > k px = 0; py = 0; return; end %% 2. 查找u所在节点区间 nNode = length(aNode); i = nNode-k-1; %matlab最低索引1 while i >= 1 if u >= aNode(i) break; end i = i-1; end if u < aNode(k+1) i = k+1; end %% 3. 一次B样条特殊情况 if (k==1 && r==1) && ... (u~=aNode(i) || (u==aNode(i) && KnotMark==0)) px = (xVertex(i)-xVertex(i-1)) / ... (aNode(i+1)-aNode(i)); py = (yVertex(i)-yVertex(i-1)) / ... (aNode(i+1)-aNode(i)); return; end if (k==1 && r==1 && KnotMark==1) px = (xVertex(i-1)-xVertex(i-2)) / ... (aNode(i)-aNode(i-1)); py = (yVertex(i-1)-yVertex(i-2)) / ... (aNode(i)-aNode(i-1)); return; end %% 4. 计算节点重复度 if i>k+1 && i<=length(xVertex) Multiple = 1; ii = i; while u == aNode(ii-1) Multiple = Multiple + 1; ii = ii - 1; end % 对于节点重复的情况(例如u4=u5=u6),选择左边的导矢(i=4) if k>1 && KnotMark==1 && ... u==aNode(i) && i~=k+1 i = i - Multiple; end end %% 5. 取影响当前点的k+1个控制点 tempx = zeros(k+1,1); tempy = zeros(k+1,1); index = 1; for j=i-k:i tempx(index)=xVertex(j); tempy(index)=yVertex(j); index=index+1; end %% 6. 求r阶导控制点 if k>1 for l=1:r for j=i-k:i-l jj=j-(i-k)+1; du = aNode(j+k+1)-aNode(j+l); beta = (k-l+1)/du; tempx(jj)=beta*(tempx(jj+1)-tempx(jj)); tempy(jj)=beta*(tempy(jj+1)-tempy(jj)); end end end %% 7. de Boor算法 for l=1:(k-r) for j=i-k:i-l-r jj=j-i+k+1; du=aNode(j+k+1)-aNode(j+r+l); if du==0 alpha=0; else alpha=(u-aNode(j+r+l))/du; end tempx(jj)=... (1-alpha)*tempx(jj)+... alpha*tempx(jj+1); tempy(jj)=... (1-alpha)*tempy(jj)+... alpha*tempy(jj+1); end end %% 8. 输出 px=tempx(1); py=tempy(1); end

3、B样条最小二乘拟合

理论:

预先计算数据点的参数值和节点矢量。设给定m+1个有序数据点,…,逼近曲线的次数为k,寻找一条k次B样条曲线:

满足端点约束,即两端数据点,其余数据点在最小二乘意义上被逼近,即目标函数:

是关于n-1个控制顶点的最小值。

注意:不是在曲线上距离最近的点。

使目标函数最小,则使其对于n-1个控制顶点的导数等于零。

于是

是一个以为未知量的线性方程。令,得到n-1个线性方程。写成矩阵形式:


代码实现:(没考虑首末端点的约束,实现结果和matlab的spap2一致)

% B样条最小二乘拟合函数 function [D,U_2] = getD_B_approx(NumCtrl,k,points) % 输入: % k:曲线次数 % t:节点矢量 % x:数据点参数序列 % M:数据点坐标(每一列是一个数据点) %% 数据点弦长参数化 du=sqrt(diff(points(1,:)).^2+diff(points(2,:)).^2); points_u=[0 cumsum(du)]; points_u=points_u/points_u(end); %% 获取节点矢量 U = getU(NumCtrl,k,points_u,points); U_2 = getU_2(NumCtrl,k,points_u); %% 最小二乘拟合 D = k_bspline_approx(k,U_2,points_u,points); end %=========== 计算基函数 ===============% function [y,x] = k_bspline_basis(j,k,t,x) % B-spline basis function value B(j,n) at x. % % Input arguments: % j: 第j个基函数 % interval index, 0 =< j < numel(t)-n % k: 次数 % B-spline order (2 for linear, 3 for quadratic, etc.) % t: 节点矢量 % knot vector % x (optional): 所求值的位置 % value where the basis function is to be evaluated % % Output arguments: % y: % B-spline basis function value, nonzero for a knot span of n % Copyright 2010 Levente Hunyadi n=k+1; validateattributes(j, {'numeric'}, {'nonnegative','integer','scalar'}); validateattributes(n, {'numeric'}, {'positive','integer','scalar'}); validateattributes(t, {'numeric'}, {'real','vector'}); assert(all( t(2:end)-t(1:end-1) >= 0 ), ... 'Knot vector values should be nondecreasing.'); if nargin < 4 x = linspace(t(n), t(end-n+1), 100); % allocate points uniformly else validateattributes(x, {'numeric'}, {'real','vector'}); end assert(0 <= j && j < numel(t)-n, ... 'Invalid interval index j = %d, expected 0 =< j < %d (0 =< j < numel(t)-n).', j, numel(t)-n); y = k_bspline_basis_recurrence(j,k,t,x); end function y = k_bspline_basis_recurrence(i,k,t,u) y = zeros(size(u)); if k > 0 % 求下一阶N_i,k-1(u) b = k_bspline_basis(i,k-1,t,u); % (u-u_i)/(u_i+k-u_i) dn = u - t(i+1); dd = t(i+k+1) - t(i+1); % 第一项 if dd ~= 0 % indeterminate forms 0/0 are deemed to be zero y = y + b.*(dn./dd); end % 求下一阶N_i+1,k-1(u) b = k_bspline_basis(i+1,k-1,t,u); % (u_i+k+1-u)/(u_i+k+1-u_i+1) dn = t(i+k+1+1) - u; dd = t(i+k+1+1) - t(i+1+1); % 第二项 if dd ~= 0 y = y + b.*(dn./dd); end elseif t(i+2) < t(end) % treat last element of knot vector as a special case % k=0最低级的时候 % N_i,0 y(t(i+1) <= u & u < t(i+2)) = 1; else % 最后一个节点特殊处理,没有右边界 y(t(i+1) <= u) = 1; end end function [B,x] = k_bspline_basismatrix(k,t,x) % B-spline basis function value matrix B(n) for x. % % Input arguments: % n: % B-spline order (2 for linear, 3 for quadratic, etc.) % t: % knot vector % x (optional): % an m-dimensional vector of values where the basis function is to be % evaluated % % Output arguments: % B: % a matrix of m rows and numel(t)-n columns % Copyright 2010 Levente Hunyadi n=k+1; if nargin > 2 B = zeros(numel(x),numel(t)-n); for j = 0 : numel(t)-n-1 B(:,j+1) = k_bspline_basis(j,k,t,x); %第j+1列 end else [b,x] = k_bspline_basis(0,k,t); B = zeros(numel(x),numel(t)-n); B(:,1) = b; for j = 1 : numel(t)-n-1 B(:,j+1) = k_bspline_basis(j,k,t,x); end end end function D = k_bspline_approx(k,t,x,M) % B-spline curve control point approximation with known knot vector. % % Input arguments: % k: % B-spline order (2 for linear, 3 for quadratic, etc.) % t: % knot vector % x: % B-spline values corresponding to which data points are observed % M: % d-by-m matrix of observed data points, possibly polluted with noise, % d is typically 2 for plane, 3 for space, or 3 or 4, respectively, if % weights are present % % Output arguments: % D: % d-by-n matrix of control points % Copyright 2010 Levente Hunyadi validateattributes(k, {'numeric'}, {'positive','integer','scalar'}); validateattributes(t, {'numeric'}, {'real','vector'}); validateattributes(x, {'numeric'}, {'real','vector'}); validateattributes(M, {'numeric'}, {'real','2d'}); B = k_bspline_basismatrix(k,t,x); Q = M * B; D = Q / (B'*B); end function U = getU_2(NumCtrl,k,u) % 输入: % NumCtrl:控制点数量 % k:曲线次数 % u:数据点参数序列 % points:数据点坐标 % 数据点数量 num_dataPoint = length(u); % 从数据点均匀挑选 index = round(linspace(1,num_dataPoint,NumCtrl)); index = unique(index); % 防止重复索引 t=u(index); p=k+1; t = t(:); n = length(t)-p; if p<2, error(message('SPLINES:AVEKNT:wrongk')) elseif n<0, error(message('SPLINES:AVEKNT:toofewknots')) elseif p==2, tstar = reshape(t(1+[1:n]),1,n); else temp = repmat(t,1,p-1); temp = sum(reshape([temp(:);zeros(p-1,1)],n+p+1,p-1).')/(p-1); tstar = temp(1+[1:n]); end U=[zeros(1,k+1),tstar,ones(1,k+1)]; end

http://www.jsqmd.com/news/1392548/

相关文章:

  • 第6章 时域递归滤波:IIR滤波器在视频降噪中的应用
  • 2026微信小程序开发费用需要多少?哪个更具性价比?
  • 从零到一带你速通DeepSeek Harness
  • 极空间部署OneNav实战:书签分类、数据保存与公网访问
  • Easy Image X v3 26X4 深度解析:步进式装机、部署预设与无人值守直达桌面
  • 沃尔玛购物卡回收平台怎么选?看折扣与到账两个指标 - 圆圆收
  • 2026不锈钢飘带雕塑厂家选购指南及实力参考 - 曲阳嘉华园林
  • DWMBlurGlass窗口毛玻璃美化完全指南:4种材质怎么选,Win10/11标题栏一步到位的界面美化方案
  • 重庆宠物医院助理医生岗前培训 2026 想学宠物临床实操去哪里 - 湖北找学校
  • 长沙AI大模型开发培训行业评测 正规机构课程与师资配置整理 - 梦想蓝途
  • 2026年头盔安全插扣源头厂家供应商推荐:批量采购选型指南 - 汇聚至此
  • 【数据结构】二叉树的存储结构(顺序/链式)
  • 那五个永远调不对大小的窗口,终于有救了:Window Resizer 强制调整窗口大小实操指南
  • 2026年地坪漆十大品牌选型全指南:正规合规服务商盘点、多场景适配解析及签约避坑实用FAQ - 商业大观
  • 破解物理AI技术困局(37):TVA攻克多智能体协同难题
  • 多智能体应用实战 | Agent不是玩具,是生产力——OpenClaw六大企业应用场景与落地价值
  • 瓦努阿图绿卡到底靠不靠谱?这几类人办了才不亏 - 优企甄选
  • 黑苹果EFI配置从8小时缩到50分钟:OpCore-Simplify如何把复杂留给自己
  • 笔试面试一站式,考编上岸选博傲 - 博傲教育
  • 2026广东建筑资质办理选购指南|6家服务商测评+高驳回率破局方案+六大避坑要点 - 优质品牌中立测评推荐
  • 资源编号:339 | 高德地图 9.1.87(车机定制版)
  • 2026地坪行业核心品牌实力对比全解析:资质/产能/案例/服务多维度选型指南+合作避坑FAQ - U渠道
  • 第三章 Netty 网络编程深度解析:从 HTTP 协议处理到自定义协议设计实战
  • 2026年景德镇新媒体运营推广正规服务商中网创信教你如何选择?服务模式、交付能力与避坑要点 - 中国品牌价值观察网
  • Day49-AI微服务化-将大模型能力封装为标准微服务
  • 2026年构建现代化芯产业体系,国内半导体博览会哪家好? - 2027品牌AI展
  • 破解物理AI技术困局(43):TVA攻克长周期稀疏奖励难题
  • AI的「梦」-龍德明宇
  • 筑牢高端装备“度量基石”:笛灵科技以自主创新赋能精密测量产业 - 甄选测评馆
  • 生命涌现的小龙虾技能之【Feed Intake Estimation | 畜禽采食量估算】简介