当前位置:   article > 正文

学习笔记:B样条曲线法_准均匀b样条曲线

准均匀b样条曲线

一、算法简介

1、样条是一根富有弹性的细木条或塑料条,在应用CAD/CAM技术以前,航空、船舶和汽车制造业普遍采用手工绘制自由曲线。绘制员用压铁压住样条,使其通过所有给定的型值点,再适当地调整压铁,改变样条形态,直到符合设计要求。

2、B样条曲线是B-样条基函数(给定区间上的所有样条函数组成一个线性空间)的线性组合。

二、算法思想

贝塞尔曲线有以下缺陷:
1、确定了多边形的顶点数(n+1),也就决定了所定义的Bezier曲线的阶次(n次),这样很不灵活。
2、当顶点数(n+1)较大时,曲线的次数较高,曲线的导数次数也会较高,因此曲线会出现较多的峰谷值。
3、贝塞尔曲线无法进行局部修改。
B样条曲线除了保持Bezier曲线所具有的有点外,还弥补了上述所有的缺陷。

三、算法过程

1、均匀B样条曲线:当节点沿参数轴均匀等距分布,为均匀B样条曲线,如U={0,1,2,3,4,5,6}。当n和k一定时,均匀B样条的基函数呈周期性,所有基函数有相同形状,每个后续基函数仅仅是前面基函数在新位置上的重复。

2、准均匀B样条曲线:两端节点具有重复度k,中间节点非递减的序列,如U ={0,0,0,1,2,3,4,5,5,}准均匀B样条曲线保留了贝塞尔曲线在两个端点处的性质:样条曲线在端点处的切线即为倒数两个端点的连线。准均匀B样条曲线用途最为广泛。

3、一般来说,次数越高,则曲线的导数次数也会较高,那么将会有很多零点存在,较多的导数零点就导致原曲线存在较多的极值,使曲线出现较多的峰谷值;次数越低,样条曲线逼近控制点效果越好。

4、另一方面,三次B样条曲线能够实现二阶导数连续,故最终选择准均匀三次B样条曲线作为轨迹规划的曲线比较合适。

 

  1. function NodeVector = U_quasi_uniform(n, k)
  2. % 准均匀B样条的节点向量计算,共n+1个控制顶点,k次B样条,k+1
  3. NodeVector = zeros(1, n+k+2);
  4. piecewise = n - k + 1; % 曲线的段数
  5. if piecewise == 1 % 只有一段曲线时,n = k
  6. for i = k+2 : n+k+2
  7. NodeVector(1, i) = 1;
  8. end
  9. else
  10. flag = 1; % 不止一段曲线时
  11. while flag ~= piecewise
  12. NodeVector(1, k+flag+1) = NodeVector(1, k + flag) + 1/piecewise;
  13. flag = flag + 1;
  14. end
  15. NodeVector(1, n+2 : n+k+2) = 1; % 节点向量前面和后面有(k+1)个重复值(阶数)
  16. end
  1. % B样条曲线法
  2. % 作者:Ally
  3. % 日期:2021/2/6
  4. clc
  5. clear
  6. close all
  7. %% 数据定义
  8. k = 4; % k阶、k-1次B样条
  9. flag = 2; %1,2分别绘制均匀B样条曲线、准均匀B样条曲线
  10. d = 3.5;
  11. P=[0, 10, 25, 25, 40, 50;
  12. -d/2,-d/2,-d/2+0.5,d/2-0.5,d/2,d/2 ]; %n=5, 6个控制点,可以满足曲率连续
  13. n = size(P,2)-1; % n是控制点个数,从0开始计数
  14. %% 生成B样条曲线
  15. path=[];
  16. Bik = zeros(n+1, 1);
  17. if flag == 1 % 均匀B样条
  18. NodeVector = linspace(0, 1, n+k+1); %节点矢量
  19. for u = (k-1)/(n+k+1) : 0.001 : (n+2)/(n+k+1)
  20. for i = 0 : 1 : n
  21. Bik(i+1, 1) = BaseFunction(i, k-1 , u, NodeVector);
  22. end
  23. p_u = P * Bik;
  24. path = [path; [p_u(1,1),p_u(2,1)]];
  25. end
  26. elseif flag == 2 % 准均匀B样条
  27. NodeVector = U_quasi_uniform(n, k-1); % 准均匀B样条的节点矢量
  28. for u = 0 : 0.005 : 1-0.005
  29. for i = 0 : 1 : n
  30. Bik(i+1, 1) = BaseFunction(i, k-1 , u, NodeVector);
  31. end
  32. p_u = P * Bik;
  33. path=[path; [p_u(1),p_u(2)]];
  34. end
  35. else
  36. fprintf('error!\n');
  37. end
  38. %% 画图
  39. d = 3.5; % 道路标准宽度
  40. W = 1.8; % 汽车宽度
  41. L = 4.7; % 车长
  42. figure
  43. len_line = 50;
  44. P0 = [0, -d/2];
  45. % 画灰色路面图
  46. GreyZone = [-5,-d-0.5; -5,d+0.5; len_line,d+0.5; len_line,-d-0.5];
  47. fill(GreyZone(:,1),GreyZone(:,2),[0.5 0.5 0.5]);
  48. hold on
  49. fill([P0(1),P0(1),P0(1)-L,P0(1)-L],[-d/2-W/2,-d/2+W/2,-d/2+W/2,-d/2-W/2],'b')
  50. % 画分界线
  51. plot([-5, len_line],[0, 0], 'w--', 'linewidth',2); %分界线
  52. plot([-5,len_line],[d,d],'w','linewidth',2); %左边界线
  53. plot([-5,len_line],[-d,-d],'w','linewidth',2); %左边界线
  54. % 设置坐标轴显示范围
  55. axis equal
  56. set(gca, 'XLim',[-5 len_line]);
  57. set(gca, 'YLim',[-4 4]);
  58. % 绘制路径
  59. scatter(path(:,1),path(:,2),100, '.b');%路径点
  60. scatter(P(1,:),P(2,:),'g')
  61. plot(P(1,:),P(2,:),'r');%路径点
  1. function Bik_u = BaseFunction(i, k , u, NodeVector)
  2. if k == 0 % 0次B样条
  3. if u >= NodeVector(i+1) && u < NodeVector(i+2)
  4. Bik_u = 1;
  5. else
  6. Bik_u = 0;
  7. end
  8. else
  9. Length1 = NodeVector(i+k+1) - NodeVector(i+1);
  10. Length2 = NodeVector(i+k+2) - NodeVector(i+2); % 支撑区间的长度
  11. if Length1 == 0 % 规定0/0 = 0
  12. Length1 = 1;
  13. end
  14. if Length2 == 0
  15. Length2 = 1;
  16. end
  17. Bik_u = (u - NodeVector(i+1)) / Length1 * BaseFunction(i, k-1, u, NodeVector) ...
  18. + (NodeVector(i+k+2) - u) / Length2 * BaseFunction(i+1, k-1, u, NodeVector);
  19. end

学习自B站:小黎的Ally

视频链接:路径规划与轨迹跟踪系列算法学习_第8讲_B样条曲线法_哔哩哔哩_bilibili

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/891583
推荐阅读
相关标签
  

闽ICP备14008679号