Параметрические кривые и их растеризация
Растеризация кривых Безье
Прямой метод
(определяются по выражению (4.2)). Подберем шаг
так, чтобы
и
были меньше размера стороны пикселя d (если мы работаем в пиксельных координатах, то это 1 ), т. е. мы не пропустим ни одного пикселя при таких приращениях. Т.к.
и
- многочлены, то, соответственно, легко найти максимумы их модулей Mx и My на отрезке [0, 1]. Положим M = max(Mx,My), тогда, взяв
, получим что смещения по x и по y при каждом шаге не превосходят длины стороны пикселя.
// x(t), y(t) заданы в пиксельных координатах => d = 1
// M - максимум модулей dx/dt и dy/dt на всем отрезке [0,1]
// round(x) - округляет x до ближайшего целого
dt = 1 / M;
t = 0;
while(t < 1)
{
x = x(t); // см. выражение 4.2
y = y(t); // см. выражение 4.2
plot( round(x) , round(y) );
t += dt;
}
Листинг
4.1.
Прямой метод растеризации кривой Безье
Недостаток данного алгоритма состоит в том, что при малых смещениях по x и y много итераций проходит зря, т.к. происходит повторная закраска одних и тех же пикселей.
Метод разбиения
Предложен де Кастелье. Рассмотрим пример этого алгоритма для кривой 4-го порядка с опорными точками P0P1P2P3 (см. рис. 4.6). Если рассмотреть участок между P0 и
, то он может быть задан как кривая Безье с опорными точками
(почему это так, подробнее см., например, в [28]).
Аналогичные рассуждения справедливы и для участка между
и P4. Будем применять этот алгоритм рекурсивно для левой и правой частей, пока кривая не выродится в прямую с точностью до пикселя, а это так или иначе (все точки попадут в один пиксель) произойдет.
plot(P) рисует пиксель с координатами, равными округленным до целых координатам точки P.
BBox(P1, . . . ,Pn) вычисляет наименьший ограничивающий прямоугольник для точек P1, . . . ,Pn.
// работаем в пиксельных координатах
// (размер пикселя равен 1x1)
// P0 - начальная точка кривой
// Pn - конечная точка кривой
DrawCurve(P0,P1, . . . ,Pn)
{
// Проверка на завершение
if( макс. длина ребра BBox(P0,P1, . . . , Pn) < 1 )
return;
if( P0,P1, . . . , Pn лежат на отрезке P0Pn
с точностью до пикселя )
{
Нарисовать отрезок P0Pn;
// (см. лекцию о растеризации отрезков)
return;
}
Найти P01,P02, . . . , P0{n-1} для t = 0,5;
// используя (4.1)
Найти P0n для t = 0,5; // используя (4.1)
Найти P1{n-1},P2{n-2}, . . . , P{n-1}1 для t = 0,5;
// используя (4.1)
plot(P0n);
// Нарисовать половинки (см. рис. 4.6)
DrawCurve( P0,P01, . . . , P0n);
DrawCurve( P0n,P1{n-1}, . . . , Pn);
}
Листинг
4.2.
Метод растеризации кривой Безье путем разбиения
Для построения кривых по большому множеству опорных точек пришлось бы использовать кривые Безье большого порядка, что привело бы к громоздким вычислениям; к тому же часто желательным является локальное влияние на форму кривой (для кривых Безье это не так). Поэтому чаще используют

