170 likes | 365 Views
Computação Gráfica Rodrigo Toledo. Rasterização de linha s. Desenhando uma linha. Como decidir quais pixels devem ser acesos para que seja traçada uma linha?. y. . y. y. x. Obs: Considere os cruzamentos de linhas e colunas como o centro dos pixels. x. x.
E N D
Computação Gráfica Rodrigo Toledo Rasterizaçãode linhas
Desenhando uma linha Como decidir quaispixels devem seracesos para que sejatraçada uma linha?
y y y x Obs: Considere os cruzamentos de linhas e colunas como o centro dos pixels x x • O que acontece quando a inclinação é maior que 1 (maior que 45º)? Método 1 • Para cada coluna ascender um pixel • Se inclinação > 1, inverte-se x e y. • Vamos considerar apenas o caso 0<inclinação<1 (observe que são 8 casos)
Exemplo (x2,y2) y=mx+b b (x1,y1) (5,3) (4,2.33) (9,4) 3 y=(1/3)x+1 (3,2) (4,2) 2 2 (5,2.66) 1 (3,2) 3 4 5 Calcula-se m e b 3a iteração 1a iteração 2a iteração Método 1 – eq. da reta e algoritmo yi = m xi + b onde: m= Dy/Dx b = y1 - m x1 void Line1(int x1, int y1, int x2, int y2, int color) { float m = (y2-y1)/(x2-x1); float b = y1 - m*x1; float y; int x; PutPixel(x1,y1,color); for (x=x1+1; x<=x2; x++) { y = m*x + b; PutPixel(x,ROUND(y), color); } }
② addition ① multiplication ③ round operation Como tirar a multiplicação? Como melhorar o algoritmo? void Line2(int x1, int y1, int x2, int y2, int color) { float m = (y2-y1)/(x2-x1); float b = y1 - m*x1; float y; int x; PutPixel(x1,y1,color); for (x=x1+1; x<=x2; x++) { y = m*x + b; PutPixel(x,ROUND(y), color); } }
Método 2 – Algoritmo de linha incremental Se xi+1 = xi + 1 então yi+1 = yi + Dy/Dx void LineDDA(int x1, int y1, int x2, int y2, int color) { float y; float m = (y2-y1)/(x2-x1); int x; PutPixel(x1,y1,color); y = y1; for (x=x1+1; x<=x2; x++) { y += m; PutPixel(x,ROUND(y), color); } } m • Ainda são necessários uma adição de floats e uma round operation. • É possível fazer um algoritmo apenas com somas de inteiros.O nome desse algoritmo é: Bresenham’s algorithm.
NE yk+1 E yk xk+1 xk xk+1 xk Bresenham’s Line Drawing Algorithm • No processo de rasterização de (x1,y1) para (x2,y2), suponha que o pixel (xk, yk) já foi desenhado. • Obviamente, a posição X do próximo pixel é: xk+1. • 0<m<1, então a posição Y do próximo pixel é: ykou yk+1. • Qual devemos escolher? E=(xk+1, yk) or NE=(xk+1, yk+1)?
Bresenham’s Line Drawing Algorithm NE NE yk+1 yk+1 ek+1 m m ek+1 ek ek yk yk E E (xk,yk) (xk,yk) Algoritmo: • Estima-se o novo erro (ek+1) caso a escolha seja o pixel E (yk+1= yk) • ek+1 = ek + m • Se (ek+1 > 0.5) significa que deveríamos escolher NE (yk+1= yk +1) • Neste caso, o valor correto para ek+1 é:ek+1 = ek + m – 1 (um valor negativo) • Para facilitar o algoritmo, considere o primeiro pixel com erro = -0.5 e a decisão passa a ser (ek+1 > 0) • Chamemos de ek, o erro do último pixel desenhado (xk, yk).
void BresLine1(int x1, int y1, int x2, int y2, int color) { int DDx, Dx = x2 - x1; int DDy, Dy = y2 - y1; DDx = Dx<<1; DDy = Dy<<1; int ei = -Dx; int x,y; PutPixel(x1, y1, color); for (x=x1+1; x<=x2; x++) { e+=DDy; if (e>=0) { y++; e-=DDx; } PutPixel(x, y, color); } } ei = 2*Dx*e Para transformar todas as operações em inteiros: multiplicar por (2*Dx) Bresenham’s Line Drawing Algorithm void BresLine0(int x1, int y1, int x2, int y2, int color) { int Dx = x2 - x1; int Dy = y2 - y1; float m = (float)Dy/Dx; float e= -0.5; int x,y; PutPixel(x1, y1, color); for (x=x1+1; x<=x2; x++) { e+=m; if (e>=0) { y++; e-=1; } PutPixel(x, y, color); } }
y 1 2 2 y 1 x orientação x outros quadrantes Rasterização de Retas-caso geral-
Estilos de linha void BresLine2(int x1, int y1, int x2, int y2, int color) { int DDx, Dx = x2 - x1; int DDy, Dy = y2 - y1; DDx = Dx<<1; DDy = Dy<<1; int ei = -Dx; int x,y; int style[8]={1,1,0,0,1,1,0,0}; int k=1; PutPixel(x1, y1, color); for (x=x1+1; x<=x2; x++) { e+=DDy; if (e>=0) { y++; e-=DDx; } if (style[(++k)%8]) PutPixel(x, y, color); } }
Universo Físico Universo Matemático Universo de Representação Universo de Implementação Paradigma dos 4 Universos da Linha Uma linha consiste em points • (x1,x2) (y1,y2) • y = mx + b • Equação implícita • Equação paramétrica Existem diversas maneiras de se definir matematicamente uma linha! A representação é feita com o uso de alguma definição matemática. Mas a discretização mais relevante ocorre mesmo no momento do raster. • Variáveis para as definições matemáticas • Algoritmos de rasterização • int x1, x2, y1, y2; • Bresenham
Amostragem, Aliasing, e Anti-aliasing • A linha, que no universo físico é contínua, é amostrada em uma matriz finita 2D de pixels. • Tal discretização pode causar distorções visuais como cisalhamento ou efeito de escada. • Essas distorções são chamadas de aliasing. • Para reduzir o problema de aliasing, usa-se uma técnica chamada anti-aliasing. • A técnica consiste em uma superamostragem (uma vez que o aliasing é causada por uma subamostragem)
1 3 3 3 2 3 SUPERAMOSTRAGEM • Superamostragem = Amostrar um objeto numa resolução maior do que será reconstruído. dividir os pixels em sub-pixels (i.e. 9), aplicar o algoritmo de Bresenham nesses sub-pixels contar o número de sub-pixels “acesos” por pixel O pixel será aceso com intensidade proporcional ao número de sub-pixels acesos.
Exemplo de Anti-aliasing em Linhas • Observe que quando a cor de fundo não é preto, o anti-aliasing deve fazer uma composição da intensidade com a cor de fundo. • Anti-aliasing é necessário não só para linhas, mas também para polígonos e texturas (o que já é mais complicado)
Usada no “algoritmo do ponto médio” de raster de linha: NE yp+1/2 M yp E xp xp+1 xp+2 Eqaução Implícita da Reta y y2 y1 x x1 x2 (três variáveis apenas: a, b e c)
r v P P1 P0 Equação Paramétrica da Reta Para toda a reta: γ(t) = P + tv, tR Para um segmento de reta: P(t) = P0 + (P1 – P0)t, t[0,1] onde: t=0 em P0 e t=1 em P1