Baixe o app para aproveitar ainda mais
Prévia do material em texto
Computação Gráfica I aula 05 Pontos, Linhas, Polígonos e Redimensionamento Computação Gráfica I2 As primitivas de desenho no OpenGL devem estar sempre entre os comandos glBegin() e glEnd(). Entre esses comandos podemos passar para o OpenGL um conjunto de vértices. O parâmetro do comando glBegin() define como o OpenGL irá interpretar esses vértices. glBegin(<parametro>); // conjunto de vértices glEnd(); OpenGL - Pontos Computação Gráfica I3 A primitiva mais simples é o desenho de um ponto. Para tal, basta passar a constante GL_POINTS no comando glBegin() Se quisermos alterar as cores dos pontos, basta usar o comando glColor3f() passando os componentes RGB da cor desejada. glBegin(GL_POINTS); glColor3f(0.0f, 0.0f, 0.0f); glVertex2i(5, 5); glvertex2i(-5, 5); glColor3f(1.0f, 0.0f, 0.0f); glVertex2i(-5, -5); glVertex2i(5, -5); glEnd(); OpenGL - Pontos GL_POINTS indica que os vértices fornecidos devem ser tratados como pontos isolados. Define a cor preta como cor de desenho Desenha dois pontos em preto Define a cor vermelha como cor de desenho Desenha os outros dois pontos em vermelho Computação Gráfica I4 Exercício 2: crie um programa para plotar os pontos (5,5), (-5,5), (-5,- 5), (5,-5) e (0,0) no plano cartesiano, tomando como base o segundo programa dado como exemplo. OpenGL – Exercício 2 Computação Gráfica I5 #include <gl/glut.h> // Função callback chamada para fazer o desenho propriamente dito void desenha(void) { //Limpa o buffer com a cor de fundo especificada glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_POINTS); glColor3f(0.0f, 0.0f, 0.0f); glVertex2i(5, 5); glvertex2i(-5, 5); glColor3f(1.0f, 0.0f, 0.0f); glVertex2i(-5, -5); glVertex2i(5, -5); glEnd(); //Executa os comandos OpenGL glFlush(); } Importante: as funções inicializa() e main() devem ficar iguais à mostradas anteriormente. OpenGL – Exercício 2 Computação Gráfica I6 // Inicializa parâmetros de rendering void inicializa (void) { // Define a cor de fundo da janela de visualização (RGB) glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Define o tamanho do plano cartesiano em 20x20 glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-10, 10, -10, 10); } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(400, 200); glutInitWindowPosition(50,50); glutCreateWindow("Primeiro programa"); glutDisplayFunc(desenha); inicializa(); glutMainLoop(); } OpenGL – Exercício 2 Computação Gráfica I7 Observe que, apesar de plotarmos os vértices de um quadrado, obtivemos os vértices de um retângulo. Isso acontece quando combinamos viewports e planos cartesianos cujas razões entre largura e altura são diferentes. OpenGL – Exercício 2 Computação Gráfica I8 Para resolver o problema da distorção temos duas soluções: 1. Determinamos a largura e altura do plano para que estes fiquem proporcionais à largura e altura da viewport. Exemplo: OpenGL – Coordenadas 400 200 -20 20 -10 10 Computação Gráfica I9 2. Determinamos a largura e altura do plano para que estes com o mesmo tamanho da viewport. Exemplo: OpenGL – Coordenadas 400 200 -200 200 -100 100 Computação Gráfica I10 Calculando o tamanho do plano cartesiano de acordo com a solução 1: int vp[4]; int largura, altura; // Recupera o tamanho da viewport glGetIntegerv(GL_VIEWPORT, vp); largura = vp[2]; altura = vp[3]; if (largura <= altura) gluOrtho2D(xmin, xmax, float(ymin * altura) / largura, float(ymax * altura) / largura); else gluOrtho2D(float(xmin * largura) / altura, float(xmax * largura) / altura, ymin, ymax); OpenGL – Coordenadas Se a largura é menor que a altura então o eixo y tem que ser maior para compensar a altura maior Se a altura é menor que a largura então o eixo x tem que ser maior para compensar a largura maior Recupera o tamanho da viewport para usar esses valores no cálculo do plano cartesiano Computação Gráfica I11 Por exemplo, se desejamos que o tamanho mínimo seja (-10, 10) nos dois eixos, ajustamos da seguinte forma: if (largura <= altura) gluOrtho2D(-10, 10, float(-10 * altura) / largura, float(10 * altura) / largura); else gluOrtho2D(float(-10 * largura) / altura, float(10 * largura) / altura, -10, 10); Com o uso dessas fórmulas é possível manter a razão entre o eixos x e y e a largura/altura da janela. OpenGL – Coordenadas Computação Gráfica I12 Por exemplo: se a janela tem largura = 400 e altura = 200, então... if (largura <= altura) gluOrtho2D(-10, 10, float(-10 * altura) / largura, float(10 * altura) / largura); else gluOrtho2D(float(-10 * largura) / altura, float(10 * largura) / altura, -10, 10); OpenGL – Coordenadas gluOrtho2D(-20, 20, -10, 10); Computação Gráfica I13 Calculando o tamanho do plano cartesiano de acordo com a solução 2: int vp[4]; int largura, altura; // Recupera o tamanho da viewport glGetIntegerv(GL_VIEWPORT, vp); largura = vp[2]; altura = vp[3]; gluOrtho2D(-largura/2, largura/2, -altura/2, altura/2); OpenGL – Coordenadas Recupera o tamanho da viewport para usar esses valores no cálculo do plano cartesiano Calcula o plano cartesiano de forma que cada pixel da viewport é um ponto no plano cartesiano Computação Gráfica I14 Por exemplo: se a janela tem largura = 400 e altura = 200, então... gluOrtho2D(-largura/2, largura/2, -altura/2, altura/2); OpenGL – Coordenadas gluOrtho2D(-200, 200, -100, 100); Computação Gráfica I15 Exercício 3: implemente a solução 1 do cálculo do plano cartesiano no código do exercício 2 e veja o resultado. OpenGL – Exercício 3 Computação Gráfica I16 Exercício 3: implemente a solução 1 do cálculo do plano cartesiano no código do exercício 2 e veja o resultado. // Inicializa parâmetros de renderizacao void inicializa(void) { int vp[4]; int largura, altura; // Define a cor de fundo da janela de visualização (RGB) glClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Define o tamanho do plano cartesiano em 10x10 glMatrixMode(GL_PROJECTION); glLoadIdentity(); // Recupera o tamanho da viewport glGetIntegerv(GL_VIEWPORT, vp); largura = vp[2]; altura = vp[3]; if (largura <= altura) gluOrtho2D(xmin, xmax, float(ymin * altura) / largura, float(ymax * altura) / largura); else gluOrtho2D(float(xmin * largura) / altura, float(xmax * largura) / altura, ymin, ymax); } OpenGL – Exercício 3 Computação Gráfica I17 Exercício 3: implemente a solução 1 do cálculo do plano cartesiano no código do exercício 2 e veja o resultado. Mas ainda temos um problema quando o usuário redimensiona a janela. OpenGL – Exercício 3 Computação Gráfica I18 Para tratar o redimensionamento da janela, precisamos informar ao OpenGL qual função ficará encarregada de tratar esse evento: glutReshapeFunc(redimensiona); Assim, toda vez que o usuário redimensionar a janela, o OpenGL vai automaticamente acionar a nossa função. A função de redimensionamento recebe como parâmetro o novo tamanho da janela (largura e altura). // Função callback chamada pelo OpenGL quando a janela // e redimensionada void redimensiona(int largura, int altura) { // codigo executado quando a janela e redimensionada } OpenGL – Redimensionamento Computação Gráfica I19 Exemplo: // Função callback chamada pelo OpenGL quando a janela e redimensionada void redimensiona(int largura, int altura) { printf(“largura = %d altura = %d\n”, altura, largura);} int main(void) { glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(400,200); glutInitWindowPosition(10,10); glutCreateWindow("Exercicio 4"); glutDisplayFunc(desenha); glutReshapeFunc(redimensiona); inicializa(); glutMainLoop(); } OpenGL – Redimensionamento Computação Gráfica I20 Como a função de redimensionamento é chamada sempre que a janela muda de tamanho, podemos essa função para alterar o tamanho da viewport. Como o tamanho da viewport será alterado, podemos usar essa função para definir o novo tamanho do plano cartesiano. Dessa forma teremos a viewport sempre consistente com o tamanho da janela e o tamanho do plano cartesiano sempre consistente com o tamanho da viewport. OpenGL – Redimensionamento Computação Gráfica I21 Exercício 4: altere o programa do exercício 3 para tratar corretamente o redimensionamento da janela. Exercício 5: porte para o OpenGL a rotina de renderização de segmentos de reta (bresenham) com tamanho do plano cartesiano de 100x100 nos eixos x e y. Use como base o programa do exercício 4. Desenhe os eixos x e y do plano cartesiano e um segmento de reta em cada octante. Exercício 6: altere o programa do exercício 5 para que o plano cartesiano tenha as mesmas dimensões da janela, ou seja, se a janela tem 400x300, então o plano cartesiano tem (-200,200) no eixo x e (-150, 150) no eixo y. OpenGL – Exercícios Computação Gráfica I22 // Função callback chamada pelo OpenGL quando a janela e redimensionada void redimensiona(int largura, int altura) { // Define o tamanho da viewport como sendo o tamanho da janela glViewport(0,0,largura,altura); // Define o plano cartesiano de acordo com o tamanho da janela glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (largura <= altura) gluOrtho2D (-50, 50, float(-50 * altura) / largura, float(50 * altura) / largura); else gluOrtho2D (float(-50 * largura) / altura, float(50 * largura) / altura, -50, 50); } OpenGL – Exercício 4 Computação Gráfica I23 Vimos anteriormente que para desenharmos pontos precisamos avisar ao OpenGL que os vértices fornecidos devem ser tratados como pontos isolados. Isso é feito através da constante GL_PONTS que é passada para a funçao glBegin(). glBegin(GL_POINTS); glVertex2i(5, 5); glvertex2i(-5,5); glVertex2i(-5, -5); glVertex2i(5, -5); glEnd(); Para alterarmos a interpretação que o OpenGL faz dos vértices fornecidos, basta mudar o valor da constante fornecida para a função glBegin(). OpenGL - Linhas GL_POINTS indica que os vértices fornecidos devem ser tratados como pontos isolados. Computação Gráfica I24 glBegin(GL_LINES): renderiza um segmento de reta ligando cada dois vértices fornecidos da seguinte forma: (v1, v2), (v3, v4), (v5, v6) e assim por diante. glBegin(GL_LINES); // Usa a cor vermelho para o primeiro segmento glColor3f(1.0f, 0.0f, 0.0f); glVertex2i(5, 5); glvertex2i(-5,5); // Usa a cor azul para o segundo segmento glColor3f(0.0f, 0.0f, 1.0f); glVertex2i(-5, -5); glVertex2i(5, -5); glEnd(); OpenGL - Linhas Nesse exemplo vão ser renderizados dois segmentos de reta ligando: (5,5)-(-5,5) e (-5,-5)-(5,-5) Computação Gráfica I25 glBegin(GL_LINE_STRIP): renderiza um segmento de reta ligando cada dois vértices fornecidos da seguinte forma: (v1, v2), (v2, v3), (v3, v4) e assim por diante. glBegin(GL_LINE_STRIP); // Usa a cor vermelho para o primeiro segmento glColor3f(1.0f, 0.0f, 0.0f); glVertex2i(5, 5); glvertex2i(-5,5); // Usa a cor azul para o terceiro segmento glColor3f(0.0f, 0.0f, 1.0f); glVertex2i(-5, -5); glVertex2i(5, -5); glEnd(); OpenGL - Linhas Nesse exemplo vão ser renderizados três segmentos de reta ligando: (5,5)-(-5,5) vermelho (-5,5)-(-5,-5) variando do vermelho até o azul (-5,-5)-(5,-5) azul Computação Gráfica I26 glBegin(GL_LINE_LOOP): igual ao GL_LINE_STRIP, só que liga o último ponto ao primeiro. É usado para renderizar polígonos sem preenchimento. glBegin(GL_LINE_LOOP); // Usa a cor vermelho para o primeiro segmento glColor3f(1.0f, 0.0f, 0.0f); glVertex2i(5, 5); glvertex2i(-5,5); // Usa a cor azul para o terceiro segmento glColor3f(0.0f, 0.0f, 1.0f); glVertex2i(-5, -5); glVertex2i(5, -5); glEnd(); OpenGL - Linhas Nesse exemplo vão ser renderizados quatro segmentos de reta ligando: (5,5)-(-5,5) vermelho (-5,5)-(-5,-5) variando do vermelho até o azul (-5,-5)-(5,-5) azul (5,-5)-(5,5) variando do azul até o vermelho Computação Gráfica I27 Para alterar a espessura da linha utilizamos a função glLineWidth antes do glBegin: glLineWidth(5); glBegin(GL_LINE_LOOP); // Usa a cor vermelho para o primeiro segmento glColor3f(1.0f, 0.0f, 0.0f); glVertex2i(5, 5); glvertex2i(-5,5); // Usa a cor azul para o terceiro // segmento glColor3f(0.0f, 0.0f, 1.0f); glVertex2i(-5, -5); glVertex2i(5, -5); glEnd(); OpenGL - Linhas Computação Gráfica I28 glBegin(GL_POLYGON): igual ao GL_LINE_LOOP, só que preenche o poligono usando os valores definidos para os segmentos de reta. glBegin(GL_POLYGON); // Usa a cor vermelho para o primeiro segmento glColor3f(1.0f, 0.0f, 0.0f); glVertex2i(5, 5); glvertex2i(-5,5); // Usa a cor azul para o terceiro segmento glColor3f(0.0f, 0.0f, 1.0f); glVertex2i(-5, -5); glVertex2i(5, -5); glEnd(); OpenGL - Polígonos Nesse exemplo vão ser renderizados os mesmos segmentos do exemplo anterior, porém preenchendo o polígono com as cores definidas para os segmentos de reta. Computação Gráfica I29 Outro exemplo de glBegin(GL_POLYGON): glBegin(GL_POLYGON); glColor3f(1.0f, 0.0f, 0.0f); // Vermelho glVertex2i(5, 5); glColor3f(0.0f, 1.0f, 0.0f); // Verde glVertex2i(-5,5); glColor3f(0.0f, 0.0f, 1.0f); // Azul glVertex2i(-5, -5); glColor3f(1.0f, 1.0f, 0.0f); // Amarelo glVertex2i(5, -5); glEnd(); OpenGL - Polígonos Computação Gráfica I30 glBegin(GL_TRIANGLES): desenha um triângulo preenchido a cada três vértices fornecidos da seguinte forma: (v1, v2, v3), (v4, v5, v6) e assim por diante. glBegin(GL_TRIANGLES); glColor3f(1.0f, 0.0f, 0.0f); glVertex2i(5, 5); glVertex2i(-5,5); glVertex2i(-5, -5); glColor3f(0.0f, 0.0f, 1.0f); glVertex2i(10, 0); glVertex2i(0, 0); glVertex2i(0, -10); glEnd(); OpenGL - Triângulos Nesse exemplo vão ser renderizados dois triângulos, sendo o primeiro vermelho e o segundo azul. Computação Gráfica I31 Outro exemplo de glBegin(GL_TRIANGLES): glBegin(GL_TRIANGLES); glColor3f(1.0f, 0.0f, 0.0f); glVertex2i(5, 5); glColor3f(0.0f, 1.0f, 0.0f); glVertex2i(-5,5); glColor3f(0.0f, 0.0f, 1.0f); glVertex2i(-5, -5); glColor3f(0.0f, 0.0f, 1.0f); glVertex2i(10, 0); glColor3f(0.0f, 1.0f, 0.0f); glVertex2i(0, 0); glColor3f(1.0f, 0.0f, 0.0f); glVertex2i(0, -10); glEnd(); OpenGL - Triângulos Computação Gráfica I32 glBegin(GL_TRIANGLE_STRIP): desenha um triângulo preenchido a cada três vértices fornecidos da seguinte forma: (v1, v2, v3), (v2, v3, v4), (v3, v4, v5) e assim por diante. glBegin(GL_TRIANGLE_STRIP); glColor3f(1.0f, 0.0f, 0.0f); glVertex2i(5, 5); glVertex2i(-5,5); glVertex2i(-5, -5); glVertex2i(10, 0); glVertex2i(0, 0); glVertex2i(0, -10); glEnd(); OpenGL - Triângulos Nesse exemplo vão ser renderizados quatro triângulos. Computação Gráfica I33 glBegin(GL_TRIANGLE_FAN): desenha um triângulo preenchido a usando o primeiro vértice como ponto de referência da seguinte forma: (v1, v2, v3), (v1, v3, v4), (v1, v4, v5) e assim por diante. glBegin(GL_TRIANGLE_FAN); glColor3f(1.0f, 0.0f, 0.0f); glVertex2i(5, 5); glVertex2i(-5,5);glVertex2i(-5, -5); glVertex2i(10, 0); glVertex2i(0, 0); glVertex2i(0, -10); glEnd(); OpenGL - Triângulos Nesse exemplo vão ser renderizados quatro triângulos. Computação Gráfica I34 glBegin(GL_QUADS): desenha um quadrilátero preenchido usando quatro vértices da seguinte forma: (v1, v2, v3, v4), (v5, v6, v7, v8), (v9, v10, v11, v12) e assim por diante. glBegin(GL_QUADS); glColor3f(1.0f, 0.0f, 0.0f); glVertex2i(5,5); glVertex2i(-5,5); glVertex2i(-5,-5); glVertex2i(5,-5); glColor3f(0.0f, 1.0f, 0.0f); glVertex2i(10,-5); glVertex2i(5, -5); glVertex2i(5,-10); glVertex2i(10, -10); glEnd(); OpenGL - Quadrados Nesse exemplo vão ser renderizados dois quadriláteros: um vermelho e outro verde Computação Gráfica I35 glBegin(GL_QUAD_STRIP): desenha um quadrilátero preenchido usando quatro vértices da seguinte forma: (v1, v2, v3, v4), (v3, v4, v5, v6), (v5, v6, v7, v8) e assim por diante. glBegin(GL_QUAD_STRIP); glColor3f(1.0f, 0.0f, 0.0f); glVertex2i(5,5); glVertex2i(0,5); glVertex2i(5,0); glVertex2i(0,0); glColor3f(0.0f, 1.0f, 0.0f); glVertex2i(0,-5); glVertex2i(-5, -5); glColor3f(0.0f, 0.0f, 1.0f); glVertex2i(0,-10); glVertex2i(-5, -10); glEnd(); OpenGL - Quadrados Computação Gráfica I36 Linhas poligonais • São figuras construídas através da composição de segmentos de linhas retas deforma consecutiva. • Estes segmentos de retas (arestas ou lados) ligam diversos pontos denominados vértices. • Estas figuras podem ser abertas ou fechadas, quando os vértices inicial e final são coincidentes. Processo de Construção de Linhas Poligonais • O baseia-se na definição da posição dos vértices em função de pontos assinalados na superfície de desenho de forma sequencial. Estes vértices podem ser definidos através de eventos de mouse (mouseDown e mouseUp). • A definição de término de uma linha poligonal, é necessário definir um evento que pode ser uma quantidade pré-definida de vértices ou um evento de duplo-clique para o fechamento da figura. Introdução Polígonos Computação Gráfica I37 Polígonos • São figuras fechadas construídas através da composição de linhas retas. Classificação dos polígonos quanto aos lados: • Polígonos regulares (lados de igual comprimento) • Polígonos irregulares (lados de comprimentos diferentes) Classificação dos polígonos quanto aos ângulos: • Polígonos convexos (todos os ângulos internos menores do que 180º). • Polígonos côncavos (pelo menos um ângulo interno maior do que 180º). Processo de Construção de Polígonos • O baseia-se na definição prévia da posição dos vértices da figura em função de pontos sequenciais assinalados na superfície de desenho. • A forma mais simples é determinar os vértices a partir de apenas dois pontos podem ser definidos através dos eventos mouseDown e mouseUp. Introdução Polígonos Computação Gráfica I38 Triângulos • O triângulo é o polígono com três lados (menor número de lados). • Soma dos ângulos internos é 180º. Classificação dos triângulos quanto aos lados: • Triângulo isósceles – possui dois lados iguais • Triângulo equilátero – possui três lados iguais • Triângulo escaleno – possui três lados diferentes Equilátero Isósceles Escaleno Escaleno Triângulos Computação Gráfica I39 Classificação dos triângulos quanto aos ângulos: • Triângulo retângulo – possui um ângulo reto (igual a 90º) • Triângulo acutângulo – todos ângulos são agudos (menores do que 90º) • Triângulo obtusângulo – possui um ângulo obtuso (maior do que 90º) Equilátero Acutângulo Isósceles Acutângulo Escaleno Retângulo Escaleno Obtusângulo Triângulos Computação Gráfica I40 Construindo um Triângulo Isósceles • Um triângulo isósceles é uma figura que pode ser inscrita em um retângulo: d / 2 d Triângulos Computação Gráfica I41 Construindo um Triângulo Isósceles Ferramenta para desenho de triângulos isósceles (caixa de ferramentas): • Evento mouseDown : considerar o primeiro ponto assinalado no formulário de desenho como o canto inferior esquerdo (X1, Y1) do retângulo que envolve o triângulo • Evento mouseUp : após arrasto na superfície, o segundo ponto como o canto superior direito (X2, Y2): B A C X1 Y2 X2 Y1 Evento mouseUp Evento mouseDow n Triângulos Computação Gráfica I42 Construindo um Triângulo Isósceles • Após o evento mouseUp já se possui as coordenadas dos pontos A e C A = (X1, Y1) C = (X2, Y1) • Também pode-se calcular a coordenada do ponto B = (XB, YB), já que possui YB = Y2 e a coordenada XB está no meio entre X1 e X2: XB = (X1 + (X2 – X1) / 2) = (X1+X2)/2 • Com esse ponto determinado, faz-se a ligação dos três pontos A, B e C com os segmentos de retas AB, BC, e AC: B A C X1 Y2 X2 Y1 Evento mouseUp Evento mouseDown Triângulos Computação Gráfica I43 • Para a Versão Visual Basic Private Sub triangulo_isosceles (X1 As Single, Y1 As Single, X2 As Single, Y2 As Single) XA = X1 YA = Y1 XB = X1 + (X2 - X1) / 2 YB = Y2 XC = X2 YC = Y1 Picture1.Line (XA, YA)-(XB, YB), glbLcolor Picture1.Line (XB, YB)-(XC, YC), glbLcolor Picture1.Line (XC, YC)-(XA, YA), glbLcolor End Sub B A C X1 Y2 X2 Y1 Evento mouseUp Evento mouseDown Triângulos Computação Gráfica I44 • Para a Versão C - // Função que desenha um triângulo isósceles vazado void Triangulo_Isosceles (int x1, int y1, int x2, int y2) { int xa, ya, xb, yb, xc, yc; xa = x1; ya = y1; xb = x1 + (x2 – x1) / 2; yb = y2; xc = x2; yc = y1; DDA (xa, ya, xb, yb); DDA (xb, yb, xc, yc); DDA (xc, yc, xa, ya); } B A C X1 Y2 X2 Y1 Evento mouseUp Evento mouseDow n Triângulos Computação Gráfica I45 • Para a Versão C – Open GL // Função que desenha um triângulo isósceles vazado void Triangulo_Isosceles (int x1, int y1, int x2, int y2) { float xa = x1; float ya = y1; float xb = x1 + (x2 – x1) / 2; float yb = y2; float xc = x2; float yc = y1; glBegin(GL_LINE_LOOP); glVertex2f (xa, ya); glVertex2f (xb, yb); glVertex2f (xc, yc); glEnd(); } B A C X1 Y2 X2 Y1 Evento mouseUp Evento mouseDow n Triângulos Computação Gráfica I46 Quadriláteros • São os polígonos com quatro lados. • Soma dos ângulos internos é 360. Classificação dos Quadriláteros quanto aos lados: • Paralelogramo – possui lados paralelos 2 a 2 • Trapézio – possui apenas 2 lados paralelos • Trapezóide - não possui lados paralelos Paralelogramo Paralelogramo Trapézio Trapezóide Quadriláteros Computação Gráfica I47 Casos especiais do paralelogramo • Losango – paralelogramo com lados iguais • Retângulo - paralelogramo com ângulos retos (90º) • Quadrado - paralelogramo com os lados iguais e ângulos retos (90º) Losango Losango Retângulo Quadrado Quadriláteros Computação Gráfica I48 Casos especiais do trapézio • Trapézio isósceles: trapézio com 2 lados iguais e ângulos iguais 2 a 2. • Trapézio retângulo: trapézio com 2 ângulos retos. • Trapézio escaleno: trapézio com todos os lados e ângulos diferentes. Trapézio isósceles Trapézio escaleno Trapézio retângulo Quadriláteros Computação Gráfica I49 • O retângulo é um polígono com quatro lados em ângulo reto. • De maneira similar ao triângulo, pode-se usar os eventos mouseDown e mouseUp para definir a posição na tela de dois vértices opostos do retângulo, por exemplo: canto superior esquerdo e canto inferior direito. • Entretanto, este posicionamento não determina o retângulo. • Conforme pode ser verificado, qualquerponto pertencente ao arco capaz de 90º poderá servir de vértice, o que significa que vários retângulos possuem a mesma diagonal. Canto Inferior Esquerdo Canto Superior Direito Evento mouseUp Evento mouseDown Arco capaz de 90º Quadriláteros Computação Gráfica I50 Retângulos Solução: Definir um critério adicional: os lados devem ser paralelos (ou ortogonais) aos lados da janela. Método para Desenho de Retângulos Vazados • Para desenho de retângulos vazados (sem preenchimento), o VB disponibiliza o seguinte método: LINE (x1, y1) - (x2, y2), color, B onde: (x1, y1) - (x2, y2) = posições dos cantos opostos do retângulo color = cor da linha de contorno do retângulo B = informa que é para desenhar retângulo (Box) e não linha x1 x2 y2 y1 Quadriláteros Computação Gráfica I51 • Para a Versão C // Função que desenha um retângulo vazado void Retangulo_Vazado (int x1, int y1, int x2, int y2) { glBegin(GL_LINE_LOOP); glVertex2i (x1, y1); glVertex2i (x1, y2); glVertex2i (x2, y2); glVertex2i (x2, y1); glEnd(); } x1 x2 y2 y1 Quadriláteros Computação Gráfica I52 Método para Desenho de Retângulos Preenchidos • Para desenho de retângulos preenchidos, o VB disponibiliza o seguinte método: LINE (x1, y1) - (x2, y2), color, BF onde:(x1, y1) - (x2, y2) = posições dos cantos opostos do retângulo color = cor de preenchimento do retângulo B = informa que é para desenhar retângulo (Box) e não linha F = preenche o interior do retângulo (Fill) com a mesma cor usada para os lados x1 x2 y2 y1 Quadriláteros Computação Gráfica I53 • Para a Versão C // Função que desenha um retângulo preenchido void Retangulo_Preenchido (int x1, int y1, int x2, int y2) { // Especifica que a cor corrente é azul // R G B glColor3f(0.0f, 0.0f, 1.0f); // Desenha um quadrado preenchido com a cor corrente glBegin(GL_QUADS); glVertex2i (x1, y1); glVertex2i (x1, y2); glVertex2i (x2, y2); glVertex2i (x2, y1); glEnd(); } x1 x2 y2 y1 Quadriláteros Computação Gráfica I54 • O pentágono é um polígono de cinco lados que também pode ser inscrito em um retângulo. Para adicionar uma nova ferramenta para desenhar pentágonos, deve-se considerar o primeiro ponto (evento mouseDown) no form frmDesenho como o canto superior esquerdo (X1, Y1) do retângulo que envolve o pentágono, e o ponto do evento mouseUp como o canto inferior direito (X2, Y2): • Após o segundo clique pode-se calcular as coordenadas dos pontos dos pontos A, B, C, D e E, considerando que: d / 4 d L / 2 L L / 8 B A C C X1 Y1 X2 Y2 E D DX = (X2 – X1) / 4 DY = (Y2 – Y1) / 8 Ponto A XA = X1 + 2*DX e YA = Y1 Ponto B XB = X2 e YB = Y1 + 3*DY Ponto C XC = X2 - DX e YC = Y2 Ponto D XD = X1 + DX e YD = Y2 Ponto E XE = X1 e YE = Y1 + 3*DY Pentágono Computação Gráfica I55 • Uma estrela de cinco pontas é uma figura que pode ser derivada de um pentágono. • Assim, ela também pode ser inscrita em um retângulo. • Para adicionar uma nova ferramenta para desenhar estrelas, deve-se considerar o primeiro ponto (evento mouseDown) no form frmDesenho como o canto superior esquerdo (X1, Y1) do retângulo que envolve a estrela, e o ponto do evento mouseUp como o canto inferior direito (X2, Y2): Pentágono Estrela A C X1 Y1 X2 Y2 B D F H I J EG Estrelas Computação Gráfica I56 DX = X2 – X1 DY = Y2 – Y1 Ponto A: XA = X1 + DX / 2 e YA = Y1 Ponto B: XB = X1 + 5 * DX / 8 e YB = Y1 + 3 * DY / 8 Ponto C: XC = X2 eYC = YB Ponto D: XD = X1 + 11 * DX / 16 e YD = Y1 + 5 * DY / 8 Ponto E: XE = X1 + 13 * DX / 16 e YE = Y2 Ponto F: XF = XA e YF = Y1 + 6 * DY / 8 Ponto G: XG = X1 + 3 * DX / 16 e YG = Y2 Ponto H: XH = X1 + 5 * DX / 16 e YH = YD Ponto I: XI = X1 e YI = YB Ponto J: XJ = X1 + 3 * DX / 8 e YJ = YB 3L/16 5L/16 3L/8 L/2 5L/8 11L/16 13L/16 3d/8 5d/8 6d/8 L d A C X1 Y1 X2 Y2 B D F H I J EG Estrelas Computação Gráfica I57 • Considere um polígono regular de N lados, inscrito em um círculo de raio R. • Dadas as coordenadas (X1, Y1) do centro do círculo (no evento mouseDown) e um ponto qualquer (X2, Y2) da circunferência (no evento mouseUp), o raio do círculo pode ser calculado por: R = SQR((X2-X1)2 + (Y2-Y1)2) • O lado L pode ser determinado por: R*Sin( / 2) = L/2 X1 X2 Y1 Y2 R X1 Xi Y1 Yi R /2 R sin(/2) R cos(/2) Lado paralelo ao eixo x Polígono Regular Computação Gráfica I58 • O lado L pode ser determinado por: R*Sin( / 2) = L/2 ou seja: L = 2 * R * Sin( / 2) • É fácil ver que nessas condições, o ângulo central ( = 360 / N) é sempre igual ao ângulo externo. L/2 /2 R ângulo central = ângulo externo Polígono Regular Computação Gráfica I59 • Um bom ponto de partida é aquele que apresenta o lado do topo paralelo ao eixo x, neste caso: Xi = X1 + R. sin(/2) Yi = Y1 – R cos(/2) X1 Xi Y1 Yi R /2 R sin(/2) R cos(/2) Lado paralelo ao eixo x Polígono Regular Computação Gráfica I60 Fazendo: 1 = XF = Xi + L cos(1) YF = Yi + L Sin(1) = XFXi Yi X1 R YFY1= L L cos(1) L sin(1) Polígono Regular Computação Gráfica I61 • Para a próxima iteração vale observar que os ângulos sucessivos formam uma PA: 2 4 3 5 Polígono Regular Computação Gráfica I62 • Dessa maneira o próximo ponto será determinado incrementado-se o ângulo de : 2 = (1 + ) • Transfere-se o valor obtido para ser o valor inicial da próxima iteração: Xi2 = XF e Yi2 = YF • E aplica-se novamente o método: XF2 = Xi2 + L cos(2) e YF2 = Yi2 + L Sin(2) = = 3 XFXi Yi X1 R YFY1= L L cos(1) L sin(1) = 2 Polígono Regular Computação Gráfica I63 Private Sub PoliRegular(X1 As Integer, Y1 As Integer, X2 As Integer, Y2 As Integer) Pi = 3.141596 N = glbFiltro alfa = 2 * Pi / N DX = X2 - X1 DY = Y2 - Y1 R = Sqr(DX * DX + DY * DY) L = 2 * R * Sin(alfa / 2) beta = alfa XI = X1 + R * Sin(alfa / 2) YI = Y1 - R * Cos(alfa / 2) For i = 1 To N XF = XI + L * Cos(beta) YF = YI + L * Sin(beta) Picture1.Line (XI, YI)-(XF, YF), glbLcolor XI = XF YI = YF beta = beta + alfa Next i End Sub = = 3 XFXi Yi X1 R YFY1= L L cos(1) L sin(1) = 2 XFn = Xin + L cos(n) YFn = Yin + L Sin(n) Polígono Regular
Compartilhar