贝塞尔曲线(Bezier Curve)原理及公式推导

1. 定义

贝塞尔曲线(Bezier curve),又称贝兹曲线贝济埃曲线,是应用于二维图形应用程序的数学曲线。一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段节点组成,节点是可拖动的支点,线段像可伸缩的皮筋,我们在绘图工具上看到的钢笔工具就是来做这种矢量曲线的。贝塞尔曲线是计算机图形学中相当重要的参数曲线,在一些比较成熟的位图软件中也有贝塞尔曲线工具,如PhotoShop等。

贝塞尔曲线的一些特性:

  • 使用 n n n个控制点 { P 1 , P 2 , . . . , P n } \{P_1,P_2,...,P_n\} {P1​,P2​,...,Pn​}来控制曲线的形状
  • 曲线通过起始点 P 1 P_1 P1​和终止点 P n P_n Pn​,接近但不通过中间点 P 2 P_2 P2​~ P n − 1 P_{n-1} Pn−1​

2. 直观理解

Step 1. 在二维平面内选三个不同的点并依次用线段连接

在这里插入图片描述

Step 2. 在线段 A B AB AB和 B C BC BC上找到 D D D、 E E E两点,使得 A D D B = B E E C \frac{AD}{DB}=\frac{BE}{EC} DBAD​=ECBE​

在这里插入图片描述

Step 3. 连接 D E DE DE,并在 D E DE DE上找到 F F F点,使其满足 D F F E = A D D B = B E E C \frac{DF}{FE}=\frac{AD}{DB}=\frac{BE}{EC} FEDF​=DBAD​=ECBE​(抛物线的三切线定理)

在这里插入图片描述
Step 4. 找出符合上述条件的所有点

在这里插入图片描述
上述为一个二阶贝塞尔曲线。同样的有 n n n阶贝塞尔曲线:

曲线图示
一阶在这里插入图片描述
三阶在这里插入图片描述
四阶在这里插入图片描述
五阶在这里插入图片描述

3. 公式推导

3.1 一次贝塞尔曲线(线性公式)

定义:给定点 P 0 P_0 P0​、 P 1 P_1 P1​,线性贝塞尔曲线只是一条两点之间的直线,这条线由下式给出,且其等同于线性插值:
B ( t ) = P 0 + ( P 1 − P 0 ) t = ( 1 − t ) P 0 + t P 1 ,   t ∈ [ 0 , 1 ] B(t)=P_0+(P_1-P_0)t=(1-t)P_0+tP_1,\text{ } t\in[0,1] B(t)=P0​+(P1​−P0​)t=(1−t)P0​+tP1​, t∈[0,1]

在这里插入图片描述

其中,公式里的 P 0 P_0 P0​、 P 1 P_1 P1​同步表示为其 x x x或 y y y轴坐标。

假设 P 0 P_0 P0​坐标为 ( a , b ) (a,b) (a,b), P 1 P_1 P1​坐标为 ( c , d ) (c,d) (c,d), P 2 P_2 P2​坐标为 ( x , y ) (x,y) (x,y),则有:

x − a c − x = t 1 − t ⇒ x = ( 1 − t ) a + t c (3-1) \frac{x-a}{c-x}=\frac{t}{1-t} \Rightarrow x=(1-t)a+tc \tag{3-1} c−xx−a​=1−tt​⇒x=(1−t)a+tc(3-1)

同理有:

y − b d − y = t 1 − t ⇒ x = ( 1 − t ) b + t d (3-2) \frac{y-b}{d-y}=\frac{t}{1-t} \Rightarrow x=(1-t)b+td \tag{3-2} d−yy−b​=1−tt​⇒x=(1−t)b+td(3-2)

于是可将 ( 3 − 1 ) ( 3 − 2 ) (3-1) (3-2) (3−1)(3−2)简写为:

B ( t ) = ( 1 − t ) P 0 + t P 1 ,   t ∈ [ 0 , 1 ] (3-3) B(t)=(1-t)P_0+tP_1 ,\text{ } t\in[0,1] \tag{3-3} B(t)=(1−t)P0​+tP1​, t∈[0,1](3-3)

3.2 二次贝塞尔曲线(二次方公式)

定义:二次贝塞尔曲线的路径由给定点 P 0 P_0 P0​、 P 1 P_1 P1​、 P 2 P_2 P2​的函数 B ( t ) B(t) B(t)给出:
B ( t ) = ( 1 − t ) 2 P 0 + 2 t ( 1 − t ) P 1 + t 2 P 2 ,   t ∈ [ 0 , 1 ] B(t)=(1-t)^{2} P_0+2t(1-t)P_1+t^2P_2,\text{ } t\in [0,1] B(t)=(1−t)2P0​+2t(1−t)P1​+t2P2​, t∈[0,1]

在这里插入图片描述

假设 P 0 P 1 P_0P_1 P0​P1​上的点为 A A A, P 1 P 2 P_1P_2 P1​P2​上的点为 B B B, A B AB AB上的点为 C C C(也即 C C C为曲线上的点。则根据一次贝塞尔曲线公式有:

A = ( 1 − t ) P 0 + t P 1 B = ( 1 − t ) P 1 + t P 2 C = ( 1 − t ) A + t B (3-4)

A=(1−t)P0+tP1B=(1−t)P1+tP2C=(1−t)A+tB

\tag{3-4} A=(1−t)P0​+tP1​B=(1−t)P1​+tP2​C=(1−t)A+tB​(3-4)

将上式中 A A A、 B B B带入 C C C中,即可得到二次贝塞尔曲线的公式:

B ( t ) = ( 1 − t ) 2 P 0 + 2 t ( 1 − t ) P 1 + t 2 P 2 ,   t ∈ [ 0 , 1 ] (3-5) B(t)=(1-t)^{2} P_0+2t(1-t)P_1+t^2P_2,\text{ } t\in [0,1] \tag{3-5} B(t)=(1−t)2P0​+2t(1−t)P1​+t2P2​, t∈[0,1](3-5)

3.3 三次贝塞尔曲线(三次方公式)

同理可得三次贝塞尔曲线公式:

B ( t ) = ( 1 − t ) 3 P 0 + 3 t ( 1 − t ) 2 P 1 + 3 t 2 ( 1 − t ) P 2 + t 3 P 3 ,   t ∈ [ 0 , 1 ] (3-6) B(t)=(1-t)^{3} P_0+3t(1-t)^2P_1+3t^2(1-t)P_2+t^3P_3,\text{ } t\in [0,1] \tag{3-6} B(t)=(1−t)3P0​+3t(1−t)2P1​+3t2(1−t)P2​+t3P3​, t∈[0,1](3-6)

3.4 n n n次贝塞尔曲线(一般参数公式)

定义:给定点 P 0 , P 1 , . . . , P n P_0,P_1,...,P_n P0​,P1​,...,Pn​,则 n n n次贝塞尔曲线由下式给出:
在这里插入图片描述

n n n次贝塞尔曲线的公式可由如下递归表达:

P 0 n = ( 1 − t ) P 0 n − 1 + t P 1 n − 1 ,   t ∈ [ 0 , 1 ] (3-7) P_0^n=(1-t)P_0^{n-1}+tP_1^{n-1},\text{ }t\in[0,1] \tag{3-7} P0n​=(1−t)P0n−1​+tP1n−1​, t∈[0,1](3-7)

进一步可以得到贝塞尔曲线的递推计算公式:

P i k { P i ,   k = 0 ( 1 − t ) P i k − 1 + t P i + 1 k − 1 ,   k = 1 , 2 , . . . , n ;   i = 0 , 1 , . . . , n − k P_i^k

{Pi, k=0(1−t)Pk−1i+tPk−1i+1, k=1,2,...,n; i=0,1,...,n−k

Pik​{Pi​, k=0(1−t)Pik−1​+tPi+1k−1​, k=1,2,...,n; i=0,1,...,n−k​

这就是德卡斯特里奥算法(De Casteljau’s algorithm)

参考

[1] https://www.jianshu.com/p/0c9b4b681724
[2] https://www.jianshu.com/p/8f82db9556d2

  • 4
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
三次样条插值方法可以通过以下步骤实现对机械臂的轨迹规划: 1. 对贝塞尔曲线函数获得的机械臂末端坐标点进行三次样条插值,得到跟时间t相关的位置和速度函数。其中,需要根据末端坐标点的数量i和时间间隔dt计算出插值所需的系数矩阵,并通过求解三对角线方程组的方式计算出每个时间点的位置和速度。 2. 根据机械臂的正解公式,将位置和速度函数转化为电缸位移函数,即求解每个时间点三组机械臂的滑块位移。 3. 根据电缸位移函数和机械臂的逆解公式,得到跟时间t相关的末端位姿函数。 下面是部分MATLAB代码示例: % 输入数据 i = size(Q, 1); % 末端坐标点数量 dt = 0.01; % 时间间隔 % 计算插值所需的系数矩阵 M = zeros(i); M(1, 1:2) = [1, 0]; M(i, i-1:i) = [0, 1]; for j = 2:i-1 M(j, j-1:j+1) = [1, 4, 1]; end M = M / 6; % 计算每个时间点的位置和速度 t = 0:dt:(i-1)*dt; P = bezier(Q, t); % 计算贝塞尔曲线上每个时间点的位置 V = zeros(i, 3); for j = 2:i-1 V(j, :) = (P(j+1, :) - P(j-1, :)) / (2*dt); end % 解三对角线方程组,得到每个时间点的位置和速度 A = diag(ones(i,1)*4) + diag(ones(i-1,1),1) + diag(ones(i-1,1),-1); A(1,2) = 2; A(i,i-1) = 2; B = [V(1,:)*dt^2; 3*(P(3:i,:)-P(1:i-2,:)); V(i,:)*dt^2]; M_inv = inv(M); M_inv_B = M_inv * B; Q_dot = A \ M_inv_B; Q_ddot = zeros(i, 3); for j = 1:i-1 Q_ddot(j, :) = (Q_dot(j+1, :) - Q_dot(j, :)) / dt; end Q_ddot(i, :) = Q_ddot(i-1, :); % 计算每个时间点的电缸位移 L = 1; % 电缸长度 H = 0.5; % 机械臂高度 r = 0.5; % 机械臂半径 theta = zeros(i, 3); for j = 1:i x = P(j, 1); y = P(j, 2); z = P(j, 3); r1 = sqrt(x^2 + y^2); r2 = sqrt((r1-L)^2 + z^2); phi1 = atan2(y, x); phi2 = atan2(z, r1-L); alpha = acos((L^2 + r1^2 + r2^2 - 2*L*r1 - 2*L*r2 + 2*r1*r2) / (2*L*sqrt(r1^2+r2^2-L^2))); theta(j, :) = [phi1, phi2+alpha, acos((r2^2-r^2-H^2)/(2*r*H))]; end theta_dot = zeros(i, 3); for j = 2:i theta_dot(j, :) = (theta(j, :) - theta(j-1, :)) / dt; end theta_dot(1, :) = theta_dot(2, :); % 根据机械臂的逆解公式,计算每个时间点的末端位姿 X = zeros(i, 6); for j = 1:i [X(j,1:3), X(j,4:6)] = delta_ik(theta(j,:), theta_dot(j,:)); end % delta_ik函数,用于计算机械臂的逆解 function [xyz, xyzdot] = delta_ik(theta, thetadot) L = 1; H = 0.5; r = 0.5; phi1 = theta(1); phi2 = theta(2); phi3 = theta(3); dphi1 = thetadot(1); dphi2 = thetadot(2); dphi3 = thetadot(3); x = (L+r*sin(phi3))*cos(phi1)*cos(phi2) + r*cos(phi3)*sin(phi1); y = (L+r*sin(phi3))*sin(phi1)*cos(phi2) - r*cos(phi3)*cos(phi1); z = H + (L+r*sin(phi3))*sin(phi2); xyz = [x, y, z]; xyzdot = [-sin(phi1)*dphi1*(L+r*sin(phi3))*cos(phi2) - cos(phi1)*sin(phi2)*dphi2*(L+r*sin(phi3)) - r*sin(phi1)*sin(phi3)*dphi3; cos(phi1)*dphi1*(L+r*sin(phi3))*cos(phi2) - sin(phi1)*sin(phi2)*dphi2*(L+r*sin(phi3)) + r*cos(phi1)*sin(phi3)*dphi3; cos(phi2)*dphi2*(L+r*sin(phi3)) + r*cos(phi3)*dphi3]; end

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值