Desenho de Primitvas Prof. Leandro Tonietto ! Baseada na apresentação do Prof. João Ricardo Bittencourt ! Atualizada em: 08/05/2013 [email protected] Processamento Gráfico - UNISINOS 1 Sumário ! ! ! ! ! Base: ponto e linha Algoritmo genérico de linha Bresenhan Retângulo Elipse e formas curvas Polígono qualquer 2 Introdução ! ! ! Para desenho de primitivas podemos utilizar comandos das bibliotecas e linguagens, que desenham as primitivas na tela Podemos também representar as primitivas no SRU definido no OpenGL, utilizando as primitivas de desenho (GL_POINTS, GL_LINES, GL_TRIANGLES, GL_QUADS, GL_POLYGON, ...) e passando véritices (glVertex2f) Ou podemos desenhar manualmente na tela ou numa imagem que representa a viewport. " Neste, o qual estamos interessados nesta aula, vamos preencher pontos de uma imagem, ou melhor, definir pixels que deve ser preenchidos com alguma cor. 3 Desenho de um ponto A primitiva mais simples para desenho é o x ponto. ! Requer apenas uma posição y p1 no espaço: x e y, portanto, o vértice/ponto p1. ! Seguindo a ideia de desenho de primitivas em imagem, temos o comando setPixel ou o comando putPixel para definir a cor de um determinado pixel, representado pelo ponto p1. Assim: ! putPixel(int x, int y, int cor){ pixels[x + y*width] = cor; } 4 Desenho de uma linha A linha também é um primitiva simples, x1 x2 que é definida por dois pontos: p1 e p2. y1, y2 p2 p1 A linha pode ser desenhada de maneira trivial se estiver p1 alinhada a um dos eixos: ! ! p2 drawLine(int x1,int y1,int x2,int y2, int cor){ if(x1 == x2){ for(int i=y1; i<y2; i++) putPixel(x1, i); } else if(y1 == y2){ for(int i=x1; i<x2; i++) putPixel(i, y1); } else { bresenham(x1, y1, x2, y2); } Quando os pontos não estão alinhados é necessário um } algoritmo mais complexo. O mais famoso é o Bresenham. 5 Desenho de uma linha - Bresenham Proposto por Jack Bresenham em 1962. ! Algoritmo clássico para desenhar uma linha em um espaço 2D. ! " Reta contínua em eixos discretos Um dos primeiros algoritmos propostos na Computação Gráfica ! Parte da ideia de desenhar um ponto, incrementando em ambas as coordenadas e corrigindo o erro de incremento. ! 6 Desenho de uma linha - Bresenham ! Algoritmo: bresenham(Ponto p1, Ponto p2){ int dx = abs(p2.x-p1.x) int dy = abs(p2.y-p1.y) float erro = 0 float d = dy/dx int y = p1.y para cada x de p1.x ate p2.x faça pinta o ponto(x,y) erro = erro + d se erro >= 0.5 entao y = y+1 erro = erro - 1.0 } 7 Desenho de uma linha - Bresenham ! Alguns pontos a serem considerados: " O algoritmo não é legal para linhas alinhadas aos eixos, nestes casos é melhor utilizar o for simples. Assim como posto no slide 5. " Este algoritmo possui quatro variantes, dependendo da “ordem” dos pontos e do sentido da linha (são quatro direções possíveis) • Neste sentido, é possível diminuir para dois casos invertendo a ordem dos pontos, se for o caso. " O algoritmo de desenho de linhas pode ser utilizado para desenho do contorno de qualquer outra primitiva geométrica que pode ser reduzida a um polígono. 8 Desenho de Retângulo ! ! O desenho de retângulo requer apenas dois pontos: o ponto mínimo e o ponto máximo. Dois for’s são suficientes para desenhar um retângulo alinhado aos eixos. " Se o retângulo estiver rotacionado, então utilizar algoritmo de desenho de polígono qualquer. " Algoritmo de retângulo alinhamento aos eixos: drawRect(int x1, int y1, int x2, int y2, cor){ for(int y=y1; y<y2; y++){ putPixel(x1, y, cor); putPixel(x2, y, cor); } desenha linhas verticais for(int x=x1; x<x2; x++){ putPixel(x, y1, cor); putPixel(x, y2, cor); } } desenha linhas horizontais 9 Desenho de Polígono Qualquer ! ! 2 Um polígono é formado por vários 1 segmentos de reta, também chamados de arestas. Para desenhar um polígono basta 0 desenhar (algoritmo drawLine) para cada dois vértices do polígonos " Algoritmo: 6 5 drawPolygon(Point *pol, int n, int cor){ for(int i=0; i<n-1; i++){ drawLine(pol[i].x, pol[i].y, pol[i+1].x, pol[i+1].y, cor); } // é necessário ligar o último vértice // com o primeiro drawLine(pol[n-1].x, pol[n-1].y, pol[0].x, pol[0].y, cor); } 10 3 4 Desenho de Elipse ! 4 Elipse pode ser pode ser desenhada como um polígono qualquer, porém os pontos não são informados pelo usuários, eles são calculados com base nos raios (a e b) e o centro/posição da elipse. 3 5 1 6 0 7 " Algortimo: #define PI 3.1415926535898 8 9 drawEllipse(int n, int cx, int cy, int rx, int ry, int cor){ float inc = 1/n; int j=0; Point *pol = new Point[n]; for (float i = 0; i < 1; i += inc) { angle = 2*PI*i; pol[j].x = cos(angle)*raioX+cx; pol[j].y = sin(angle)*raioY+cy; j++; } drawPolygon(pol, n, cor); } 11 2 10