Рассчитать граничные точки поверхности, определенной 2 кривыми Безье? - PullRequest
2 голосов
/ 23 ноября 2011

Учитывая 6 точек, определяющих 2 квадратичные кривые Безье, как рассчитать точки, в которых касательные для обеих кривых совпадают?

Расстояние между касательными уменьшается и в конечном итоге достигает 0, когда они совпадают. Как рассчитать это, не повторяя сто раз и не проверяя каждую часть? Есть ли математическое решение для этого?

enter image description here

Ответы [ 2 ]

3 голосов
/ 23 ноября 2011

Удобно, что в Википедии даже показан градиент для квадратичной кривой Безье , определяемой P_0, P_1, P_2, поэтому нам даже не нужно его вычислять.

gradient

Итак, если у нас есть 2 кривые, определенные с помощью B_1 (t) и B_2 (t), и мы хотим знать местоположение на кривой B_2 (t), которое имеет ту же касательную, что и, например, B_1 (0.5).Нам нужно только найти t такой, что B_1 '(0.5) = B_2' (t).Поскольку градиент представляет собой линейное уравнение, решить это равенство тривиально.

edit: это такой крутой вопрос, мне пришлось написать код:)

Рассмотрим этот рисунок: enter image description here

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; ...].Поэтому я определяю 2 кривые с точками p0, p1, p2 и q0, q1, q2, затем создаю функцию для вычисления Безье (B) и градиента (C).Затем я строю кривые и рассматриваю касательную при t = 0,2. Надеюсь, оставшаяся математика ясна, но если нет, просто задайте вопрос.

Также обратите внимание, что мы не решаем, чтобы градиенты были равныкак я изначально сказал!Вместо этого нам нужно найти градиент, который имеет такое же соотношение х / у.А если нет решения, то нет места, где касательные равны.

1 голос
/ 23 ноября 2011

Квадратичные кривые Безье P и Q

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

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) -го порядка с контрольными точками Ди = п (Р ​​(г + 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)

Для второй кривой

Ех = 2 * и * (q2x-QP1x + Q0x) + 2 (Q1x-Q0x) * * тысячу двадцать-одна * * 1 022 Еу = 2 * и * (q2y-QP1y + Q0y) + 2 (Q1y-Q0y)

Условие, что векторы параллельны:

Dx * +1027 * Еу-Dy Ех = 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 * и * QBY + Q0y-т ^ 2 * Pay-2 * T * * PBY тысячи пятьдесят-одина-P0y) * * тысяча пятьдесят-два (т * чела + PBx) = 0 * 1 053 *

Maple решает эту систему с таким результатом:

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

(- 2 * Pax QBY Оплатите QBx + PBx Оплатите PBY Qax + Pax PBY PBx QAy + Q0x * 1 076 * Оплатите * тысяча семьдесят семь * Pax QAy-Pax * PBY ^ 2 * Qax-PBx ^ 2 * Оплатите QAy + P0x Оплатите ^ 2 * Qax-P0y * 1 081 * Pax * тысячу восемьдесят-два * Оплатите Гах-Q0y Pax ^ 2 * QAy + P0y * Pax ^ 2 * QAy + Оплатите ^ 2 * QBx ^ 2-P0x Оплатите Pax QAy + Q0y Pax 1090 * Оплатите * Qax + Pax ^ 2 * QBY ^ 2-Q0x * 2 ^ Оплатите * Qax) * _ Z ^ 2 +

(Q0y PBx * тысяча девяносто-четырь * Оплатите Qax + Q0x * тысяча девяносто шесть * PBY * тысяча девяносто-семь * Pax * 1 098 * QAy + Q0y Pax PBY * Qax + 2 * Pax * QBY ^ 2 * PBx + 2 * Оплатите * QBx ^ 2 * PBY-2 * Pax QBY PBY * QBx-2 * PBx QBY Оплатите QBx-P0y Pax PBY Qax-P0y PBx * Qax Оплатите-2 * * Q0x +1111 * * 1112 Оплатите * PBY * Qax + 2 * P0y Pax 1115 * PBx * QAy- P0x Оплатите PBx QAy + 2 * P0x Оплатите PBY Qax-P0x PBY Pax * один тысяча сто двадцать четыре * QAy-2 * Q0y Pax PBx QAy + Q0x 1129 * Оплатите * 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 * * 1 139 * 1140 PBx * PBY * * Qax тысяча сто сорок один + Q0x PBY PBx QAy-P0x PBY PBx * QAy)

Эта формула означает, что t является корнем кубического уравнения с этими странными коэффициентами. Кубик разрешим. Если есть реальное значение t в диапазоне [0..1], то мы можем вычислить и проверить тот же диапазон. Конечно, это довольно сложный метод, и мои вычисления могут содержать ошибки и опечатки

Дополнение: возможен случай 3 вещественных корней кубики (и 3 касательных):

enter image description here

...