Найти Y с учетом X на кубической кривой Безье?
Мне нужен метод, который позволяет мне найти Y-координату на кубической кривой Безье, заданную X-координату.
Я сталкивался с множеством мест, где мне говорили, что нужно рассматривать это как кубическую функцию, а затем пытаться найти корни, что я понимаю. ОДНАКО уравнение для кубической кривой Безье имеет вид (для x-координат):
X(t) = (1-t)^3 * X0 + 3*(1-t)^2 * t * X1 + 3*(1-t) * t^2 * X2 + t^3 * X3
Что меня смущает, так это добавление (1-t)
ценности. Например, если я заполню значения X некоторыми случайными числами:
400 = (1-t)^3 * 100 + 3*(1-t)^2 * t * 600 + 3*(1-t) * t^2 * 800 + t^3 * 800
тогда переставь это:
800t^3 + 3*(1-t)*800t^2 + 3*(1-t)^2*600t + (1-t)^3*100 -400 = 0
Я до сих пор не знаю значение (1-t)
коэффициенты. Как я должен решить уравнение, когда (1-t)
еще неизвестно?
5 ответов
Существует три распространенных способа выражения кубической кривой Безье.
Первый х в зависимости от т
x(t) = sum( f_i(t) a_i )
= (1-t)^3 * x0 + 3*(1-t)^2 * t * x1 + 3*(1-t) * t^2 * x2 + t^3 * x3
Во-вторых, у как функция х
y(x) = sum( f_i(x) a_i )
= (1-x)^3 * y0 + 3*(1-x)^2 * x * y1 + 3*(1-x) * x^2 * y2 + x^3 * y3
Эти первые два математически одинаковы, просто используют разные имена для переменных.
Судя по твоему описанию "найди Y-координату на кубической кривой Безье, учитывая x-координату на ней". Я предполагаю, что у вас есть вопрос, используя второе уравнение: вы пытаетесь переставить первое уравнение, чтобы помочь вам решить его, где, как вам следует использовать второе уравнение. Если это так, то перестановка или решение не требуются - просто подключите свое значение x, и у вас есть решение.
Вполне возможно, что у вас есть уравнение третьего типа, который является уродливым и сложным случаем. Это и параметры x, и y являются кубическими кривыми Безье третьей переменной t.
x(t) = sum( f_i(t) x_i )
y(t) = sum( f_i(t) y_i )
Если это ваш случай. Дайте мне знать, и я могу подробно рассказать, что вам нужно сделать, чтобы решить эту проблему.
Я думаю, что это честный вопрос CS, поэтому я попытаюсь показать, как я решил это. Обратите внимание, что данный x может иметь более 1 значения y, связанного с ним. В случае, когда мне это нужно, это гарантированно не так, поэтому вам придется выяснить, как определить, какой из них вы хотите.
Я перебрал t, создав массив значений x и y. Я сделал это с довольно высоким разрешением для моих целей. (Я искал для создания 8-битной справочной таблицы, поэтому я использовал ~1000 точек.) Я просто включил t в уравнение Безье для следующих x и следующих y координат для сохранения в массиве. После того, как я сгенерировал все это, я просмотрел массив, чтобы найти 2 ближайших значения x. (Или, если было точное совпадение, используйте это.) Затем я выполнил линейную интерполяцию на этом очень маленьком отрезке, чтобы получить нужное мне значение y.
Дальнейшее развитие выражения должно избавить вас от (1 - t)
факторы
Если вы запускаете:
expand(800*t^3 + 3*(1-t)*800*t^2 + 3*(1-t)^2*600*t + (1-t)^3*100 -400 = 0);
В wxMaxima или Maple (вы должны добавить параметр t
хотя в этом) вы получите:
100*t^3 - 900*t^2 + 1500*t - 300 = 0
Решите новое кубическое уравнение для t
(вы можете использовать формулу кубического уравнения для этого), после того, как вы получили t
, ты можешь найти x
делать:
x = (x4 - x0) * t (asuming x4 > x0)
Поэтому я искал какой-то метод, который позволил бы мне найти Y-координату на кубической кривой Безье, учитывая x-координату на ней.
Рассмотрим кубическую кривую Безье между точками (0, 0) и (0, 100) с контрольными точками в точках (0, 33) и (0, 66). Существует бесконечное число Y для данного X. Так что нет уравнения, которое решило бы Y при X для произвольного кубического Безье.
Для надежного решения вы, вероятно, захотите начать с алгоритма де Кастельжау
Разделите кривую рекурсивно, пока отдельные сегменты не приблизятся к прямой линии. Затем вы можете определить, пересекают ли эти различные отрезки линии ваш x или являются ли они вертикальными отрезками, x которых соответствует искомому вами x (мой пример выше).
Уравнение для кривой Безье (получение значения х):
Bx = (-t^3 + 3*t^2 - 3*t + 1) * P0x +
(3*t^3 - 6*t^2 + 3*t) * P1x +
(-3*t^3 + 3*t^2) * P2x +
(t^3) * P3x
Переставить в виде кубика т
0 = (-P0x + 3*P1x - 3*P2x + P3x) * t^3+
(3*P0x - 6*P1x + 3*P2x) * t^2 +
(-3*P0x + 3*P1x) * t +
(P0x) * P3x - Bx
Решите это, используя кубическую формулу, чтобы найти значения для t. Может быть несколько реальных значений t (если ваша кривая дважды пересекает одну и ту же точку x). В моем случае я имел дело с ситуацией, когда для любого значения x было только одно значение y. Таким образом, я смог просто взять единственный реальный корень в качестве значения t.
a = -P0x + 3.0 * P1x - 3.0 * P2x + P3x;
b = 3.0 * P0x - 6.0 * P1x + 3.0 * P2x;
c = -3.0 * P0x + 3.0 * P1x;
d = P0x;
t = CubicFormula(a, b, c, d);
Затем поместите значение t обратно в кривую Безье для y
By = (1-t)^3 * P0x +
3t(1-t)^2 * P1x +
3t^2(1-t) * P2x +
t^3 * P3x