Перетащите кривую Безье, чтобы отредактировать ее - PullRequest
6 голосов
/ 23 февраля 2010

Вы поймете, что я имею в виду, если будете использовать программы для графического редактирования, такие как Gimp или Photoshop. Чтобы редактировать кривую в этих программах (которая, вероятно, является кривой Безье), мы можем щелкнуть по кривой, перетащить мышь, и кривая изменится соответственно. Я подозреваю, что все, что стоит за этим механизмом, связано с векторами, но я не смог найти ни одного документа, в котором бы упоминалось, как это сделать. Кто-нибудь может сказать мне, как я могу это сделать? Большое спасибо.

[править] Я имел в виду выбрать саму кривую, чтобы изменить (отредактировать) ее (нажмите на кривую и перетащите кривую, чтобы изменить ее). Как обычно, мы выбираем контрольные точки для изменения кривой. Я знаю, чтобы изменить кривую, мне нужно отредактировать контрольные точки, но как я могу интерпретировать изменение кривой в изменение контрольных точек?

Ответы [ 6 ]

3 голосов
/ 25 февраля 2010

Есть несколько способов выполнить то, что вы видите, в зависимости от того, как вы хотели бы, чтобы оно вело себя. Я объясню некоторые из более простых методов изменения кривой Безье с помощью манипуляции с точкой на кривой.

Первое, что нужно сделать, это выяснить значение параметра (t), где пользователь щелкнул по кривой. Как правило, это будет приблизительным. Если вы выполняете рендеринг Безье по пикселям или субпикселям, просто запишите для каждого пикселя значение t и используйте его. Если вы проводите тесселяцию на отрезки, посмотрите, какой отрезок ближе всего, найдите значения t двух конечных точек и вычислите значение t в соответствии с расстоянием вдоль линии.

Получив значение t, вы можете включить его в уравнение кривой Безье. В итоге вы получите что-то в форме:

P = k0*P0 + k1*P1 + k2*P2 + k3*P3

где P - точка на кривой, P0, P1, P2 и P3 - входные контрольные точки, а k0, k1, k2 и k3 - постоянные для данного t. Я буду называть значения k «взносами», или, более конкретно, вкладами контрольных точек в точку на кривой P (t). Хорошее свойство, которое нужно помнить: k0 + k1 + k2 + k3 = 1.

Итак, допустим, у вас есть вектор V = P '- P, где P' - новая позиция, а P - исходная позиция. Нам нужно переместить некоторые контрольные точки, чтобы получить P 'туда, куда нужно, но у нас есть некоторая гибкость в отношении того, какую из контрольных точек мы хотим переместить. Можно использовать любую точку с ненулевым вкладом или некоторую комбинацию.

Допустим, пользователь нажимает на кривую в момент времени t = 0. В этом случае только k0 не равен нулю, поэтому

P0 := P0 + V

даст правильный результат. Это также можно записать как

P0 := P0 + k0 * V

В общем случае, когда все вклады отличны от нуля, вы можете применить одно и то же преобразование к каждой из точек, что будет иметь эффект очень гладкой разбросанной деформации.

Другой вариант - просто переместить контрольную точку с максимальным вкладом на все расстояние. Я думаю, что уравнение для использования будет что-то вроде

Pmax := Pmax + 1/kmax * V

но в любом случае все сводится к просмотру вкладов при заданном значении t и перемещению контрольных точек, чтобы новая точка находилась в нужном месте.

Этот подход довольно общий и работает для NURBS и большинства других сплайнов, даже поверхностей. Есть еще один довольно распространенный метод, который использует Greville Abscissae, который набирает как можно больше точек, но по моему опыту слишком легко получить колебания.

1 голос
/ 23 февраля 2010

РЕДАКТИРОВАТЬ - В ответ на ваш вопрос отредактируйте

Чтобы иметь возможность выбрать саму кривую для перемещения контрольных точек, я бы предположил, что кривые Безье определенно не являются шагом вперед - вам нужно будет решить уравнение в обратном порядке, чтобы найти правильные местоположения контрольных точек. , Вы также обнаружите, что в некоторых случаях на самом деле невозможно переместить контрольные точки, чтобы заставить кривую идти туда, куда вы хотите.

Если вы использовали B-сплайны, то вы могли бы просто вставить новую контрольную точку в точке на кривой, ближайшей к точке, по которой пользователь щелкнул, и затем переместить новую контрольную точку. Таким образом, вы фактически добавили бы новую контрольную точку.

Оригинальный текст

Предполагая, что у вас уже есть реализация кривой Безье, которая при заданном наборе контрольных точек (обычно три для Безье, но может быть столько, сколько вы хотите) может создать набор точек, которые будут соединены линиями на устройстве отображения (обычно вы используете параметрическое уравнение 0 >= u <= 1), тогда это просто.

Ваши контрольные точки определяют, куда идет кривая, поэтому вам просто нужно реализовать обратную связь при выборе и перетащить / отпустить эти контрольные точки.

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

B-сплайны были бы лучше, и их вариации - это то, что вы на самом деле видите в фотошопе и др.

0 голосов
/ 25 мая 2012

См. Github.com/bootchk/freehandTool для объектных моделей

Пользователь перетаскивает. Спроецируйте перетаскивание на ближайшую контрольную точку или руку между контрольными точками. Интерпретировать перетаскивание как вращение и / или перемещение (преобразование) упомянутых ближайших контрольных точек. Примечание во множественном числе: ближайшими могут быть совпадающие контрольные точки (концы) двух сегментов или контрольные точки плеча сегмента Безье.

0 голосов
/ 23 февраля 2010

ОК, поэтому давайте предположим, что вам нужно использовать кривые Безье, потому что вы используете библиотеку рендеринга, которая имеет их в качестве примитива. Если вы абсолютно женаты на идее использования контрольных точек на самой кривой, вы можете просто интерполировать контрольные точки, используя метод, описанный здесь: Как найти контрольные точки для сегмента BezierSegment с учетом точек начала, конца и 2 точек пересечения в C # - AKA Cubic Bezier 4-точечная интерполяция

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

0 голосов
/ 23 февраля 2010

Пожалуйста, уточните, что вы хотите сделать? Вы хотите редактировать кривые Безье в приложении? Вас интересует общая математика?

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

0 голосов
/ 23 февраля 2010

Перетаскивание просто меняет контрольные точки кривой Безье, и кривая соответственно пересчитывается. См. Википедия для хорошего объяснения того, как они работают.

...