Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по КГ.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
778.24 Кб
Скачать

Вычерчивание прямых линий

Поскольку в большинстве случаев для визуализации используются линейные аппроксимации, то скорость прочерчивания прямых линий является важным фактором.

Будем считать, что у нас есть функция point(x, y) для высвечивания пикселя. Основная задача заключается в определении точек сетки (x, y) на экране, которые должны быть высвечены. Поскольку таких точек может быть очень много, то предпочтительно использовать только целочисленную арифметику, которая выполняется значительно быстрее, чем вычисления над числами с плавающей точкой. Рассмотрим для общности один из случаев, отрезка T1T2: . Для рассмотрения самого перехода от чисел с плавающей точкой к целым числам опишем несколько алгоритмов.

1. Real (без целочисленной арифметики)

Т.к. для прямой линии

Обозначим

k=(float)(x2-x1)/(float)(y2-y1);

for (x=x1; x<=x2;x++) {

y=y1+(int)(k*(x-x1)+0.5);

point(x, y);

}

Операция (int) (k*(x-x1)+0.5) производит математическое округление (а не отсечение дробной части)

2. Real-integer (промежуточный алгоритм)

Е сли внимательно посмотреть на изменений y, то можно увидеть, что он или остается тем же, или увеличивается на 1. Выбор должен осуществлятся таким образом, чтобы новая точка сетки (x, y) располагалась по возможности ближе к прямой линии, проходящей через T1 и T2. Это означает, что расстояние по вертикали между новой выбранной точкой и этой линией не должно превышать значение 0.5. Введем d для обозначения этого расстояния и потребуем, чтобы –0.5 <= d <= 0.5. Это неравенство обеспечивает условие для определения необходимости давать приращение переменной y.

k=(float)(x2-x1)/(float)(y2-y1);

d=0;

y=y1;

for (x=x1; x<=x2;x++) {

point(x, y);

d+=k;

if (d>0.5) {y++; d--;}

}

Поскольку d обозначает насколько ниже точной линии лежит вычисленная точка, то значение d увеличивается на значение наклона k, если x увеличивается на 1, и если y остается без изменений. Это условие не выполняется, если значение переменной d превышает значение 0.5. В этот момент нужно увеличить y на 1. Очевидно, что в этот момент отклонение d должно быть уменьшено на 1.

3. Integer (алгоритм Брезенхема, 1965 г.)

, где y2–y1 – целое, и x2–x1 – то же целое.

Поскольку d вычисляется как конечная сумма элементов, каждый из которых равен либо k, либо –1, то d является также рациональной дробью и k может быть записана в виде частного со знаменателем (x2–x1). Для избавления от нецелого 0.5 необходимо умножить знаменатель на 2. Теперь

V=2*(x2-x1)

K=k*V

D=d*V

Условие изменится так: d>0.5 => d*v>0.5*v => D>(x2-x1) => D>dx .

Т.к. сравнение с нулем производится быстрее, то D-dx>dx => D-dx => E>0,

где E=D-dx. Т.к. первоначально d=0, то и D=0 => первоначально E=-dx

dx=x2-x1;

dy=y2-y1;

V=dx*2;

K=dy*2;

E=-dx;

y=y1;

for (x=x1; x<=x2;x++) {

point(x, y);

E+=K;

if (E>0) {y++; E-=V;}

}

Если расстояние по вертикали между T1 и T2 больше, чем по горизонтали, то независимой переменной будет y вместо x.

Пересечение прямой и плоскости, видимость прямой

 

Задана плоскость или

.

Любая точка 3-мерного пространства представима в однородных координатах вектором

Если точка S лежит на плоскости, то

Если же S не лежит на плоскости, то знак этого скалярного произведения показывает, по какую сторону от плоскости расположена точка.