Мне нужен алгоритм для преобразования замкнутой кривой Безье (возможно, самопересекающейся) в двоичное растровое изображение: 0 для внутренних пикселей и 1 для внешних. Я пишу код, который должен реализовать некоторые операции с кривыми Безье, может ли кто-нибудь дать мне некоторые ресурсы или учебные пособия по Безье? Википедия и другие ничего не сказали об оптимизации, вычитании, объединении, вставке и удалении узлов и других операциях :-)
Как преобразовать замкнутые кривые Безье в растровые изображения?
Ответы (2)
Этот статья Чарльза Лупа и Джима Блинна входит в много подробностей по вашему вопросу.
Другой вариант — разбить кривую Безье на линейные сегменты, а затем использовать ваш любимый алгоритм заполнения полигонов.
Хочу добавить, что вариант тесселяции очень эффективен и дает отличные результаты. Звучит неправильно аппроксимировать кривую Безье отрезками, потому что вы думаете, что результат будет выглядеть как многоугольник. Хитрость заключается в том, чтобы сделать сегменты линий достаточно короткими, чтобы ошибка была очень маленькой (скажем, менее 1/10 пикселя).
Вот формула, которую я использовал для вычисления размера шага, чтобы гарантировать, что максимальная ошибка (т. е. отклонение сегментов линии от истинной кривой) меньше дельты:
Пусть (x1,y1), (x2,y2), (x3,y3), (x4,y4) будут контрольными точками кривой Безье в пиксельных координатах.j
dd0 = square(x1-2*x2+x3) + square(y1-2*y2+y3); dd1 = square(x2-2*x3+x4) + square(y2-2*y3+y4); dd = 6*sqrt(max(dd0, dd1));
Тогда dd является максимальным значением 2-й производной по кривой - поскольку 2-я производная кубического является линейной функцией, этот максимум должен приходиться на конечную точку. Здесь я использовал квадрат(х) как аббревиатуру для х*х.
if (8*delta > dd) { epsilon = 1; } else { epsilon = sqrt(8*delta/dd); }
Тогда эпсилон - это размер вашего шага: если вы выберете конечные точки ваших линейных сегментов при t = 0, t = эпсилон, t = 2 * эпсилон, ..., (и последняя конечная точка при t = 1), то линейные сегменты будет находиться в пределах дельты исходной кривой.
Выберите delta = 0,1, и вы получите растровое изображение, визуально неотличимое от исходной кривой.