Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лекции по компьютерной графике

.pdf
Скачиваний:
60
Добавлен:
16.03.2015
Размер:
1.48 Mб
Скачать

Климентьев К.Е. Компьютерная графика (курс лекций).

Индивидуальные задания по теме “Алгоритмы построения и преобразования изображений”

1.Вращение и масштабирование фрагмента штрихового изображения

2.Перевод полутонового изображения в “серую гамму” и выделение контуров в режиме

3.Перевод полутонового изображения в “серую гамму” и последовательные матричные операции: 1) размывка контуров; 2) увеличение резкости.

4.Вращение “проволочной” фигуры (линии которой построены при помощи алгоритма Брезенхама) в плоскостях, перпендикулярных плоскости экрана.

5.Вращение символов 8х8 в плоскости экрана относительно заданного центра

6.Вращение “проволочной” фигуры в плоскости экрана

7.Наложение полутоновой текстуры на треугольник и вращение в плоскости экрана.

8.Наложение полутоновой текстуры на треугольник и вращение в плоскостях, перпендикулярных плоскости экрана.

9.Построение множества случайно расположенных окружностей и замкнутых четырехугольников, границы которых построены при помощи алгоритма Брезенхама и “заливка” получившихся замкнутых фигур при помощи рекурсивного алгоритма со случайной “затравкой”.

10.Построение объемного “проволочного” куба при помощи алгоритма Брезенхама и вращение его в плоскостях, перпендикулярных плоскости экрана.

11.Построение случайного лабиринта, линии которого построены при помощи алгоритма Брезенхама и обход его рекурсивным алгоритмом.

12.Построение “фигур Лиссажу” и заливка каждого сегмента отдельным цветом рекурсивным алгоритмом с затравкой.

13.Построение изображения “коридора”, стены и потолок которого покрыты полутоновыми текстурами

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

15.Вращающееся звездное небо.

16.“Лупа”. Масштабирование круглого фрагмента штрихового изображения.

17.Трансформации небольшого полутонового изображения: масштабирование, перемещение, вращение в плоскости экрана, симметричное отражение

18.“Спрайты”: перемещение небольшого изображения поверх другого.

19.Вращение фрагмента полутонового изображения в плоскости, перпендикулярной плоскости экрана

20.“Лупа”. Масштабирование фрагмента полутонового изображения.

Примечание. Лабораторная работа выполняется в операционной системе MS-DOS (возможно использование DOS-сессии операционных систем Windows 95/98/ME). Языки программирования: Pascal или C, рекомендуемые системы программирования: Turbo Pascal v6.0/7.0 и Borland C/C++ v3.1. Применение расширенных возможностей языка С++

(классов, перегруженных операторов и т.п.), а также использование языка ассемблера не допускается. Если не указано иное, то работа выполняется в графическом режиме

320x200x256.

51

Климентьев К.Е. Компьютерная графика (курс лекций).

Индивидуальные задания по теме “Программирование трехмерных изображений”

Вариант

ОреnGL

Win API

 

 

 

 

 

1

Бильярдный стол с шарами

Шар

 

2

Шахматная доска с фигурами

Круглая буханка хлеба

3

Бусы из разноцветных камней на

Яйцо

 

 

подоконнике

 

 

4

Египет: пирамиды и пальмы

Огурец

 

 

 

 

 

5

Сатурн с кольцами и спутниками

Капля

 

6

Футбольное поле с мячом

Груша

 

7

Елка с шарами

Головка чеснока

 

8

Самовар на столе

Цилиндр

 

9

Натюрморт на столе: яблоки, томаты и

Конус

 

 

корнишоны.

 

 

10

Яблоко и червяк

Урна

 

11

Снеговик зимой

Ваза

 

12

Сигарета в круглой пепельнице на столе

Тор

 

13

Пятачок с воздушным шариком

Спираль

 

14

Винни Пух с горшочком меда

Куб

 

15

Одуванчики на лугу

Тетраэдр

 

16

Чебурашка с флажком

Усеченный конус

 

17

Робот с лопатой

Юла

 

18

Коробок а столе с рассыпанными

Октаэдр

 

 

спичками

 

 

19

Бутылка с рюмками на столе

Трехгранная призма

 

20

Домик и деревья

Пятигранная призма

 

21

Сад с яблонями и грибами

Пистолетная пуля

 

22

Аист с младенцем в небе

Винтовочная пуля

 

23

Конфеты и чупа-чупсы на столе

Ромбовидная четырехгранная призма

24

Воздушный шар в небе с облаками

Дельтовидная

четырехгранная

 

 

призма

 

25

Ракета в космосе

Половинка цилиндра

 

Примечание. Лабораторная работа выполняется в операционной системе Windows с использованием Win32 API, а также стандартных библиотек DirectX (DirectDraw) и OpenGL. Изображение должно состоять из объемных геометрических фигур, с учетом перспективы и однотонного освещения. Языки программирования: C или Object Pascal. Рекомендуемые системы программирования: Borland C/C++ v5.0, Borland C/C++ Builder, MS Visual C/C++ v 6.0, допускается использование Borland/Inprise Delphi. Применение языка ассемблера не допускается. Если не указано иное, то графическим режимом по умолчанию является

800x600x256.

52

Климентьев К.Е. Компьютерная графика (курс лекций).

Задание по теме “Средства работы с графикой”

Создать HTML-страницу на тему “Про себя - любимого (-мую)”. Составляется на русском языке в кодировке Win-1251 и должна обязательно использовать следующие возможности:

заголовки разных уровней вложенности;

текстовые абзацы (параграфы);

жесткий разрыв строки;

горизонтальную разделительную линию;

пронумерованный или ненумерованный список;

изменение стилей текста: курсив, жирный, подчеркивание;

предварительно отформатированный текст;

центрированный фрагмент текста;

подстрочный (или надстрочный) индекс;

изменение размера шрифта;

измерение цвета шрифта;

изменение вида шрифта;

“запрещенные” символы: <, >, ”, & и т.п.;

таблицы;

масштабированные изображения;

ссылки на другие HTML-документы или в другую позицию текущего документа;

изменение цвета фона;

использование изображений в качестве фона.

Использование JavaScript-апплетов и прочих скриптов, таблиц стилей и форм вводавывода не допускается.

53

Климентьев К.Е. Компьютерная графика (курс лекций).

Примеры программ, демонстрирующих алгоритмы 2D- и 3D-графики

Вывод точки реализован в MS-DOS через BIOS, все остальное сделано полностью самостоятельно.

Вариант на Си.

#include <dos.h> #include <math.h> #include <stdio.h>

/*

Установить новый видеорежим:

380x25x16

4320x200x4 0x12 640x480x16 0x13 320x200x256 */

setvmode(unsigned char m) { union REGS r1; struct SREGS r2; r1.h.al=m;

r1.h.ah=0;

int86x(0x10, &r1, &r1, &r2);

}

/* Нарисовать точку цвета c в координатах x/y */ setpoint( int x, int y, unsigned char c) {

union REGS r1; struct SREGS r2; r1.h.ah=0xC;

r1.h.al=c;

r1.h.bh=0;

r1.x.cx=x;

r1.x.dx=y;

int86x(0x10, &r1, &r1, &r2);

}

/* Вспомогательные процедурки для рисования треугольника */ swap( int* x, int* y) { int tmp; tmp = *x; *x = *y; *y = tmp; } int countx(int x1,int y1,int x2,int y2,int yy)

{return x1+((yy-y1)*(x2-x1))/(y2-y1);}

/* Рисование треугольника */

triang(int xa, int ya, int xb, int yb, int xc, int yc, int c) { int x, y, x3, x4;

if (yc<yb) { swap(&xc, &xb); swap(&yc, &yb); } if (yc<ya) { swap(&xc, &xa); swap(&yc, &ya); } if (yb<ya) { swap(&xb, &xa); swap(&yb, &ya); } for(y=ya;y<yc;y++) {

if (y<yb) {

x3 = countx(xa, ya, xc, yc, y);

x4 = countx(xa, ya, xb, yb, y); if (x4<x3) swap(&x3, &x4);

for (x=x3;x<x4;x++) setpoint(x,y,c);

}

else {

x3 = countx(xa, ya, xc, yc, y);

x4 = countx(xb, yb, xc, yc, y); if (x4<x3) swap(&x3, &x4);

for (x=x3;x<x4;x++) setpoint(x,y,c);

}

}

}

#define XYZ struct xyz XYZ { double x, y, z; };

/*Расчет новых 3-мерных координат для точки, повернутой на углы alfa и beta*/ XYZ Rotate( XYZ t, double alfa, double beta) {

54

Климентьев К.Е. Компьютерная графика (курс лекций).

XYZ tmp;

alfa = alfa * (3.141592/180.); beta = beta * (3.141592/180.);

tmp.x = t.x*cos(alfa) - t.y*sin(alfa);

tmp.y = t.x*sin(alfa)*cos(beta) + t.y*cos(alfa)*cos(beta) - t.z*sin(beta); tmp.z = t.x*sin(alfa)*sin(beta) + t.y*cos(alfa)*sin(beta) + t.z*cos(beta); return tmp;

}

/* Расчет вектора из вершины грани на лампочку */ XYZ VLamp( XYZ l, XYZ v) {

XYZ tmp;

tmp.x = l.x - v.x; tmp.y = l.y - v.y; tmp.z = l.z - v.z; return tmp;

}

/*Расчет длины вектора*/ double VLen( XYZ t) {

return sqrt(t.x*t.x + t.y*t.y + t.z*t.z);

}

/* Расчет координат нормального вектора к грани */

XYZ Normal(XYZ t1, XYZ t2, XYZ

t3) {

XYZ nn;

- (t2.z-t1.z)*(t3.y-t1.y);

nn.x = (t2.y-t1.y)*(t3.z-t1.z)

nn.y = (t2.z-t1.z)*(t3.x-t1.x)

- (t2.x-t1.x)*(t3.z-t1.z);

nn.z = (t2.x-t1.x)*(t3.y-t1.y)

- (t2.y-t1.y)*(t3.x-t1.x);

return nn;

 

}

 

/* Расчет косинуса фи */ double CosFi( XYZ a, XYZ b) {

return (a.x*b.x + a.y*b.y + a.z*b.z)/(VLen(a)*VLen(b));

}

main() { /* Проверка */ unsigned char c;

int i, j;

XYZ s[20][20]; XYZ nnn; XYZ lll; XYZ Lamp; double cf;

/* Шаг 1 - расчет сетки для 3-мерного объекта */ for (i=0;i<20;i++) {

for (j=0;j<20;j++) { s[i][j].x=i*5+50; s[i][j].y=j*5+50; s[i][j].z=50*sin((i+j)/6.0)+50;

}

}

/* Шаг 2 - поворот граней сетки */ for (i=0;i<20;i++) {

for (j=0;j<20;j++) { s[i][j]=Rotate(s[i][j], 10, 25);

}

}

setvmode(0x13);

/* Отображение треугольников по точкам s[i,i] s[i+1,j] s[i,j+1] */ for (i=0;i<19;i++) {

for (j=0;j<19;j++) {

/* Рассчитали нормаль */ nnn=Normal(s[i][j], s[i+1][j], s[i][j+1]);

/* Рассчитать вектор на лампочку */ Lamp.x=30;

Lamp.y=180;

Lamp.z=210;

55

Климентьев К.Е. Компьютерная графика (курс лекций).

lll=VLamp( s[i][j], Lamp );

/* Рассчитать косинус фи между нормалью и вектором лампочки */ cf=CosFi(nnn,lll);

/* Нарисовать треугольник, закрасив его цветом, пропорциональным cos(фи) */ triang(

s[i][j].x, s[i][j].y, s[i+1][j].x, s[i+1][j].y, s[i][j+1].x, s[i][j+1].y, (cf+1)*8+16

); /* Нарисовать смежный треугольник для грани */

triang(

s[i+1][j+1].x, s[i+1][j+1].y, s[i+1][j].x, s[i+1][j].y, s[i][j+1].x, s[i][j+1].y, (cf+1)*8+16

);

}

}

 

scanf("%c",&c);

 

setvmode(3);

 

}

Вариант на Паскале

 

uses dos;

 

{--------------------------------------------------------------------------

}

{Изменение графического режима}

procedure gmode(m:byte); var r:registers; begin r.ah:=0; r.al:=m; intr($10, r) end;

{Рисование точки с координатами x,y и цветом c}

procedure pix(x,y:integer; c:byte); begin mem[$A000:$140*y+x]:=c end;

{--------------------------------------------------------------------------}

{Обмен 2-х переменных своими значениями} procedure swap( var x, y : integer);

var tmp : integer; begin tmp:=x; x:=y; y:=tmp end;

{Расчет очередной точки прямой линии}

function countx(x1, y1, x2, y2, yy : integer) : integer; begin

if y2<>y1 then countx:=x1+((yy-y1)*(x2-x1)) div (y2-y1) else countx:=x1 end;

{Рисование закрашенного треугольника цветом c}

procedure triangol( xa, ya, xb, yb, xc, yc : integer; c : byte);

var x, y, x3, x4 : integer;

 

begin

 

swap(yc, yb) end;

if (yc<yb) then begin swap(xc, xb);

if (yc<ya) then begin swap(xc, xa);

swap(yc, ya) end;

if (yb<ya) then begin swap(xb, xa);

swap(yb, ya) end;

for y:=ya to yc do begin

 

if (y<yb) then begin

x4 := countx(xa, ya, xb, yb, y);

x3

:= countx(xa, ya, xc, yc, y);

if

(x4<x3) then swap(x3, x4); for

x:=x3 to x4 do pix(x,y,c);

end

 

 

else begin

 

x3

:= countx(xa, ya, xc, yc, y); x4 := countx(xb, yb, xc, yc, y);

if

(x4<x3) then swap(x3, x4); for

x:=x3 to x4 do pix(x,y,c);

end end end;

 

{--------------------------------------------------------------------------

 

}

const

pi=3.1415926; gr=pi/180.0;

 

type xyz = record x, y, z : real end;

56

Климентьев К.Е. Компьютерная графика (курс лекций).

{Округление к ближайшему целому} function pin(x:real):integer; begin

if (x-round(x))<0.5 then pin:=round(x) else pin:=round(x+1.0); end;

{Поворот точки на углы alfa и beta для проецирования} procedure rot(var t: xyz; alfa, beta : real; var tmp:xyz); begin

alfa:=alfa*gr; beta:=beta*gr; tmp.x:=t.x*cos(alfa)-t.y*sin(alfa);

tmp.y:=t.x*sin(alfa)*cos(beta)+t.y*cos(alfa)*cos(beta)-t.z*sin(beta); tmp.z:=t.x*sin(alfa)*sin(beta)+t.y*cos(alfa)*sin(beta)+t.z*cos(beta);

end;

{Расчет длины вектора} function vlen(t:xyz):real;

begin vlen:=sqrt(sqr(t.x)+sqr(t.y)+sqr(t.z)) end;

{Определение координаты нормали к плоскости в точке } procedure normal(t1, t2, t3:xyz; var nn:xyz);

begin nn.x:=(t2.y-t1.y)*(t3.z-t1.z)-(t2.z-t1.z)*(t3.y-t1.y); nn.y:=(t2.z-t1.z)*(t3.x-t1.x)-(t2.x-t1.x)*(t3.z-t1.z); nn.z:=(t2.z-t1.z)*(t3.y-t1.y)-(t2.y-t1.y)*(t3.x-t1.x);

end;

{Расчет косинуса фи}

function cosfi(a, b:xyz):real;

begin cosfi:= (a.x*b.x+a.y*b.y+a.z*b.z)/(vlen(a)*vlen(b)) end; {----------------------------------------------------------------}

{Расчет точки для сферы}

procedure spoint(r, alfa, beta:real; var tmp:xyz); begin

alfa:=alfa*gr; beta:=beta*gr; tmp.x:=r*cos(alfa)*sin(beta); tmp.y:=r*cos(alfa)*cos(beta); tmp.z:=r*sin(alfa)

end;

{Расчет точки для тора}

procedure tpoint(r1, r2, alfa, beta:real; var tmp:xyz); begin

alfa:=alfa*gr; beta:=beta*gr; tmp.x:=(r1+r2*cos(alfa))*sin(beta); tmp.y:=(r1+r2*cos(alfa))*cos(beta); tmp.z:=r1*sin(alfa)

end;

{Расчет точки для цилиндра}

procedure cpoint(r, alfa, h, l:real; var tmp:xyz); begin

alfa:=alfa*gr;

tmp.x:=r*sin(alfa);

tmp.y:=r*cos(alfa);

tmp.z:=h*l;

end;

{Расчет точки поверхности, заданной красивым уравнением }

procedure

apoint(

xx, yy : real; var tmp:xyz );

begin

xx*20.0+100;

tmp.x :=

tmp.y :=

yy*20.0+100;

tmp.z :=

(sin(xx)*sin(yy))*50.0;

end;

 

 

const mx=50;

{Количество параллелей и меридианов}

dx=6.28/mx;

{Шаг сетки по X}

dy=6.28/mx;

{Шаг сетки по Y}

57

Климентьев К.Е. Компьютерная графика (курс лекций).

var

i, j : integer; xx, yy : real;

setka

: array

[0..mx-1] of array [0..mx-1] of xyz; {Массив сетки}

color

: byte;

{Цвет}

norm

: xyz;

{координаты нормали}

light

: xyz;

{координаты лампочки}

cf

: real;

{косинус фи}

begin

{Посчитать сетку узлов} yy:=-3.14;

for i:=0 to mx-1 do begin xx:=-3.14;

for j:=0 to mx-1 do begin apoint(xx, yy, setka[i][j]); xx:=xx+dx;

end;

yy:=yy+dy;

end;

{ Повернуть сетку на alfa=10 и beta=30 градусов } for i:=0 to mx-1 do begin

for j:=0 to mx-1 do begin

rot(setka[i][j], 10.0, 30.0, setka[i][j]) end

end;

{задаем координаты лампочки} light.x := 20;

light.y := 0; light.z := 20;

gmode($13); {Включение графического режима}

{Нарисовать сетку}

for i:=0 to mx-2 do begin for j:=0 to mx-2 do begin

{Расчитываем нормаль к грани, заданной 3-мя соседними вершинами} normal(setka[i][j], setka[i+1][j], setka[i][j+1], norm);

{Расчет косинуса фи между нормалью и вектором лампочки} cf := cosfi(norm, light);

{Расчет номера цвета - косинус от -1 до 1, результат будет от 16 до 31 } color := round((cf+1.0)*7.5)+16;

{Рисуем первый треугольник грани} triangol(

pin(setka[i][j].x), pin(setka[i][j].y), pin(setka[i+1][j].x), pin(setka[i+1][j].y), pin(setka[i][j+1].x), pin(setka[i][j+1].y), color);

{Рисуем второй треугольник грани} triangol(

pin(setka[i+1][j+1].x), pin(setka[i+1][j+1].y), pin(setka[i+1][j].x), pin(setka[i+1][j].y), pin(setka[i][j+1].x), pin(setka[i][j+1].y), color);

end end;

readln;

gmode(3); {Выключение графического режима}

end.

58