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

Лабораторная работа №2 (растеризация треугольника)

.doc
Скачиваний:
13
Добавлен:
20.06.2014
Размер:
189.95 Кб
Скачать

2

ФЕДЕРАЛЬНОЕ АГЕНТСТВО ПО ОБРАЗОВАНИЮ

ГОСУДАРСТВЕННОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ

ВЫСШЕГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ

ЛИПЕЦКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ

КАФЕДРА АВТОМАТИЗИРОВАННЫХ СИСТЕМ УПРАВЛЕНИЯ

Лабораторная работа №2

по дисциплине

«Компьютерная графика»

на тему:

«Растеризация треугольника»

Студент

Филатов А.А.

подпись, дата

фамилия, инициалы

Группа

АС-09-1

Принял

Назаркин О.А.

ученая степень, звание

подпись, дата

фамилия, инициалы

Липецк 2010

1.Задание

Реализовать алгоритм растрирования треугольника, при условии, что вершины окрашены в разные цвета. Реализовать смешивание цветов внутри треугольника. Количество треугольников: 10.

2.Теория

Барицентрические координаты — координаты точки n-мерного аффинного пространства An, отнесенные к некоторой фиксированной системе из (n + 1)-ой точки , не лежащих в (n − 1)-мерном подпространстве.

Пусть z есть произвольная точка в An. Каждая точка  может быть единственным образом представлена в виде суммы

где  — вещественные числа, удовлетворяющие условию

Числа  называются барицентрическими координатами точки x. Легко видеть, что барицентрические координаты не зависят от выбора z.

Точка x является центром тяжести масс , расположенных в точках .

Формулы для расчета:

3.Алгоритм

Для одного треугольника:

1. Проверяем все пиксели, находятся они внутри треугольника или нет.

2. Вычисляются барицентрические координаты точки относительно вершин треугольника.

3. Определяем цвет пикселя исходя из цветов вершин и барицентрических координат и закрашиваем пиксель.

3. Пункты 1-3 выполняется 10 раз с другими параметрами (по количеству треугольников).

4.Листинг программы

#include <math.h>

#include <time.h>

#include <stdlib.h>

//параметры для преобразования координат из мировой системы координат в оконную

int width=1000;

int height=600;

int xmin=-width/2;

int xmax=width/2;

int ymin=-height/2;

int ymax=height/2;

int Xmax=width;

int Ymax=height;

//цвета

#define WHITE 0xFFFFFFFF

#define BLACK 0xFF000000

#define RED 0xFFFF0000

#define GREEN 0xFF00FF00

#define BLUE 0xFF0000FF

#define CYAN 0xFF00FFFF

#define MAGENTA 0xFFFF00FF

#define YELLOW 0xFFFFFF00

void Randomize()

{

srand(time(NULL));

}

int Random(int val)

{

return rand()%val;

}

struct Dot//пиксель

{

int x;

int y;

unsigned int color;

};

unsigned int ARGB(int a, int r, int g, int b)

{

if(a>255) a=255;

if(r>255) r=255;

if(g>255) g=255;

if(b>255) b=255;

return 0x00000000 | a<<24 | r<<16 | g<<8 | b;

}

unsigned int randomColor()

{

return 0xFF000000 | Random(255)<<16 | Random(255)<<8 | Random(255);

}

struct Dot randomDot(int sizeX,int sizeY)

{

struct Dot A;

A.x=Random(sizeX)-sizeX/2;

A.y=Random(sizeY)-sizeY/2;

A.color=ARGB(Random(256)+128,Random(256),Random(256),Random(256));

return A;

}

int Xs(int x)//перевод координаты х из мировой в оконную

{

return int(float(Xmax/(xmax-xmin))*(x-xmin));

}

int Ys(int y)//перевод координаты у из мировой в оконную

{

return int(Ymax-(y-ymin)*float(Ymax/(ymax-ymin)));

}

unsigned int AlphaBlend(const unsigned int bg, const unsigned int src)//альфа-наложение, bg - фон, src - пиксель

{

unsigned int a = src >> 24;

if(!a)

return bg;

unsigned int bg_r=(bg>>16)%256;

unsigned int bg_g=(bg>>8)%256;

unsigned int bg_b=(bg)%256;

unsigned int src_r=(src>>16)%256;

unsigned int src_g=(src>>8)%256;

unsigned int src_b=(src)%256;

int r=int(bg_r*double((255-a)/255.)+src_r*double(a/255.));

int g=int(bg_g*double((255-a)/255.)+src_g*double(a/255.));

int b=int(bg_b*double((255-a)/255.)+src_b*double(a/255.));

if(r>255) r=255;

if(g>255) g=255;

if(b>255) b=255;

return 0xFF000000 | r<<16 | g<<8 | b;

}

unsigned int Blending(unsigned int color1,unsigned int color2,unsigned int color3)//смешивание трех цветов

{

int a1=color1>>24;

int a2=color2>>24;

int a3=color3>>24;

int r1=(color1>>16)%256,g1=(color1>>8)%256,b1=color1%256;

int r2=(color2>>16)%256,g2=(color2>>8)%256,b2=color2%256;

int r3=(color3>>16)%256,g3=(color3>>8)%256,b3=color3%256;

int a=a1+a2+a3;

int r=int(r1*double(a1/255.)+r2*double(a2/255.)+r3*double(a3/255.));

int g=int(g1*double(a1/255.)+g2*double(a2/255.)+g3*double(a3/255.));

int b=int(b1*double(a1/255.)+b2*double(a2/255.)+b3*double(a3/255.));

if(a>255) a=255;

if(r>255) r=255;

if(g>255) g=255;

if(b>255) b=255;

return 0x00000000 | a<<24 | r<<16 | g<<8 | b;

}

unsigned int AlphaColor(unsigned int color, int alpha)//возврат цвета color с прозрачностью alpha

{

int r=(color>>16)%256,g=(color>>8)%256,b=color%256;

if(alpha>255) alpha=255;

//alpha=255-alpha;

return 0x00000000 | alpha<<24 | r<<16 | g<<8 | b;

}

bool IdenticalSignTriangle(struct Dot A,struct Dot B,struct Dot C,struct Dot D)//проверка, лежат ли точки С и D по одну сторону прямой АВ

{

double p1=double(B.y-A.y)/double(B.x-A.x)*double(C.x-A.x)-double(C.y-A.y);

double p2=double(B.y-A.y)/double(B.x-A.x)*double(D.x-A.x)-double(D.y-A.y);

if((p1>0 && p2>0) || (p1<=0 && p2<=0))

return true;

return false;

}

bool BelongTriangleLine(struct Dot A,struct Dot B,struct Dot C,struct Dot D)//проверка принадлежности точки треугольнику

{

if(IdenticalSignTriangle(A,B,C,D) && IdenticalSignTriangle(C,A,B,D) && IdenticalSignTriangle(B,C,A,D))

return true;

return false;

}

double distDotLine(struct Dot A,struct Dot B,struct Dot D)//расстояние от точки D до прямой АВ (по перпендикуляру)

{

double a=B.y-A.y;

double b=A.x-B.x;

double c=A.x*(A.y-B.y)+A.y*(B.x-A.x);

return abs((a*D.x+b*D.y+c)/sqrt(a*a+b*b));

}

void drawTriangle(unsigned int *pDest, struct Dot A,struct Dot B,struct Dot C)//рисование треугольника с вершинами А,В,С в массиве pDest

{

int x,y;

struct Dot D;

double pa, pb, pc;

for(y=ymax;y>ymin;y--)

for(x=xmin;x<xmax;x++)

{

D.x=x;

D.y=y;

pa=double((B.y-C.y)*(D.x-C.x)+(C.x-B.x)*(D.y-C.y))/double((B.y-C.y)*(A.x-C.x)+(C.x-B.x)*(A.y-C.y));

pb=double((C.y-A.y)*(D.x-C.x)+(A.x-C.x)*(D.y-C.y))/double((C.y-A.y)*(B.x-C.x)+(A.x-C.x)*(B.y-C.y));

pc=1-pa-pb;

if(BelongTriangleLine(A,B,C,D))

{

D.color=Blending(AlphaColor(A.color,int(pa*255.)),AlphaColor(B.color,int(pb*255.)),AlphaColor(C.color,int(pc*255.)));

pDest[Ys(y)*width+Xs(x)]=D.color;

}

}

}

struct Dot createDot(int x,int y,unsigned int color)//возвращает заполненную структуру (подобие конструктора)

{

struct Dot A;

A.x=x;

A.y=y;

A.color=color;

return A;

}

void FillData(void *data, int Width, int Height)//функция рисование шести треугольников

{

width=Width;

height=Height;

unsigned int* pDest = (unsigned int*)data;

unsigned int background=0xFFFFFFFF;

for(int y=ymax;y>ymin;y--)

for(int x=xmin;x<xmax;x++)

{

pDest[Ys(y)*width+Xs(x)]=background;

if(!x || !y)

pDest[Ys(y)*width+Xs(x)]=0xFF888888;

}

drawTriangle(pDest,createDot(0,0,WHITE),createDot(0,200,RED),createDot(150,100,YELLOW));

drawTriangle(pDest,createDot(0,0,WHITE),createDot(150,100,YELLOW),createDot(150,-100,GREEN));

drawTriangle(pDest,createDot(0,0,WHITE),createDot(150,-100,GREEN),createDot(0,-200,CYAN));

drawTriangle(pDest,createDot(0,0,WHITE),createDot(1,-200,CYAN),createDot(-150,-100,BLUE));

drawTriangle(pDest,createDot(0,0,WHITE),createDot(-150,-100,BLUE),createDot(-150,100,MAGENTA));

drawTriangle(pDest,createDot(0,0,WHITE),createDot(-150,100,MAGENTA),createDot(1,200,RED));

Randomize();

drawTriangle(pDest,createDot(-500,300,randomColor()),createDot(-50,250,randomColor()),createDot(-450,10,randomColor()));

drawTriangle(pDest,createDot(500,300,randomColor()),createDot(50,250,randomColor()),createDot(450,10,randomColor()));

drawTriangle(pDest,createDot(-500,-300,randomColor()),createDot(-50,-250,randomColor()),createDot(-450,-10,randomColor()));

drawTriangle(pDest,createDot(500,-300,randomColor()),createDot(50,-250,randomColor()),createDot(450,-10,randomColor()));

}

5.Контрольный пример