32
Rasterização de linhas e polígonos

Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Embed Size (px)

Citation preview

Page 1: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Rasterização de linhas e polígonos

Page 2: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Algoritmos de rasterização de linhas

Suponha x > ySuponha x > y

incrementa x evê o que acontece com y

incrementa y evê o que acontece com x

x = 5, y =3

Page 3: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

void Line(int x1, int y1, int x2, int y2, long int color){ float m = (y2-y1)/(x2-x1); float b = y1 - m*x1; float y; SetPixel(x1,y1, color); while( x1 < x2 ) { x1++; y = m*x1 + b; SetPixel(x1,ROUND(y), color); }}

Algoritmo simples de linha(no primeiro octante)

yi = m xi + b

onde:m = y/xb = y1 - m x1

Page 4: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

void LineDDA(int x1, int y1, int x2, int y2, int color){ float y; float m = (y2-y1)/(x2-x1); SetPixel(x1,y1, c); y = y1;

while( x1 < x2 ) { x1++; y += m; SetPixel(x1,ROUND(y), c); }}

Algoritmo de linha incremental

Se xi+1 = xi + 1

entãoyi+1 = yi + y/x

Page 5: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Algoritmo de linha baseado no erro

erro de manter y

0.5

- 0.

5

x

Page 6: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

void BresLine0(int x1, int y1, int x2, int y2, int c){ int Dx = x2 – x1; int Dy = y2 - y1; float e= -0.5;

SetPixel(x1, y1, c);

while( x1 < x2 ) { x1++; e+=Dy/Dx; if (e>=0) { y1++ ; e -= 1; } SetPixel(x1, y1, c); }}

Algoritmo de linha baseado no erro

erro de manter y

0.5

- 0.

5

x

e = erro - 0.5

x

0.5

- 0.

5

Page 7: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Algoritmo de Bresenham

void BresLine1(int x1, int y1, int x2, int y2, int c){ int Dx = x2 - x1; int Dy = y2 - y1; int ei = -Dx;

SetPixel(x1, y1, c);

while( x1 < x2 ) { x1++; ei += 2*Dy; if (ei>=0) { y1++ ; ei -= 2*Dx; } SetPixel(x1, y1, c); }}

void BresLine1(int x1, int y1, int x2, int y2, int c){ int Dx = x2 - x1; int Dy = y2 - y1; int ei = -Dx;

SetPixel(x1, y1, c);

while( x1 < x2 ) { x1++; ei += 2*Dy; if (ei>=0) { y1++ ; ei -= 2*Dx; } SetPixel(x1, y1, c); }}

void BresLine0(int x1, int y1, int x2, int y2, int c){ int Dx = x2 - x1; int Dy = y2 - y1; float e= -0.5;

SetPixel(x1, y1, c);

while( x1 < x2 ) { x1++; e+=Dy/Dx; if (e>=0) { y1++ ; e -= 1; } SetPixel(x1, y1, c); }}

void BresLine0(int x1, int y1, int x2, int y2, int c){ int Dx = x2 - x1; int Dy = y2 - y1; float e= -0.5;

SetPixel(x1, y1, c);

while( x1 < x2 ) { x1++; e+=Dy/Dx; if (e>=0) { y1++ ; e -= 1; } SetPixel(x1, y1, c); }}

ei = 2*Dx*e

válidos somente quando Dx>Dy, x2 > x1 e y2 > y1

Page 8: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Equação implícita da reta

x1 x2

y1

y2

x

yBx

Dx

Dyy

0...),( DxByDxxDyyxF

DxDyn

F x y( , ) 0

F x y( , ) 0

F x y a x b y c( , ) . .

E

NE

xp xp+1 xp+2

yp

Myp+1/2

Page 9: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Algoritmo do ponto médio- variável de decisão -

d F x y a x b y cp p p p ( , ) ( ) ( )1 112

12

F Mescolha NE

escolha E( )

0

0

E

d F x y a x b y cnew p p p p ( , ) ( ) ( )2 212

12

d d anew old

d F x y a x b y cnew p p p p ( , ) ( ) ( )2 232

32

d d a bnew old NE

E a

NE a b

E

NE

xp xp+1 xp+2

yp

Myp+1/2

yp+3/2MNE

ME

Page 10: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Algoritimo do ponto médio- redução para inteiros -

d F x y a x b y cstart ( , ) ( ) ( )0 01

2 0 01

21 1

d F x y a b a bstart ( , ) / /0 0 2 2

E

NE

a

a b

d a bstart 2.

E

NE

a

a b

2

2

d F x y2. ( , )

Page 11: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Algoritimo do ponto médio- código C -

void linhaPM(int x1, int y1, int x2, int y2){ int a = y2-y1; int b = x1-x2; int d=2*a+b; /* valor inicial da var. decisao */ int incrE = 2*a; /* incremento p/ mover E */ int incrNE = 2*(a+b); /* incremento p/ mover NE */ fragmento(x1,y1);

while (x1<x2) { x1++; if (d<=0) /* escolha E */ d+=incrE; else { /* escolha NE */ d+=incrNE; y1++; } fragmento(x1,y1); }

}

Page 12: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Estilos de linha

void linhaPM(int x1, int y1, int x2, int y2){ int a = y2-y1; int b = x1-x2; int d=2*a+b; /* valor inicial da var. decisao */ int incrE = 2*a; /* incremento p/ mover E */ int incrNE = 2*(a+b); /* incremento p/ mover NE */ int style[8]={1,1,0,0,1,1,0,0}; int k=1; fragmento(x1,y1); /* primeiro pixel */

while (x1<x2) { x1++; if (d<=0) /* escolha E */ d+=incrE; else { /* escolha NE */ d+=incrNE; y1++; } if (style[(++k)%8]==1) fragmento(x1,y1); }

}

Page 13: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Rasterização de Retas-caso geral-

x

y

outros quadrantes

x

y

1

22

1

orientação

Page 14: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Rasterização de Cônicas

x

y

F(x,y) = 0

F

F

xF

y

450

x

y

simetrias do círculo:cada ponto calculado define 8 pixels

Page 15: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Rasterização de Cônicas

E

SE

MME

MSE

F(x,y) = 0

x

y

y=raio; for (x=0; x< y; x++) { if F(M)<0 escolha E else escolha SE Pixel (E ou SE) pinte os simétricos}

Page 16: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Preenchimento de polígonos

y

ys

x

0

1

23

4

i0i1 i3i4

0xi1 xi0 xi4 xi3

ymax

ymin

dados:{x0, x1, x2, x3, x4}{y0, y1, y2, y3, y4}

dados:{x0, x1, x2, x3, x4}{y0, y1, y2, y3, y4}

acha ymax e ymin

Para cada ys[ymax , ymin]

Para cada aresta calcula as interseções

ordena interseções

desenha linhas horizontais

acha ymax e ymin

Para cada ys[ymax , ymin]

Para cada aresta calcula as interseções

ordena interseções

desenha linhas horizontaisvx= {xi1 , xi0 , xi4 , xi3}

vx= {xi1 , xi0 , xi4 , xi3}

Page 17: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Preenchimento de polígonos(scan passando por vértices)

y

ys

x

01

2

3 5

i0 i2i3

0

i1 i4

4

Page 18: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Preenchimento de polígonos(scan passando por vértices)

y

ys

x

01

2

3 5

i0 i2i3

0

i1 i4

4

inclui vértices: i0-i1, i2-i3, i4-?

inclui vértices: i0-i1, i2-i3, i4-?

não inclui vértices: i0-?

não inclui vértices: i0-?

y

ys

x

01

2

3 5

i0 i2

i3

0

i1 i4

4

y

ys

x

01

2

3 5

i0

04

Page 19: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Interseção nos vértices

ousó inclui vértices de menor y: i0-i4

só inclui vértices de menor y: i0-i4

só inclui vértices de maior y: i0-i1, i2-i3

só inclui vértices de maior y: i0-i1, i2-i3

reta horizontal não produz interseçãoreta horizontal não produz interseção

Page 20: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

void FillPolygon (int np, int *x, int *y){ /* declarações */ . . .

/* calcula y max e min dos vértices*/ . . .

for(ys=ymim; ys<=ymax; ys--) /* para cada linha de scan */ { num_inters = 0; for(i=0; i<np; i++) /* para cada aresta */ { yi = y[i]; yf = y[(i+1)%np]; if (yi!=yf && ys >= MIN(yi,yf) && ys < MAX(yi,yf) ) { vxs[num_inters] = x[i] + (ys-yi)*(x[(i+1)%np]-x[i])/(yf-yi); num_inters++; } }

ordena(vxs,0,num_inters-1); /* ordena as interseções */

for (i=0;i<num_inters;i+=2) if (vxs[i]+1 <= vxs[i+1]) ScanLine(vxs[i],vxs[i+1],ys);}

Algoritmo de Fill

Page 21: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Otimizações do algoritmo de fill

dx = (x1-x0)/(ymax-ymin)

x (ou z)

y

ymin

ymax

ysys+1

x1x0

dy = 1

x = x+dxx = x+dx

Lista de Arestasstruct edge{ int y_max; /* maior y da aresta */ int y_min; /* menor y da aresta */ float xs; /* x correspondente a ys */ /* (no início é o correspondente a y_max) */ float delta_xs; /* incremento de xs entre duas linhas de scan */};

Page 22: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Algoritmo de Fill de Polígonos (Parte 1-Alocação de Memória)

#define Max(a,b) (((a) > (b)) ? (a) : (b))#define Min(a,b) (((a) < (b)) ? (a) : (b))

void fill (int np, int *x, int *y){ static struct edge *aresta=NULL; /* vetor de arestas */ static int *vxs=NULL; /* vetor de interseções */ static int old_np=0; /* número de pontos da última chamada */

int ymax, ymin; /* limites do polígono */ int num_inters; /* num. de interseções */ int num_arestas; /* num. de arestas */ int ys; /* ordenada da reta de scan */ int i;

/* realoca os vetores de arestas e de interseções */ if (np > old_np) { old_np=np; if (vxs) free (vxs); if (aresta) free (aresta); vxs=(int *) malloc ((np-1)*sizeof(int)); /* max num. De inters.*/ aresta=(struct edge *) malloc (np*sizeof(struct edge)); }

/* CONTINUA NA PARTE 2 */

Page 23: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Algoritmo de Fill de Polígonos (Parte 2-Lista de Arestas)

/* PARTE 1*/

/* calcula y max e min e monta o vetor de arestas */ ymax = y[0]; ymin = y[0]; num_arestas = 0; for(i=0;i<np;i++) { int i1=(i+1)%np; if (y[i] != y[i1]) {

aresta[num_arestas].y_max = Max(y[i],y[i1]);aresta[num_arestas].y_min = Min(y[i],y[i1]);

aresta[num_arestas].delta = ((float)(x[i1]-x[i])/ (float)(y[i1]-y[i]));

if (aresta[num_arestas].y_mim == y[i]) aresta[num_arestas].xs = x[i];else aresta[num_arestas].xa = x[i1];

if (aresta[num_arestas].y_max > ymax) ymax = aresta[num_arestas].y_max;

if (aresta[num_arestas].y_min < ymin) ymin = aresta[num_arestas].y_min;

num_arestas++; } }/* CONTINUA NA PARTE 3 */

Page 24: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Algoritmo de Fill de Polígonos (Parte 3-Varredura)

/* PARTES 1 E 2 */

for(ys=ymin; ys<ymax; ys++) /* para cada linha de scan */ { num_inters = 0; for(i=0; i<num_arestas; i++) { if (aresta[i].y_max < ys){ /* retira da lista de arestas */ aresta[i] = aresta[num_arestas-1]; num_arestas--; } if((ys>=aresta[i].y_min)&&(ys<aresta[i].y_max)){ /* intersepta */ vxs[num_inters] = aresta[i].xs; aresta[i].xs += aresta[i].delta; /* atualiza o xs */ num_inters++; } } /* for */

ordena(vxs,0,num_inters-1); /* ordena as interseções */

for(i=0;i<num_inters;i+=2) if (vxs[i]+1 <= vxs[i+1]) hline(vxs[i],vxs[i+1],ys,0xff); }} /* fill */

/* FIM */

Page 25: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Ordenação no Algoritmo de Fill

static void ordena(int *vxs, int left, int right){ int i,j; int a;

i = left; j = right; a = vxs[(left + right)/2]; do { while (vxs[i] < a && i < right) i++; while (a < vxs[j] && j > left) j--; if (i<=j)

{ int b = vxs[i]; vxs[i] = vxs[j]; vxs[j] = b; i++;j--;}

} while (i<=j); if (left < j) ordena(vxs,left,j); if (i < right) ordena(vxs,i,right);}

Page 26: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Caso Particular: Triângulo

B

A

C

a

b

c

x

y A

Page 27: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

int triangleDraw( Triangle triangle ) { float xA,yA, xB,yB, xC,yC, dx1,dy1, dx2,dy2, dx3,dy3; float xLeft,yLeft, xRight,yRight;

triangleGetABC( triangle, &xA, &yA, &xB, &yB, &xC, &yC );

dx1 = ( ( yB - yA ) > 0) ? ( ( xB - xA ) / ( yB - yA ) ) : 0; dx2 = ( ( yC - yA ) > 0) ? ( ( xC - xA ) / ( yC - yA ) ) : 0; dx3 = ( ( yC - yB ) > 0) ? ( ( xC - xB ) / ( yC - yB ) ) : 0;

xLeft = xRight = xA; yLeft = yRight = yA;

if( dx1 > dx2 ) { while( yLeft <= yB ) { horizontalLine( (int)xLeft, (int)xRight, (int)yLeft ); ++yLeft; ++yRight; xLeft += dx2; xRight += dx1; } xRight = xB; yRight = yB; while( yLeft <= yC ) { horizontalLine( (int)xLeft, (int)xRight, (int)yLeft ); ++yLeft; ++yRight; xLeft += dx2; xRight += dx3; } } else { . . .} return 0;}

Page 28: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

int triangleDraw( Triangle triangle ) { . . . if( dx1 > dx2 ) { while( yLeft <= yB ) { horizontalLine( (int)xLeft, (int)xRight, (int)yLeft ); ++yLeft; ++yRight; xLeft += dx2; xRight += dx1; } xRight = xB; yRight = yB; while( yLeft <= yC ) { horizontalLine( (int)xLeft, (int)xRight, (int)yLeft ); ++yLeft; ++yRight; xLeft += dx2; xRight += dx3; } } else { while( yLeft <= yB ) { horizontalLine( (int)xLeft, (int)xRight, (int)yLeft ); ++yLeft; ++yRight; xLeft += dx1; xRight += dx2; }

xLeft = xB; yLeft = yB; while( yLeft <= yC ) { horizontalLine( (int)xLeft, (int)xRight, (int)yLeft ); ++yLeft; ++yRight; xLeft += dx3; xRight += dx2; } } return 0;}

Page 29: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Triângulo decisão das arestas esquerda e direita

B

A

C

a

b

c

x

yA

a

xl xr

B

A

C

a

b

c

x

yA

a

xl xr

yA

yB

yC

yA

yB

yC

0bc

0bc

))(())(( ABACACAB yyxxyyxxbc

Page 30: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Triângulo loop superior

B

A

C

a

b

c

x

yA

a

xl xr

B

A

C

a

b

c

x

yA

a

xl xr

yA

yB

yC

yA

yB

yC

CACAr

BABAl

Arl

As

yyxxdx

yyxxdx

xxx

yy

BABAr

CACAl

Arl

As

yyxxdx

yyxxdx

xxx

yy

BAs yyy

Page 31: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Triângulo loop inferior

B

A

C

a

b

c

x

yA

a

xl xr

B

A

C

a

b

c

x

yA

a

xl xr

yA

yB

yC

yA

yB

yC

CACAr

BABAl

Arl

As

yyxxdx

yyxxdx

xxx

yy

BABAr

CACAl

Arl

As

yyxxdx

yyxxdx

xxx

yy

BAs yyy

Page 32: Rasterização de linhas e polígonos. Algoritmos de rasterização de linhas Suponha x > y incrementa x e vê o que acontece com y incrementa y e vê o que

Stipples, patterns e imagens

void SetPixel(int x,int y){ int i=(x-x0)%w; int j=(y-y0)%h;

if (stipple[i][j]) { Pixel(x,y,foreground); } else { if (backopacity) Pixel(x,y,background); }}

Stipple

void SetPixel(int x,int y){ color = pattern[(x-x0)%w][(y-y0)%h] Pixel(x,y,color);}

Pattern

w = 5

h = 5