2

给定定义 2 条二次贝塞尔曲线的 6 个点,我如何计算两条曲线的切线相同的点?

当切线重合时,切线之间的距离会变小并最终达到 0。如何在不循环一百次并检查每个部分的情况下计算这个?有数学解决方案吗?

在此处输入图像描述

4

2 回答 2

3

方便地维基百科甚至显示了由 P_0、P_1、P_2 定义的二次贝塞尔曲线的梯度,因此我们甚至不需要计算它。

坡度

因此,如果我们有 2 条由 B_1(t) 和 B_2(t) 定义的曲线,并且我们想知道曲线 B_2(t) 中与 B_1(0.5) 具有相同切线的位置。我们只需要找到满足 B_1'(0.5) = B_2'(t) 的 t。由于梯度是一个线性方程,解决这个等式应该很简单。

编辑:这是一个很酷的问题,我不得不写一些代码:)

考虑这个数字: 在此处输入图像描述

B = @(t,p0,p1,p2)((1-t)*((1-t)*p0 + t*p1) + t*((1-t)*p1 + t*p2)) 
C = @(t,p0,p1,p2)(2*(1-t)*(p1-p0) + 2*t*(p2-p1));

p0 = [1;2];
p1 = [3;5];
p2 = [6;-1];
X = [];
for t=0:0.05:1
    X = [X B(t,p0,p1,p2)];
end

q0 = [2;0];
q1 = [4;7];
q2 = [5;0];
Y = [];
for t=0:0.05:1
    Y = [Y B(t,q0,q1,q2)];
end

figure(1)
clf;
hold on;
plot([p0(1) p1(1) p2(1)], [p0(2) p1(2) p2(2)], 'ro:')
plot(X(1,:), X(2,:), 'g-');

plot([q0(1) q1(1) q2(1)], [q0(2) q1(2) q2(2)], 'bo:')
plot(Y(1,:), Y(2,:), 'm-');

% Consider: t = 0.2
% Note: B(0.2,p0,p1,p2) = [1.84; 2.84]
%       C(0.2,p0,p1,p2) = [4.4; 2.4]
%
% 2*(1-t)*([4;7] - [2;0]) + 2*t*([5;0]-[4;7]) = [4-2*t; 14-28*t]
% (4-2*t)/(14-28*t) = 4.4/2.4
% 9.6 - 4.8t = 61.6 - 123.2t
% 118.4t - 52 = 0
% t = 0.439
%
% B(0.439,q0,q1,q2) = [3.56; 3.45]

plot([1.84, 3.56], [2.84, 3.45], 'ks--')

这是matlab代码,我希望它有点清楚,如果你不使用matlab,请注意列向量表示为[a;b;c;d;...]。所以我用点 p0,p1,p2 和 q0,q1,q2 定义了 2 条曲线,然后创建一个函数来计算贝塞尔曲线 (B) 和梯度 (C)。然后我绘制曲线并考虑 t=0.2 处的切线,我希望剩下的数学是清楚的,但如果不是,就问一个问题。

另外,请注意,我们并没有像我最初所说的那样解决梯度相等!相反,我们需要求解具有相同 x/y 比率的梯度。如果没有解,那么就没有切线相等的地方。

于 2011-11-23T03:51:06.217 回答
1

二次贝塞尔曲线 P 和 Q

P(t)=P0*(1-t)^2 + 2*P1*(1-t)*t + P2*t^2 = t^2*(P0-2*P1+P2)+2*t *(P1-P0)+P0

Q(t)=Q0*(1-u)^2 + 2*Q1*(1-u)*u + Q2*u^2= u^2*(Q0-2*Q1+Q2)+2*t *(Q1-Q0)+Q0

第n阶贝塞尔曲线的导数是第(n-1)阶曲线,控制点Di=n(P(i+1)-Pi)

D0=2(P1-P0) D1=2(P2-P1)

D=D0*(1-t)+D1*t=2*t*(P2-2*P1+P0)+2*(P1-P0) – 现在我们在参数 t 的点处有切线

标量形式:

Dx=2*t*(P2x-2P1x+P0x)+2(P1x-P0x)

Dy=2*t*(P2y-2P1y+P0y)+2(P1y-P0y)

对于第二条曲线

Ex=2*u*(Q2x-QP1x+Q0x)+2(Q1x-Q0x)

Ey=2*u*(Q2y-QP1y+Q0y)+2(Q1y-Q0y)

向量平行的条件:

Dx Ey-Dy Ex=0

P曲线的导数向量与Q曲线对应点相接触的条件

向量积 (Q(u) - P(t)) x D(t) = 0

现在我们有两个方程用于两个未知数 - t 和 u。

令 PAx = P2x-2P1x+P0x, PBx = P1x-P0x, PAy, PBy, QAx, QAy, QBx,QBy

现在方程组是:

(t PAx+PBx) (u QAy+QBy)-(t PAy+PBy) (u QAx+QBx)=0

(u^2*QAx+2*u*QBx+Q0x-t^2*PAx-2*t PBx-P0x) (t*PAy+PBy)-(u^2*QAy+2*u*QBy+Q0y -t^2*Pay-2*t PBy-P0y) (t*PAx+PBx)=0

Maple 以这样的结果解决了这个系统:

t = RootOf((PAx^2*PBy QAy+PBx PAy^2*QAx-PAx PBy PAy QAx-PBx PAy PAx QAy)*_Z^3+

(-2*PAx QBy PAy QBx+PBx PAy PBy QAx+PAx PBy PBx QAy+Q0x PAy PAx QAy-PAx*PBy^2*QAx-PBx^2*PAy QAy+ P0x PAy^2*QAx- P0y PAx PAy QAx -Q0y PAx^2*QAy+P0y*PAx^2*QAy+PAy^2*QBx^2- P0x PAy PAx QAy+Q0y PAx PAy QAx+PAx^2*QBy^2-Q0x*PAy^2*QAx) *_Z^2+

(Q0y PBx PAy QAx+Q0x PBy PAx QAy+Q0y PAx PBy*QAx+2*PAx*QBy^2*PBx+2*PAy*QBx^2*PBy-2*PAx QBy PBy*QBx-2*PBx QBy PAy QBx- P0y PAx PBy QAx- P0y PBx PAy*QAx-2*Q0x PAy PBy*QAx+2* P0y PAx PBx QAy- P0x PAy PBx QAy+2* P0x PAy PBy QAx- P0x PBy PAx QAy-2*Q0y PAx PBx QAy+Q0x PAy PBx QAy)*_Z-

P0y PBx PBy QAx-Q0x PBy^2*QAx-Q0y*PBx^2*QAy+P0y*PBx^2*QAy+P0x*PBy^2*QAx-2*PBx QBy PBy*QBx+PBx^2*QBy^ 2+PBy^2*QBx^2+Q0y PBx PBy QAx+Q0x PBy PBx QAy- P0x PBy PBx*QAy)

这个公式表示 t 是具有这些奇怪系数的三次方程的根。立方是可解的。如果在 [0..1] 范围内有 t 的实数值,那么我们可以计算 u 并检查相同的范围。当然,这是一个相当复杂的方法,我的计算可能包含错误和拼写错误

加法:3个三次实根(和3个切线)的情况是可能的:

在此处输入图像描述

于 2011-11-23T04:15:57.330 回答