Использование алгоритма генерации точек отрезка, вывд на экран треугольника и, использование алгоритма заполнения

Страницы работы

Фрагмент текста работы

РАСЧЕТНО-ГРАФИЧЕСКОЕ ЗАДАНИЕ 2

Задание 1. Используя алгоритм генерации точек отрезка, вывести на экран треугольник и, используя алгоритм заполнения, закрасить его.

Варианты заданий. Генерация точек границы треугольника производится по одному из следующих алгоритмов:

L1. Симметричный ЦДА.

L2. Простой ЦДА.

L3. Алгоритм Брезенхема.

L4. Метод приращений.

L5. Метод приращений, использующий четыре перемещения.

Область закрашивается с использованием одного из следующих алгоритмов:

F1. С запоминанием точек границы в стек.

F2. С установкой режима XOR_PUT.

F3. Построчный алгоритм заполнения с затравкой.

F4. Построчный алгоритм с затравкой с использованием рекурсии.

F5. Простой алгоритм заполнения с затравкой с использованием рекурсии.

F6. Простой алгоритм заполнения с затравкой.

Комбинации этих алгоритмов распределяются между вариантами 01-25 так:

1) L1 - F1

6) L2 – F2

11) L2 – F3

16) L2 – F4

21) L2 – F5

2) L2 - F1

7) L3 – F2

12) L3 – F3

17) L3 – F4

22) L3 – F5

3) L4 - F1

8) L4 – F2

13) L4 – F3

18) L4 – F4

23) L4 – F5

4) L5 - F1

9) L5 – F2

14) L5 – F3

19) L5 – F4

24) L5 – F5

5) L1 – F2

10) L1 – F3

15) L1 – F4

20) L1 – F5

25) L1 – F6

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

Задание 2. Построить алгоритм для генерации точек указанной кривой, принадлежащих данной четверти.

Варианты заданий.

1)   x2 + y2 = R2,                I

8)     y = ax2, a > 0,                                       II

15)   y = ax3, a < 0,       II

2)   y = ax2, a > 0,              I

9)     y= ax3, a > 0,                                      III

16)   a2x3 - y2 = 0,          I

3)   y = ax3, a > 0,              I

10)   x2 / a2 - y2 / b2 = 1,                                       II

17)   x2/a2 - y2/b2 = 1,                                     III

4)   x2 / a2 - y2 / b2 = 1,        I

11)   y2= 2px, p > 0,                                      IV

18)   x2 + y2 = R2,                                     III

5)   y2 = 2px, p > 0,            I

12)   ay3 – x = 0, a > 0,    I

19)   y= ax2, a < 0,                                     IV

6)   x2 + y2 = R2,                 II

13)   x2 + y2 = R2,                                      IV

20)   y = ax3, a < 0,                                     III

7)   ay3 - x = 0, a > 0,                                         IV

14)   y = ax2, a < 0,                                      III

21)   a2x3 - y2 = 0,                                     IV

22)   x2 / a2 - y2 / b2 = 1,           IV

24)   ay3 – x = 0, a > 0,                       III

23)   x2 / a2 + y2 / b2 = 1,          IV

25)   ay3 – x = 0, a < 0,                       IV

ПРИМЕР ВЫПОЛНЕНИЯ ЗАДАНИЯ 1

Задание. Используя алгоритм Брезенхема, вывести на экран треугольник и, используя алгоритм закраски с запоминанием точек границы в стек, закрасить его.

Решение. Ниже мы  рассмотрим реализацию, при которой стек представляется  в виде  массива. За основу возьмем пример 2.1.

Программа

#include <conio.h>

#include <graphics.h>

#include <math.h>

#define pop() stx[--deep]

#define push(x) stx[deep++]=x

/*Вывод горизонтального отрезка с

координатами начала (x0,y) и конца (x1,y)*/

void horline (int y, int x0, int x1)

{

int i;

if (x0>x1) {i=x1; x1=x0; x0=i;}

for (i=x0; i<=x1; i++) putpixel (i, y,15 ) ;

}

//Вывод закрашенного многоугольника

//dimar - число вершин многоугольника

//arx - массив x координат вершин

//ary - массив y координат вершин

void fl(int *arx, int *ary, int dimar)

{

int deep=0;

int stx[1000];                      /*Стек в виде массива*/

int i0, iglob, ix0, iy0, ix1, iy1;

int ymin;

int ix, iy, deltax , deltay, esh, sx, sy;

int temp, swab, i;

i0=0; ymin=ary[0];

/*Находим вершину с наименьшей y координатой

ary[i]*/

for (i=0;i<dimar;i++)

if (ary[i]<ymin) {i0=i; ymin=ary[i];}

/*Вывод стороны многоугольника от вершины i к вершине i+1,

от (arx[i], ary[i]) до  (arx[i+1], ary[i+1])*/

iglob = i0 ;

do      {

ix0=arx[iglob]; iy0=ary[iglob];

iglob++; if (iglob==dimar) iglob=0;

ix1=arx[iglob]; iy1=ary[iglob];

//основной цикл - вывод отрезка – генерация точек отрезка по

//алгоритму Брезенхема

ix=ix0;

iy=iy0;

deltax=abs(ix1-ix0);    //dx

deltay=abs(iy1-iy0);    //dy

if (ix1-ix0>=0) sx=1; else sx=-1;

if (iy1-iy0>=0) sy=1; else sy=-1;

//Если направление y главное, то перестановка dx и dy

if (deltay>deltax) {temp=deltax; deltax=deltay; deltay=temp; swab=1;}

else swab = 0;    //Былаперестановка

esh=2*deltay-deltax;      //E

for (i=1;i<=deltax;i++)

{

while (esh>=0)

{

if (swab==1) ix=ix+sx;

else

{

iy=iy+sy;

                        //При увеличении y на единицу, заносим

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

if (sy==1) push (ix) ;

                        //При уменьшении y на единицу, извлекаем

                        //координату x из стека и проводим

                        //горизонтальный отрезок

if (sy==-1) {temp=pop(); horline(iy,ix,temp);}

}

esh=esh-2*deltax ;

}

if (swab==1)

{

iy=iy+sy;

if (sy==1) push(ix);

if (sy==-1)

{

temp=pop();

horline(iy,ix,temp);

}

}

else ix=ix+sx;

esh=esh+2*deltay;

}

      //Пока не рассмотрены все вершины многоугольника

} while (i0!=iglob) ;

}

void main()

{

int gd=DETECT,gm;

int arx[3]={200,250,100}; //x координатывыводимоготреугольника

int ary[3]={120,180,60}; //y координаты выводимого треугольника

initgraph(&gd,&gm,""); //Инициализация графического режима

/*Вызов функции fl, которая выводит стороны многоугольника

используя алгоритм Брезенхема, и закрашивает многоугольник,

используя алгоритм с запоминанием точек границы в стек*/

fl(arx,ary,3);

getch();

closegraph();   //Выход из графического режима

}

Результат работы программы

ПРИМЕР ВЫПОЛНЕНИЯ ЗАДАНИЯ 2

Задание. Построить алгоритм для генерации точек эллипса во второй четверти методом приращений.

Решение. Для выполнения этого задания будем опираться на пример, изложенный в п.п. 2.3 данного пособия.

Уравнение эллипса  запишем в виде . В качестве начальной точки в нашем случае можно выбрать точку (0, b) или (-a, 0). Выбираем точку x= 0, y0 = b. Направление движения вдоль кривой – против часовой стрелки. В этом случае сначала выводится отрезок кривой, для которого вектор касательной V принадлежит пятой октанте, а затем отрезок, для которого вектор V1 принадлежит шестой октанте (рис. 27).

Запишем градиент функции f

.

Вектор касательной  перпендикулярен градиенту f и принадлежит пятой октанте (рис. 20) для x и y, принадлежащих второй четверти, так как и .

Запишем условие, при выполнении которого, вектор касательной принадлежит пятой октанте: , в нашем случае: . Учитывая, что < 0 и  y > 0, так как они принадлежат второй четверти, получаем условие . Если вектор касательной принадлежит пятой октанте (рис. 28), то возможны перемещения:

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

Вычислим соответствующие приращения функции f(x,y)

f(x-1, y) - f(x,y)     = b2(x-1)+ a2y- a2b- b2x- a2y+ a2b2      =  b2(-2x+1) > 0,

f(x-1, y-1) - f(x,y) = b2(x-1)+ a2(y-1)- a2b- b2x- a2y+ a2b2 = b2(-2x+1)+ a2(-2y+1) < 0.

Первое приращение положительно, так как x < 0, а второе приращение отрицательно, так как y > 0 и a2y > ½b2x½ для этого отрезка кривой.

Для второго отрезка эллипса вектор касательной принадлежит шестой октанте. В этом случае (рис. 29) выполняются условия ½Vx½ < ½Vy½ и Vx £ 0. Первое условие после вывода первого отрезка эллипса будет выполнено, следовательно, второе условие (Vx £ 0) определяет принадлежность вектора касательной шестой октанте. Точнее, выполнение этого условия гарантирует, что вектор касательной принадлежит шестой, а не седьмой октанте, Так как Vx = -2a2y,  то это условие запишется следующим образом: -2a2£ 0 или ³0.

Так как вектор касательной принадлежит шестой октанте

Похожие материалы

Информация о работе