Поиск Y задан X на кубической кривой Безье?

Итак, я искал какой-то метод, позволяющий мне найти Y-координату на кубической кривой Безье, учитывая 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). Я не могу решить, как я должен решить t, когда (1-t) неизвестно в первую очередь.

Любые идеи?

Ответ 1

Существует три общих способа выражения кубической кривой безье.

Сначала x как функция от t

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

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 )

Если это ваш случай. Дайте мне знать, и я могу детализировать, что вам нужно сделать, чтобы решить эту проблему.

Ответ 2

Я думаю, что это честный вопрос CS, поэтому я попытаюсь показать, как я это решил. Обратите внимание, что данный x может иметь более 1 y значение, связанное с ним. В случае, когда мне это нужно, это гарантировалось, что это не так, поэтому вам нужно выяснить, как определить, какой из них вам нужен.

Я повторил t, создавая массив значений x и y. Я сделал это с довольно высоким разрешением для своих целей. (Я искал генерировать 8-битную таблицу поиска, поэтому я использовал ~ 1000 точек.) Я просто подключил t к уравнению безье для следующих x и следующих координат y для хранения в массиве. Как только я создал всю созданную вещь, я просмотрел массив, чтобы найти 2 ближайших значения x. (Или, если было точное совпадение, использовалось это.) Затем я сделал линейную интерполяцию на этом очень маленьком сегменте линии, чтобы получить нужное значение y.

Ответ 3

Разработка выражения далее должна избавить вас от факторов (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) 

Ответ 4

Итак, я искал какой-то метод, позволяющий мне найти Y-координату на кубической кривой Безье, учитывая x-координату на ней.

Рассмотрим кубическую кривую Безье между точками (0, 0) и (0, 100) с контрольными точками в (0, 33) и (0, 66). Существует бесконечное число Y для данного X. Таким образом, нет никакого уравнения, которое будет решать Y, заданное X для произвольной кубической безье.

Для надежного решения вы, вероятно, захотите начать с алгоритм Де Кастеляу

Разделить кривую рекурсивно, пока отдельные сегменты не приблизит прямую линию. Затем вы можете определить, будут ли и где эти различные сегменты линии перехватывать ваш x, или являются ли они вертикальными сегментами линии, x соответствует x, который вы ищете (мой пример выше).