Rasterização de linhas e polígonos Algoritmos de rasterização de linhas Suponha > incrementa e vê o que acontece com = 5, =3 incrementa e vê o que acontece com Rasterização de Primitivas 1
Algoritmo simples de linha (no primeiro octante) i = m i + b onde: m = / b = 1 - m 1 void Line(int 1, int 1, int 2, int 2, int color) float m = (2-1)/(2-1); float b = 1 - m*1; float ; SetPiel(1,1, color); = 1; while( 1 < 2 ) 1++; = m*1 + b; SetPiel(1,ROUND(), color); Algoritmo de linha incremental Se i+1 = i + 1 então i+1 = i + / void LineDDA(int 1, int 1, int 2, int 2, int color) float ; float m = (2-1)/(2-1); SetPiel(1,1, c); = 1; while( 1 < 2 ) 1++; += m; SetPiel(1,ROUND(), c); Rasterização de Primitivas 2
Algoritmo de linha baseado no erro void BresLine(int 1, int 1, int 2, int 2, int c) int D = 2-2; int D = 2-1; float e= -.5; -.5.5 -.5.5 erro de manter e = erro -.5 SetPiel(1, 1, c); while( 1 < 2 ) 1++; e+=d/d; if (e>=) 1++ ; e -= 1; SetPiel(1, 1, c); Algoritmo de Bresenham ei = 2*D*e void void BresLine(int BresLine(int 1, 1, int int 1, 1, void void BresLine1(int BresLine1(int 1, 1, int int 1, 1, int int 2, 2, int int 2, 2, int int c) c) int int 2, 2, int int 2, 2, int int c) c) int int D D = = 2 2 -- 1; 1; int int D D = = 2 2 -- 1; 1; int int D D = = 2 2 -- 1; 1; int int D D = = 2 2 -- 1; 1; float float e= e= -.5; -.5; int int ei ei = = -D; -D; SetPiel(1, SetPiel(1, 1, 1, c); c); SetPiel(1, SetPiel(1, 1, 1, c); c); while( while( 1 1 < < 2 2 )) while( while( 1 1 < < 2 2 )) 1++; 1++; e+=d/d; e+=d/d; 1++; 1++; ei ei += += 2*D; 2*D; if if (e>=) (e>=) if if (ei>=) (ei>=) 1++ 1++ ;; e e -= -= 1; 1; 1++ 1++ ;; ei ei -= -= 2*D; 2*D; SetPiel(1, SetPiel(1, 1, 1, c); c); SetPiel(1, SetPiel(1, 1, 1, c); c); válidos somente quando D>D, 2 > 1 e 2 > 1 Rasterização de Primitivas 3
Equação implícita da reta 2 1 F (, ) < F(, ) > n = ( d d) d = d + B 1 2 F(, ) = d. d. + B. d = F(, ) = a. + b. + c p +1/2 p NE M E p p+1 p+2 Algoritmo do ponto médio - variável de decisão - p +3/2 M NE p +1/2 NE M M E escolha NE F( M) = > escolha E p E p p+1 p+2 d = F( + 1, + ) = a( + 1) + b( + ) + c 1 1 p p 2 p p 2 E NE d = F( + 2, + ) = a( + 2) + b( + ) + c 1 1 new p p 2 p p 2 d = d + a new old d = F( + 2, + ) = a( + 2) + b( + ) + c 3 3 new p p 2 p p 2 d = d + a + b new old E = a NE = a + b Rasterização de Primitivas 4
Algoritimo do ponto médio - redução para inteiros - dstart = F( + 1, + 1 2 ) = a( + 1) + b( + 1 2 ) + c d start= F (, ) + a + b / 2 = a + b / 2 = a E NE = a + b d d 2. a b = 2. F (, ) start= + E NE = 2a ( a b) = 2 + Algoritimo do ponto médio - código C - void MidpointLine(int, int, int 1, int 1, int color) int d = 1-; int d = 1-; int d=2*d-d; /* Valor inicial da var. decisao */ int incre = 2*d; /* incremento p/ mover E */ int incrne = 2*(d-d); /* incremento p/ mover NE */ int =; int =; Piel(,,fgcolor); /* Primeiro piel */ while (<l) if (d<=) /* Escolha E */ d+=incre; ++; else /* Escolha NE */ d+=incrne; ++; ++; Piel(,,color); /* while */ /* MidpointLine */ Rasterização de Primitivas 5
void MidpointLine(int, int, int 1, int 1, int color) int d = 1-; int d = 1-; int d=2*d-d; /* Valor inicial da var. decisao */ int incre = 2*d; /* incremento p/ mover E */ int incrne = 2*(d-d); /* incremento p/ mover NE */ int =; int =; int stle[8]=1,1,,,1,1,,; int k=1; Piel(,,fgcolor) while (<l) if (d<=) /* Escolha E */ d+=incre; ++; else /* Escolha NE */ d+=incrne; ++; ++; if (stle[(++k)%8]) Piel(,,color); /* while */ /* MidpointLine */ Estilos de linha 1 2 2 1 orientação Rasterização de Retas -caso geral outros quadrantes Rasterização de Primitivas 6
Rasterização de Cônicas F F(,) = = F F 45 simetrias do círculo: cada ponto calculado define 8 piels Rasterização de Cônicas =raio; for (=; < ; ++) if F(M)< escolha E else escolha SE Piel (E ou SE) pinte os simétricos E M SE M E M SE F(,) = Rasterização de Primitivas 7
Preenchimento de polígonos ma 1 4 dados:,, 1, 1, 2, 2, 3, 3, 4 4,, 1, 1, 2, 2, 3, 3, 4 4 s i1 i i4 i3 acha acha ma e ma e min min Para Para cada cada s s [ [ ma, ma, min ] min ] min 2 i1 i i4 i3 3 Para Para cada cada aresta aresta calcula as as interseções ordena interseções v= v= i1, i1, i, i, i4, i4, i3 i3 desenha linhas linhas horizontais Preenchimento de polígonos (scan passando por vértices) s 1 i i1 i2 i4 3 5 i3 2 4 inclui inclui vértices: i-i1, i-i1, i2-i3, i2-i3, i4-? i4-? não não inclui inclui vértices: i-? i-? s i 2 1 i1 i2 i4 3 i3 5 4 s 1 i 2 3 5 4 Rasterização de Primitivas 8
Interseção nos vértices só só inclui inclui vértices de de menor menor : : i-i4 i-i4 ou só só inclui inclui vértices de de maior maior : : i-i1, i-i1, i2-i3 i2-i3 reta reta horizontal não não produz interseção Algoritmo de Fill void FillPolgon (int np, int *, int *) /* declarações */... /* calcula ma e min dos vértices*/... for(s=mim; s<=ma; s--) /* para cada linha de scan */ num_inters = ; for(i=; i<np; i++) /* para cada aresta */ i = [i]; f = [(i+1)%np]; if (i!=f && s >= MIN(i,f) && s < MAX(i,f) ) vs[num_inters] = [i] + (s-i)*([(i+1)%np]-[i])/(f-i); num_inters++; ordena(vs,,num_inters-1); /* ordena as interseções */ for (i=;i<num_inters;i+=2) if (vs[i]+1 <= vs[i+1]) ScanLine(vs[i],vs[i+1],s); Rasterização de Primitivas 9
Otimizações do algoritmo de fill ma = +d +d s+1 s d = 1 min 1 (ou z) Lista de Arestas d = (1-)/( ma - min ) struct edge int _ma; /* maior da aresta */ int _min; /* menor da aresta */ float s; /* correspondente a s */ /* (no início é o correspondente a _ma) */ float delta_s; /* incremento de s entre duas linhas de scan */ ; Algoritmo de Fill de Polígonos (Parte 1-Alocação de Memória) #define Ma(a,b) #define Min(a,b) (((a) > (b))? (a) : (b)) (((a) < (b))? (a) : (b)) void fill (int np, int *, int *) static struct edge *aresta=null; /* vetor de arestas */ static int *vs=null; /* vetor de interseções */ static int old_np=; /* número de pontos da última chamada */ int ma, min; /* limites do polígono */ int num_inters; /* num. de interseções */ int num_arestas; /* num. de arestas */ int s; /* ordenada da reta de scan */ int i; /* realoca os vetores de arestas e de interseções */ if (np > old_np) old_np=np; if (vs) free (vs); if (aresta) free (aresta); vs=(int *) malloc ((np-1)*sizeof(int)); /* ma num. De inters.*/ aresta=(struct edge *) malloc (np*sizeof(struct edge)); /* CONTINUA NA PARTE 2 */ Rasterização de Primitivas 1
Algoritmo de Fill de Polígonos (Parte 2-Lista de Arestas) /* PARTE 1*/ /* calcula ma e min e monta o vetor de arestas */ ma = []; min = []; num_arestas = ; for(i=;i<np;i++) int i1=(i+1)%np; if ([i]!= [i1]) aresta[num_arestas]._ma = Ma([i],[i1]); aresta[num_arestas]._min = Min([i],[i1]); aresta[num_arestas].delta = ((float)([i1]-[i])/ (float)([i1]-[i])); if (aresta[num_arestas]._mim == [i]) aresta[num_arestas].s = [i]; else aresta[num_arestas].a = [i1]; if (aresta[num_arestas]._ma > ma) ma = aresta[num_arestas]._ma; if (aresta[num_arestas]._min < min) min = aresta[num_arestas]._min; num_arestas++; /* CONTINUA NA PARTE 3 */ Algoritmo de Fill de Polígonos (Parte 3-Varredura) /* PARTES 1 E 2 */ for(s=min; s<ma; s++) /* para cada linha de scan */ num_inters = ; for(i=; i<num_arestas; i++) if (aresta[i]._ma < s) /* retira da lista de arestas */ aresta[i] = aresta[num_arestas-1]; num_arestas--; if((s>=aresta[i]._min)&&(s<aresta[i]._ma)) /* intersepta */ vs[num_inters] = aresta[i].s; aresta[i].s += aresta[i].delta; /* atualiza o s */ num_inters++; /* for */ ordena(vs,,num_inters-1); /* ordena as interseções */ for(i=;i<num_inters;i+=2) if (vs[i]+1 <= vs[i+1]) /* fill */ hline(vs[i],vs[i+1],s,ff); /* FIM */ Rasterização de Primitivas 11
Ordenação no Algoritmo de Fill static void ordena(int *vs, int left, int right) int i,j; int a; i = left; j = right; a = vs[(left + right)/2]; do while (vs[i] < a && i < right) i++; while (a < vs[j] && j > left) j--; if (i<=j) int b = vs[i]; vs[i] = vs[j]; vs[j] = b; i++;j--; while (i<=j); if (left < j) ordena(vs,left,j); if (i < right) ordena(vs,i,right); Caso Particular: Triângulo A c b B a C Rasterização de Primitivas 12
Stipples, patterns e imagens Stipple void SetPiel(int,int ) int i=(-)%w; int j=(-)%h; h = 5 if (stipple[i][j]) w = 5 Piel(,,foreground); else if (backopacit) Piel(,,background); Pattern void SetPiel(int,int ) color = pattern[(-)%w][(-)%h] Piel(,,color); Rasterização de Primitivas 13