Плоская машинная графика, страница 7

Для реализации этого алгоритма нужно знать или уметь вычислять координаты всех точек границы области. Это является существенным недостатком алгоритма. Например, для заполнения многоугольника с установкой режима XOR_PUT нужно знать координаты всех вершин многоугольника и алгоритм генерации точек сторон многоугольника. В этом алгоритме просматриваются все точки границы области.

Так как в этом алгоритме сначала закрашивается область большая, чем нужно, а затем «лишнее» убирается, то время работы программы существенно зависит от размеров дополнительной области, которая фактически закрашивается два раза. Для уменьшения размеров этой дополнительной области вводится перегородка – вертикальная линия на экране компьютера, расположенная справа (слева) от области (рис. 7). В самом простом случае перегородка – это правая граница экрана. Чем ближе перегородка к области, тем эффективнее алгоритм.

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

Сформируем алгоритм для заполнения многоугольника.

1. Выбираем начальную точку (x0,y0) – одну из вершин многоугольника.

2. Выбирается направление обхода границы (например, по часовой стрелке).

3. Устанавливается режим XOR_PUT.

4. Рассматриваем следующую точку границы многоугольника в выбранном направлении обхода, и называем ее текущей (xтек,yтек). Сравниваем текущую точку (xтек,yтек) и предыдущую точку (xпред,yпред). Возможны три случая:

а)   yтек>yпред           в этом случае проводим горизонтальный отрезок от точки (xтек,yтек) до перегородки с помощью функции line и переходим к следующей точке границы многоугольника;

б)   yтек=yпред           в этом случае переходим к следующей точке границы многоугольника;

в)   yтек<yпред           в этом случае проводим горизонтальный отрезок от точки (xпред,yпред) до перегородки с помощью функции line и переходим к следующей точке границы многоугольника.

5. Заполнение закончено, когда просмотрены все стороны многоугольника.

Отметим, что режим XOR_PUT действует только на кусочно-линейном примитиве (line, lineto, linerel) и не действует на putpixel и bar. Поэтому горизонтальные отрезки нужно выводить с помощью функции line, а не функции putpixel. Если же в качестве элемента изображения рассматривается не пиксел, а закрашенный квадрат со стороной  в K (K>1) пикселов, то предварительно нужно подготовить функцию, в которой строится такой закрашенный квадрат с помощью функции line.

Пример 2.2. Закрасить квадрат со стороной 40 пикселов, используя алгоритм заполнения с установкой режима XOR_PUT. Левой верхней вершиной квадрата является точка с координатами (20,20). В качестве перегородки использовать вертикальную линию x=80.

Программа

#include<conio.h>

#include<graphics.h>

#include<math.h>

#include<dos.h>

//xпред, yпред

int oldx,oldy;

//Функция сравнивает текущую точку обхода периметра

//с предыдущей и выполняет соответствующие действия

//в качестве параметров передаются координаты текущей точки

void XorLine(int x, int y)

{

if (y>oldy) line(x,y,80,y);

if (y<oldy) line(oldx,oldy,80,oldy);

oldx=x; oldy=y;    //текущая точка становится предыдущей

}

void main()

{

int i, gdriver=DETECT, gmode;

//иницализация графического режима

initgraph (&gdriver, &gmode, "");

setcolor(LIGHTRED);     //установка красного цвета

rectangle(19,20,60,61); //рисование периметра квадрата (необязательно)

line(80,20,80,60);      //рисование перегородки (необязательно)

setcolor(WHITE);        //установка белого цвета

setwritemode(XOR_PUT);  //установка режима вывода XOR_PUT

oldx=20; oldy=20;       //инициализируем предыдущие координаты

//проход по левой стороне квадрата с задержкой

for(i=20;i<=60;i++) {XorLine(20,i); delay(200);}

//проход по нижней стороне квадрата

for(i=20;i<=60;i++) XorLine(i,60);

//проход по правой стороне квадрата с задержкой