Documente Academic
Documente Profesional
Documente Cultură
DEPARTAMENTO DE COMPUTAÇÃO
BACHARELADO EM ENGENHARIA DA COMPUTAÇÃO
NOVEMBRO
2008
UNIVERSIDADE CATÓLICA DE GOIÁS
DEPARTAMENTO DE COMPUTAÇÃO
GRADUAÇÃO EM ENGENHARIA DA COMPUTAÇÃO
ii
UM ESTUDO DE COMPUTAÇÃO GRÁFICA 2D:
MODELAGEM GEOMÉTRICA
_______________________________ _________________________________
Prof. Dr. Marco Antonio F. Menezes, Dr. Prof. Jeová Martins Ribeiro, Esp.
Orientador Coordenador de Projeto Final de Curso
iii
AGRADECIMENTOS
Inicialmente gostaria de agradecer aos meus pais e meu irmão por tornarem possível
a realização deste sonho e estarem sempre ao meu lado.
Ao Prof. Dr. Marco Antonio F. Menezes, pela paciência durante o processo de
orientação e pelo ensino não apenas dos conteúdos, mas sim de valores que eu nunca mais irei
esquecer. Ao Prof. Cristian Patricio Novoa Bastos, pelos esclarecimentos.
Às famílias dos meus tios Mauro e Thales, por aturarem minhas manias e caprichos
durante este trajeto. Vocês foram de fundamental importância. Outra tia importante é a tia
Berenice, que me deu um apoio enorme.
Aos colegas que passaram pelo seminário de otimização, Jordana, Maiana, Luiz
Fernando, Maurício, Eduardo e Allan, que me proporcionaram grandes dias de discussões
técnicas que me ajudaram muito para minha evolução como aluno e pessoa.
À minha namorada Maira Cristina de Souza Gomes que demonstra muito carinho,
amor e afeto.
A todos que de certa forma contribuíram para a realização deste sonho. Muito
obrigado mesmo.
iv
Aos meus familiares.
À minha mãe Mary, pai Marcos e irmão Aymar pelo afeto e suporte.
À minha namorada Maira pelo amor e carinho.
v
“A display connected to a digital computer gives us a
chance to gain familiarity with concepts not realizable
in the physical world. It is a looking glass into a
mathematical wonderland.”
Ivan Sutherland
vi
RESUMO
vii
ABSTRACT
viii
SUMÁRIO
ix
5.1.1. Universo físico ..................................................................................................51
5.1.2. Universo matemático ........................................................................................52
5.1.3. Universo de representação ................................................................................55
5.1.3.1. Representação CSG ..............................................................................55
5.1.3.2. Hierarquias ............................................................................................57
5.1.4. Universo de implementação .............................................................................61
6. CONCLUSÕES .................................................................................................................62
7. BIBLIOGRAFIA ...............................................................................................................63
x
LISTA DE FIGURAS
xi
LISTA DE TABELAS
xii
LISTA DE ABREVIATURAS E SIGLAS
2D Duas Dimensões
3D Três Dimensões
API Application Programming Interface
ARB Architeture Review Board
ASCII American Standard Code for Information Interchange
CSG Constructive Solid Geometry
GLU Graphic Library Utilities
GLUT Graphic Library Utilities Toolbox
OpenGL Open Graphic Library
UCG Universidade Católica de Goiás
VS Visual Studio 2005
xiii
1
CAPÍTULO I
INTRODUÇÃO
A computação gráfica vem se tornando a cada dia uma ferramenta muito importante
em áreas como, por exemplo, a Computação e a Matemática, visto que a necessidade de
aplicações que geram e manipulam objetos gráficos e imagens são cada vez mais exigidas.
Apesar da grande quantidade de material e aplicações existentes no mercado sobre
computação gráfica, ainda existem algumas definições e resultados que não estão
consolidados e abrem espaço para uma interpretação ambígua.
Inicialmente, a motivação para esse trabalho foi a construção de um jogo 2D (duas
dimensões) , onde tínhamos uma idéia através da utilização de métodos de otimização linear.
Todavia, esbarramos na dificuldade teórica e de implementação de algoritmos em computação
gráfica, haja vista a dissonância entre a teoria e a prática na literatura. A partir daí, resolvemos
escrever a modelagem geométrica 2D sobre certas hipóteses, em uma tentativa sucinta e clara
do ponto de vista didático e acadêmico.
O objetivo deste trabalho é escrever a modelagem geométrica 2D com exceção de
superfícies e fractais, do ponto de vista do paradigma dos quatro universos e da utilização de
uma API (Application Programming Interface) gráfica OpenGL (Open Graphic Library) para
a implementação de modelagem de objetos gráficos.
No capítulo 2, apresentamos alguns tópicos em álgebra linear necessários para o
estudo da computação gráfica. Neste capítulo, contamos com a contribuição do Prof. Cristian
Patricio Novoa Bastos.
No capítulo 3, introduzimos a computação gráfica, onde enunciamos as hipóteses
deste trabalho, definimos objetos gráficos e apresentamos o paradigma dos quatro universos.
Neste capítulo contamos com a valorosa correção (da primeira versão) e contribuição do Prof.
Luiz Velho, a contribuição dos matemáticos Genésio Lima dos Reis e Cristian Patricio Novoa
Bastos, e dos físicos Francisco Aparecido Pinto Osório e Celso José Viana Barbosa. É
importante afirmar que este capítulo foi escrito pelo orientador Prof. Marco Antonio F.
Menezes.
No capítulo 4, introduzimos a API gráfica OpenGL para programação de aplicações
gráficas 2D. Aqui, configuramos um ambiente de programação para trabalharmos a OpenGL
com a linguagem de programação C. No capítulo 5, estudamos a modelagem geométrica do
ponto de vista do paradigma dos quatro universos apresentado no capítulo 3, e da utilização
2
CAPÍTULO II
PRELIMINARES EM ÁLGEBRA LINEAR
2.1 Matrizes
a diagonal composta pelos elementos a ij com i = j. Uma matriz diagonal é uma matriz que
possui todos os seus elementos fora da diagonal principal iguais a 0. Uma matriz identidade é
4
uma matriz diagonal, cujos elementos da diagonal principal são iguais a 1. A matriz
identidade será denotada pelo símbolo I.
Considere i = 1,2,..., m e j=1,2,...n e sejam A e B duas matrizes, m x n. A operação
de adição entre as matrizes A e B é dada por:
[ cij ] = [ a ij ] + [ bij ].
[ d ij ] = α [ a ij ].
[ e ji ] = [ aij ].
n
cil = ∑ aik bkl , i = 1,2,..., m e l=1,2,...,q.
k =1
Considere A uma matriz quadrada. Dizemos que A é invertível, quando existir uma
matriz A −1 , denominada matriz inversa de A, tal que
AA −1 = A −1 A = I.
Duas propriedades básicas de matrizes são:
−1
(AB) T = B T A T e (AB) = B −1 A −1 .
Definição 2.1 Um espaço vetorial real V é um conjunto, não vazio, formado por
elementos denominados vetores, no qual estão definidas duas operações: a adição
+: V x V → V
(u,v) a u + v,
i) 0 ∈W ;
ii) se u , v ∈ W , então u + v ∈ W ; e
iii) se v ∈ W , então, para todo α ∈ R , α ⋅ v ∈ W .
6
v = α 1v 1 + α 2 v 2 + ... + α n v n .
α 1 + α 2 + ... + α n = 1 .
Em particular, quando α j ∈ [0,1] , j = 1,2,...,n, dizemos que v é uma combinação
H = {v ∈ V ; u T v = α }
é denominado um hiperplano.
α 1v 1 + α 2 v 2 + ... + α n v n = 0 ⇒ α 1 =α 2 = L = α n = 0 .
7
n
[ v1 ,v 2 ,...,v ].
n
f) Um conjunto { v1 ,v 2 ,...,v } de vetores de V será dito uma base de V, quando:
n
i) { v1 ,v 2 ,...,v } é linearmente independente, e
n
ii) [ v1 ,v 2 ,...,v ] = V.
W1 + W2 = {v = w1 + w2 ∈ V ; w 1 ∈ W1 e w 2 ∈ W2 } .
i) T (u + v ) = T (u ) + T (v ) , para todos u , v ∈ V ;
ii) T (αv ) = αT (v ) , para todo v ∈ V e para todo α ∈ R .
Segue-se desta definição que uma transformação linear é única. Além disso, segue-se
desta definição e do axioma vetor nulo de espaços vetoriais que,
tais que, A1 é uma matriz m x n e A2 é uma matriz p x q, n = q. Pelo teorema 2.2, segue-se
que
(T1 o T2 ) ( x) = T1 (T2 ( x)) = T1 ( A2 x) = A1 ( A2 x) = ( A1 A2 ) x ;
9
(T1 + T2 ) ( x) = T1 ( x) + T2 ( x) = A1 x + A2 x =( A1 + A2 ) x .
T /V :V → V
T ( p + v ) = T ( p ) + T (v) .
n n
T (u j ) = ∑ aij v i e T (o) = ∑ a in +1v i .
i =1 i =1
n n
x = ∑ x j u + o ⇒ T ( x ) =∑ x j T (u j ) + T (o)
j
j =1 j =1
n n
∴ T ( x ) = ∑ (∑ aij x j + a in +1 )v i .
i =1 j =1
Ou seja, as coordenadas de T(x) no referencial G são dadas pelo produto das matrizes
n +1
um ponto q ∈ R na reta r que representa o ponto p. Se q = ( x1 ,..., x n , x n +1 ) , então tomamos
Ocorre que se λ ∈ R é um número não nulo, λ q representa o mesmo ponto projetivo p. Desse
T : RP n → RP n
T : R n +1 → R n +1
A T
M = ,
P S
T : R3 → R3
1 0 0 x
( x, y,1) a T ( x, y,1) = 0 1 0 y .
1 0 1 1
O conjunto S define o quadrado conforme a figura 2.2 (a) do exemplo 2.2. A transformação
projetiva T aplicada aos pontos extremos de S, fornece
p 1 = T (0,0,1) = (0,0,1), p 2 = T (1,0,1) = (1,0,2), p 3 = T (1,1,1) = (1,1,2), p 4 = T (0,1,1) = (0,1,1).
Através da projeção cônica obtemos (figura 2.3 (a)),
λp 2 = λ (1,0,2) = ( x, y,1) ⇒ 2λ = 1 ⇒ λ = 1 2 .
λp 3 = λ (1,1,2) = ( x, y,1) ⇒ 2λ = 1 ⇒ λ = 1 2 .
Daí, obtemos
CAPÍTULO III
UMA INTRODUÇÃO À COMPUTAÇÃO GRÁFICA
3.1 Cores
Em Borges e Rodrigues [5], podemos definir uma onda como sendo uma perturbação
que se propaga, carregando consigo momento, energia e informação. Toda onda possui uma
certa variável física que oscila, sendo esta oscilação transmitida sucessivamente. Ondas
eletromagnéticas são ondas que não necessitam de um meio material para se propagarem,
podendo viajar livremente através do espaço vazio. A mais conhecida onda eletromagnética é
a luz. Os raios X e as microondas também são exemplos de ondas eletromagnéticas. Todas as
ondas eletromagnéticas viajam através do vácuo com a mesma velocidade c,
aproximadamente 3 x 108m/s. Nas ondas eletromagnéticas as variáveis físicas que oscilam são
os campos elétrico e magnético.
Sejam dados uma lâmpada acesa e um objeto com determinado material. Esta
lâmpada pode ser considerada como uma fonte de ondas eletromagnéticas que emite luz
visível; além de calor, isto é, luz ultravioleta e infravermelho. Estas ondas eletromagnéticas
são refletidas e refratadas pelos objetos, os quais absorvem alguns comprimentos de onda e
refletem outros. A cor de um objeto é determinada pelas médias de freqüência dos pacotes de
ondas eletromagnéticas que as suas moléculas constituintes refletem e que são percebidas
16
P E 1 fh hc
L (λ ) = = = =
A ∆t 4πr 2
∆t 4πr 2
λ∆t 4πr 2
17
hc
∴ L (λ ) =
A∆tλ
Segundo Silva [15], sempre que fizermos a correspondência entre cor e comprimento
de onda, devemos tomar o comprimento de onda no vácuo, caso contrário,
L ( f ) = h ⋅ f /( A ⋅ ∆t ) ,
uma vez que quando a luz se propaga em meio material, sua velocidade, v, é menor do que no
vácuo (c).
Em Amabis e Martho [1], os órgãos responsáveis pela visão são os bulbos do olho,
popularmente chamados de olhos. Nos bulbos do olho há células sensoriais especializadas na
captação de estímulos luminosos, os fotoceptores (ou fotorreceptores). Cada bulbo do olho
movimenta-se suavemente dentro de sua órbita, graças a três pares de músculos fixados ao
globo ocular. Esse movimento é limitado pelo nervo óptico, um feixe de fibras nervosas que
parte do interior do bulbo do olho em direção ao encéfalo, passando por uma abertura no osso
da órbita ocular. Os bulbos dos olhos são revestidos por uma membrana transparente, dotada
de finíssimos vasos sanguíneos, a conjuntiva, que se estende pela superfície interna das
pálpebras. Sob a conjuntiva fica a parede do bulbo do olho, formada por três camadas de
tecido: esclera, corióide e retina (veja figura 3.2). Em particular, a camada que reveste a
câmera ocular é a retina, que contém dois tipos de células estimuláveis pela luz (fotoceptores):
os bastonetes e os cones. Os bastonetes são fotoceptores extremamente sensíveis à luz, mas
incapazes de distinguir as cores. Os cones são menos sensíveis à luz que os bastonetes, mas
possuem capacidade de discriminar diferentes comprimentos de onda permitindo a visão em
cores. Há três tipos diferentes de cones no olho humano, cada um contendo um tipo de
pigmento (molécula fotossensível). Estes são proteínas conjugadas, em que a parte não
protéica é o retineno (dehidroretinaldeído) e a parte protéica é uma opsina. Cada classe de
cone possui uma opsina diferente, determinada geneticamente; um tipo detecta luz vermelha
(R - red), outro detecta luz verde (G – green) e o terceiro detecta luz azul (B – blue); é isso
que permite a visão em cores.
18
Figura 3.2 – Olho humano (página 561 em Amabis e Martho [1] - modificado).
Neste ponto, podemos concluir que cor é um fenômeno psicofísico, porque depende
da percepção visual e de fenômenos físicos. Finalmente, podemos tomar a seguinte definição;
onde a luz pode ser pensada como ondas eletromagnéticas e ao mesmo tempo como partículas
(fótons): cor é uma percepção visual provocada pela ação de um feixe de fótons sobre células
especializadas da retina, que permitem através de informação pré-processada na própria
retina, gerar impressões para o sistema nervoso.
Nossa intenção para a próxima seção é a definição de computação gráfica.
3.2 Definições
Pela definição 3.1, podemos utilizar como modelo matemático de imagem uma
função
f :U ⊂ R2 → C ,
19
f : S → Rn.
a) Chamamos objeto gráfico o par (S, f) que consiste de um subconjunto no qual,
para cada elemento de S, associamos pela função f um atributo.
20
Cada um dos atributos do objeto gráfico (cor, textura, campo de vetores, etc.) é
definido por uma função
fj :S → R j,
n
Exemplo 3.3 Circunferência e campo de vetores (Gomes, Costa, Darsa e Velho [8] –
páginas 271 e 272; corrigido). Considere uma circunferência definida por
{ }
S = ( x, y ) ∈ R 2 ; x 2 + y 2 = 1 .
Para representar um campo de vetores na circunferência, no sentido horário, a função atributo
é definida por
21
f = (N ,T ) : S → R 4
(x,y) a f ( x, y ) = ( x, y, y,− x),
tal que a função
N : S → R2
(x,y) a N(x,y) = (x,y)
define um campo de vetores unitários normais a S e a função
T : S → R2
(x,y) a T(x,y) = (y,-x)
define um campo de vetores unitários no sentido horário e tangentes a S. Assim, o par (S, f) é
um objeto gráfico, conforme figura 3.5. O suporte geométrico é a circunferência S.
Exemplo 3.4 A imagem da figura 3.3 é um objeto gráfico, cujo suporte geométrico é
a região U.
Exemplo 3.5 Subconjuntos do espaço (Gomes e Velho [10] – páginas 197 e 198).
Qualquer subconjunto do espaço euclidiano R n é um objeto gráfico. Com efeito, dado
S ⊂ R n , definimos uma função de atributos
1, se p ∈ S
p ∈ S a f ( p) =
0, se p ∉ S .
Em geral, os valores de f(p) = 1 são associados a uma determinada cor, chamada de cor do
objeto. A função de atributos nesse caso simplesmente caracteriza os pontos do conjunto S, e
por essa razão é chamada de função característica do objeto gráfico (S, f). A função
característica define completamente o suporte geométrico S do objeto gráfico, ou seja, se p é
um ponto do espaço R n , então p ∈ S se, e somente se, f(p) = 1.
22
Figura 3.6 - Dados e processos da computação gráfica ( página 1 em Velho e Gomes [16] ).
B( p, ε ) = {v ∈ R n ; v − p < ε }.
f : R2 → B g : R2 → B
x e y
x a f ( x) = y a g ( y) = .
1+ x 1− y
x x
x 1+ x 1+ x
g ( f ( x)) = g =
= = x.
1+ x 1− x
1−
x
1+ x 1+ x
Para 1 − y < 0 , segue-se que y > 1 e y ∉ B . Assim, tome 1 − y > 0 ⇔ y < 1. Logo,
1− y = 1− y .
Dizemos que um subconjunto S ⊂ R 2 é uma região limitada, quando existe M > 0 tal que
p < M para todo p ∈ S . Ainda, considere um subconjunto S ⊂ R 2 e p ∈ R 2 . Dizemos que
p é um ponto de fronteira (ou ponto de bordo) de S, quando toda bola aberta de centro p
contém pontos de S e pontos do complementar de S.
Exemplo 3.7 No exemplo 3.4, a imagem da figura 3.3 é uma região plana. Sua
dimensão é dois.
A propósito, a dimensão do exemplo 3.2 (o objeto gráfico é um ponto vermelho e o
suporte é um ponto), é zero.
3.3.1 Hipóteses
Pretendemos estudar a computação gráfica em 2D tal que o ambiente gráfico é o R 2 .
Assim, em particular, estudaremos os objetos gráficos planares que são pontos no plano,
curvas planas e regiões planares.
As hipóteses para este trabalho são enunciadas a seguir. Considere um objeto gráfico
(S, f), S ⊂ R m e f : S → R n .
(1) m = 2; isto é, estudaremos computação gráfica em um ambiente bidimensional.
(2) n = 1; isto é, estudaremos objetos gráficos monocromáticos quando R n for o
espaço de cor.
f :S → R
(3)
s a f ( s) = k ;
25
Pela hipótese (1), não estudaremos superfícies, pois apesar de sua dimensão ser 2, o
ambiente é o R 3 . E pela hipótese (4), não estudaremos fractais, pois possui dimensão
fracionária.
Em computação gráfica usamos modelos matemáticos para formular problemas reais
ou fenômenos da natureza. Para entender esses modelos e propor problemas e soluções
relevantes é importante criar níveis de abstração. Na próxima seção discutiremos o paradigma
dos quatro universos, segundo Gomes e Velho [9].
Uma pergunta básica em computação gráfica é: onde e para que usar a computação
gráfica?
No próximo capítulo apresentaremos uma interface de programação aplicada (API).
Em particular, a API gráfica OpenGL.
27
CAPÍTULO IV
PRELIMINARES EM OPENGL
O objetivo deste capítulo é introduzir o estudo da API gráfica OpenGL. Aqui, iremos
nos ater ao estudo de OpenGL no que se refere a aplicações 2D. Para um maior
aprofundamento do estudo de OpenGL sugerimos o livro Cohen e Manssour [6].
4.1 Introdução
Com os arquivos devidamente instalados em suas pastas, podemos agora partir para o
próximo passo que trata da configuração do ambiente Visual Studio 2005 para a utilização da
API gráfica OpenGL.
Iremos agora iniciar um novo projeto, porque devemos especificar para o VS qual
linguagem e bibliotecas usaremos. Para tal, na barra de menu principal do VS, selecione as
seguintes opções: File>> New>>Project (lê-se: clique em File, aponte para New e, em
seguida, clique em Project), conforme a figura 4.2.
30
Feito isto, será exibida uma janela onde escolheremos o nome do projeto, o tipo da
aplicação que iremos trabalhar e onde salvaremos as informações como executáveis e códigos
fontes, conforme figura 4.3.
Para o uso da OpenGL, o tipo de aplicação que devemos escolher é a Win32 Console
Application. Neste exemplo, como verificado na figura 4.3, estamos dando o nome ao projeto
de Teste OpenGL, e salvando em uma pasta padrão (vide Location na figura 4.3). Ao
31
clicarmos no botão OK, será exibida a janela referente às opções do projeto, conforme a figura
4.4 (a). Clique no botão Next para prosseguir. Será exibida a janela conforme a figura 4.4 (b).
.
Figura 4.4 (b) – Opções de projeto - escolha as opções conforme a figura.
O próximo passo é definir o arquivo que será utilizado como código fonte da
aplicação. Na barra de navegação Solution Explorer (figura 4.5), localizada na parte superior
direita da tela, clique com o botão direito na pasta Source Files e, em seguida, selecione a
opção Add. Você pode adicionar ao projeto um código fonte já existente, mas no nosso caso
iremos criar um novo. Clique em New Item conforme mostra a figura 4.6.
Será exibida uma nova janela, para que possamos escolher o tipo, o nome e a
localização do código fonte da nossa aplicação, como é ilustrado na figura 4.7.
Após a confirmação deste passo, clicando no botão OK, o VS estará pronto para
rodar aplicações baseadas em OpenGL. Para efeito de teste, iremos compilar o seguinte
código usando a linguagem C, com a adição da biblioteca GL\glut. Este teste é importante
para se verificar a correta configuração do VS.
/*
Teste do OpenGL e Visual Studio 2005
*/
#include<stdio.h>
#include<GL\glut.h>
void main ()
{
printf(“Olá mundo, esse é um programa teste do ambiente de programação.\n”);
printf(“Pressione Enter para encerrar”);
getchar();
}
Podemos observar no código fonte deste exemplo que, uma vez adicionada a
biblioteca glut.h, não precisamos adicionar as bibliotecas glu.h e opengl.h. Isso porque a
glut.h já faz chamadas a estas outras bibliotecas.
35
Os tipos de dados presente nos argumentos são referentes ao tipo de dados que a
OpenGL trabalha. Assim, por exemplo, ao invés de declararmos um dado integer como int
dado, declaramos este como GLint dado. Dessa forma, podemos trabalhar o código em
qualquer sistema operacional. A tabela 4.3 lista os possíveis tipos de dados que a OpenGL
utiliza.
Argumento Descrição
GL_POINT Usado para desenhar pontos.
GL_LINES Usado para desenhar segmentos de linha.
GL_LINE_STRIP Usado para desenhar segmentos de linha conectados.
GL_LINE_LOOP Usado para desenhar segmentos de linhas conectados, onde
o último vértice se conecta com o primeiro.
GL_POLYGON Usado para desenhar polígono convexo.
GL_TRIANGLES Usado para desenhar triângulos.
GL_TRIANGLE_STRIP Usado para desenhar triângulos conectado.s
GL_TRIANGLE_FAN Usado para desenhar triângulos a partir de um ponto
central.
GL_QUADS Usado para desenhar quadriláteros.
38
Para desenharmos uma primitiva, devemos explicitar a cor que desejamos usar para
exibí-la na tela através da função glColor3f( GLfloat r, GLfloat g, GLfloat b). Os valores dos
parâmetros r, g e b correspondem a porção das cores vermelho, verde e azul, respectivamente.
A cor branca é acessada pelo uso dos valores (1, 1, 1) enquanto que a cor preta é acessada
pelo uso dos valores (0, 0, 0).
A função glClearColor ( GLfloat r, GlFloat g, GLfloat b, GLfloat a) serve para se
armazenar uma cor para pintarmos uma janela, enquanto que a função
glClear(GL_COLOR_BUFFER_BIT) usa a cor armazenada para pintar o fundo da janela.
Aqui o valor do parâmetro a corresponde ao fator de transparência da cor.
O comando glFlush( ) faz com que os comandos da função Desenha(·) sejam de fato
executados e exibidos na tela quando utlizamos um único buffer de exibição (que é uma área
da memória onde se monta a imagem para a exibição).
A seguir temos um código que especifica uma função callback de desenho:
glutDisplayFunc(·).
#include<stdlib.h>
#include<GL\glut.h>
{
*
*
//Função que faz chamado a callback de desenho
glutDisplayFunc(Desenha);
*
*
return 0;
}
A criação e gerência de janelas, bem como a gerência de eventos como, por exemplo,
do teclado e do mouse, são responsabilidade do complemento GLUT. A coordenação destas
janelas é feita através das funções de inicialização de janelas que possuem parâmetros como
tamanho, posição e nome estabelecidos pelo programador.
A tabela 4.5 lista alguns parâmetros que podemos utilizar junto à função
glutInitDisplayMode(·), sendo estes separados pelo caractere “|” .
A seguir fornecemos um código fonte, que ilustra a criação de uma janela simples
com o fundo branco.
/*
Código: Primeira Janela OpenGL
Aluno: Marcello M. Ribeiro
*/
#include<stdlib.h>
#include<GL\glut.h>
void Inicializa(void)
{
//Define-se o uso da matriz de projeção
glMatrixMode(GL_PROJECTION);
41
return 0;
}
Neste código fonte, usa-se o modo de exibição com cores RGB, além de um único
buffer de imagem definido no comando glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE).
O pixel do canto superior esquerdo está na posição (40, 40), conforme os parâmetros da
função glutInitWindowPosition (40,40). A janela possui 400 pixels de altura por 400 pixels de
largura, conforme a função glutInitWindowSize (400, 400). Nos monitores de computador a
origem do sistema de coordenadas está localizada no pixel à esquerda superior, sendo que o
eixo x cresce para a direita e o eixo y cresce para baixo. O nome da janela é Primeira janela
OpenGL, definido no comando glutCreateWindow("Primeira janela OpenGL"). Este
comando, por definição, cria a janela. Ainda, a função Inicializa() chama as funções
glMatrixMode, cujo parâmetro GL_PROJECTION ativa a matriz de projeção da OpenGL;
gluOrtho2D, cujos parâmetros definem um plano de exibição da imagem na janela GLUT; e
novamente a função glMatrixMode, cujo parâmetro GL_MODELVIEW ativa a matriz de
42
A seguir podemos verificar um exemplo de código fonte, que utiliza interações com
o mouse e com o teclado.
#include<stdio.h>
#include<stdlib.h>
#include<GL\glut.h>
return 0;
}
Além da janela de exibição da GLUT (figura 4.11) que possui um desenho de uma
primitiva, o quadrilátero, temos também uma janela que se abre paralelamente, exibindo os
resultados da interação do mouse quando clicamos com o botão esquerdo, conforme a figura
4.12. Já o resultado da interação do teclado, é o fim da exeução do programa quando
pressionamos a tecla Esc.
46
OpenGL nos fornece ferramentas práticas para lhe dar com as transformações
geométricas. São fornecidas funções próprias para rotacionar, alterar a escala ou transladar
um objeto.
As funções responsáveis por estas transformações geométricas na OpenGL são
citadas a seguir.
• void glTranslatef( GLfloat tx, GLfloat ty, GLfloat tz): função responsável por
realizar a transformação de translação em um ou vários objetos gráficos. Os
parâmetros tx, ty e tz, indicam os valores que serão utilizados para transladar
o objeto referentes aos eixos x, y e z, respectivamente. Como estamos
trabalhando no espaço 2D, tz recebe 0.
• void glScalef( GLfloat ex, GLfloat ey, GLfloat ez): função responsável por
realizar a transformação de escala em um ou vários objetos gráficos. Os
parâmetros ex, ey e ez, indicam aos valores que serão utilizados para alterar a
escala do objeto referentes aos eixos x, y e z, respectivamente. Como estamos
trabalhando no espaço 2D, ez recebe 1.
• void glRotatef( GLfloat angulo, GLfloat x, GLfloat y, GLfloat z): função
responsável por realizar a transformação de rotação em um ou vários objetos
gráficos. O parâmetro ângulo indica quantos graus iremos rotacionar o objeto
no sentido anti-horário com relação à origem, enquanto que os parâmetros x,
y e z, indicam em quais eixos iremos ativar a rotação. Os valores variam de 0
(se a rotação não for aplicada no eixo) ou 1 (se a rotação for aplicada no
eixo). No caso do espaço 2D, iremos sempre fazer a rotação em torno do eixo
z, já que este é ortogonal ao monitor do computador. Assim sendo, com
relação aos parâmetros x, y e z, sempre entraremos com os valores 0,0 e 1.
Podemos aplicar uma transformação em apenas um objeto gráfico onde existam dois
ou mais objetos. Todavia, para isto devemos salvar a matriz de transformação corrente (matriz
que está sendo utilizada pela OpenGL antes de aplicarmos as transformações; e que tanto o
usuário quanto o programador não a vêm) na pilha de matrizes de transformações, através do
comando glPushMatrix(void). Após aplicar as transformações no objeto desejado, basta
48
GLfloat Tx=0;
void Desenha (void)
{
//Aplica as transformações sobre a imagem
glMatrixMode(GL_MODELVIEW);
glFlush();
}
49
void Inicializa(void)
{
//Define-se o uso da matriz de projeção
glMatrixMode(GL_PROJECTION);
CAPÍTULO V
MODELAGEM GEOMÉTRICA 2D
1
Segundo a pergunta básica para a computação gráfica conforme capitulo 3: onde usar a computação gráfica?
Resposta: aqui. Para que? Resposta: para uma representação da individualidade humana.
52
F −1 (0) = {( x, y ) ∈ R 2 ; F ( x, y ) = 0} .
Considere, novamente, o problema de se tentar criar uma representação para a
questão da individualidade humana. Com a idéia inicial e, razoável, de representar uma
mulher sobre o globo terrestre, e com a janela de exibição já definida, ambas no universo
físico, devemos escrever matematicamente uma mulher e o globo terrestre. Uma idéia
bastante razoável seria representar uma mulher como um conjunto cujos elementos são uma
circunferência, um triângulo e um conjunto de retas ou linhas (neste último caso, queremos
dizer segmentos de reta).
Utilizaremos a descrição geométrica funcional do tipo paramétrica para descrever a
circunferência, enquanto que triângulo e linhas são primitivas da OpenGL. Dessa forma, o
código a seguir ilustra uma circunferência, um triângulo (um sólido 2D, mas também podendo
ser visto como um conjunto de segmentos de reta) e uma linha.
#include<stdio.h>
#include<GL\glut.h>
#include<math.h>
53
#define PI 3.1415
glBegin(GL_LINE_LOOP);
for(i=0; i<=segmentos; i++)
{
glVertex2f(posx+cobs(i*angulo)*raio,posy+sin(i* angulo)*raio);
}
glEnd();
}
//Programa Principal
54
Aqui, o objeto gráfico é definido pelo par (S,f) definido por: considere o espaço de
cor C = R, tal que, 0 ∈ C corresponde à cor preta.
55
S1 = {( x, y ) ∈ R 2 ; ( x − 2) 2 + ( y − 5) 2 = 1},
3
S 2 = {( x, y ) = λ1 (5,4) + λ 2 (7,4) + λ3 (6,6), ∑ λ j = 1 , λ j ∈ [0,1]},
j =1
Observe que poderíamos ter definido S2 como uma curva plana, união dos conjuntos
{( x, y ) = α (5,4) + (1 - α ) (7,4); α ∈ [0,1]},
{( x, y ) = β (5,4) + (1 - β ) (6,6); β ∈ [0,1]},
{( x, y ) = γ (7,4) + (1 - γ ) (6,6); γ ∈ [0,1]}.
segmento de reta (linha). Observe que a circunferência não é uma primitiva para a OpenGL,
mas podemos considerá-la pela sua simplicidade para representá-la no computador, isto é,
basta fornecer o centro e o raio.
As transformações são utilizadas na representação CSG com dupla finalidade:
posicionar as primitivas no plano ou modificá-las. Isto é realizado para movimentos rígidos
(translação, rotação) ou não rígidos (escala).
Após posicionar devidamente as primitivas no plano, a representação CSG se utiliza
das operações booleanas união ( ∪ * ), interseção ( ∩ * ) e diferença ( -*) de conjuntos, para
combinar as diversas primitivas e criar o objeto gráfico final.
Agora estamos prontos para afirmar que o esquema de representação CSG é uma
árvore binária em que as folhas são primitivas geométricas e os vértices representam
operadores que podem ser transformações ou operações binárias (conjunto de pontos).
Considere, mais uma vez, o problema de se tentar criar uma representação para a
questão da individualidade humana. Agora, além da idéia inicial de representar uma mulher
sobre o globo terrestre e com a janela de exibição definida; também com o objeto gráfico (S,f)
definido conforme figura 5.1. Através do esquema de representação CSG temos a seguinte
árvore CSG, conforme figura 5.2, para a mulher.
Tendo em vista que o nosso modelo é composto por diferentes objetos gráficos, e
ainda, para que possamos tentar resolver o problema em questão (representar a
individualidade humana), gostaríamos que os objetos se mantivessem agrupados de forma a
termos a nossa mulher (representada pela boneca de saia preta) em cima do globo
(representado pela circunferência) independente das transformações aplicadas nestes objetos.
57
Devemos então estabelecer uma hierarquia entre os objetos que compõe o nosso
modelo.
5.1.3.2 Hierarquias
Para o nosso caso, em uma hierarquia, o primeiro passo é definir o tipo de vinculo
hierárquico que os objetos utilizarão. Aqui, utilizamos o vínculo geométrico, que usa
transformações geométricas para gerar um vínculo espacial entre os objetos.
O próximo passo é definir uma forma de estruturação para estes objetos. Iremos
utilizar a forma conhecida como Grupo de Objetos, particularmente, grupo de objetos
compostos, onde definimos transformações fixas entre estes, de forma a garantir que o
agrupamento dos mesmos seja como o desejado.
O código fonte a seguir ilustra uma boneca sobre uma circunferência em uma
tentativa de representar uma mulher sobro o globo terrestre.
#include<stdio.h>
#include<GL\glut.h>
#include<math.h>
#define PI 3.1415
GLint escala,translacao;
GLfloat Tx,Ty,Sx,Sy;
angulo = 2*PI/segmentos;
glBegin(GL_LINE_LOOP);
for(i=0; i<=segmentos; i++)
{
glVertex2f(posx+cos(i*angulo)*raio, posy+sin(i*angulo)*raio);
}
glEnd();
}
glBegin(GL_LINES);
glVertex2i(23,28); glVertex2i(23,33);
glVertex2i(27,28); glVertex2i(27,33);
58
glVertex2i(25,37); glVertex2i(25,43);
glVertex2i(25,42); glVertex2i(21,39);
glVertex2i(25,42); glVertex2i(29,39);
glEnd();
glBegin(GL_TRIANGLES);
glVertex2i(21,33);
glVertex2i(29,33);
glVertex2f(25,37);
glEnd();
}
//Função que desenha o modelo
void individualidade(void)
{
DrawCirculo(8,40,25,18);
DrawDoll();
}
void Desenho(void)
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glFlush();
}
//Sai do programa
if (tecla==27)
{
exit(0);
}
//Aciona a transformação de escala
else if (tecla =='e')
{
59
escala=1;
translacao=0;
}
//Aciona a transformação de translação
else if (tecla == 't')
{
escala=0;
translacao=1;
}
//Altera a escala do modelo
if (escala == 1)
{
if (tecla == 'a')
{
Sx=Sx-0.1;
if (Sx<=0)
{
Sx=0;
}
}
else if (tecla == 'd')
{
Sx=Sx+0.1;
}
else if(tecla == 'w')
{
Sy=Sy+0.1;
}
else if (tecla == 's')
{
Sy=Sy-0.1;
if (Sy<=0)
{
Sy=0;
}
}
}
//Translada o modelo
else if (translacao == 1)
{
if (tecla == 'a')
{
Tx--;
if (Tx<=-17)
{
Tx=-17;
}
}
else if (tecla == 'd')
{
Tx++;
if (Tx>=17)
{
Tx=17;
}
}
else if(tecla == 'w')
{
Ty++;
60
if (Ty>=3)
{
Ty=3;
}
}
else if (tecla == 's')
{
Ty--;
if (Ty<=-10)
{
Ty=-10;
}
}
}
glutPostRedisplay();
}
}
//Programa Principal
void main (void)
{
//Define quantidade de buffers e esquema cores da janela
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
//Define a posição inicial da janela
glutInitWindowPosition(100,100);
//Define o tamanho inicial da janela
glutInitWindowSize(400,400);
//Cria a janela com o título selecionado
glutCreateWindow("Modelagem Geométrica");
//Exibe o cena na janela
glutDisplayFunc(Desenho);
//Tratamento do teclado
glutKeyboardFunc(Teclado);
//Parâmetros de inicialização da cena
Inicializa();
//Aguarda interação através de eventos
glutMainLoop();
}
O código fonte acima gera a figura 5.3 de acordo com uma árvore CSG (figura 5.2).
61
CAPÍTULO VI
CONCLUSÕES
CAPÍTULO VII
BIBLIOGRAFIA
2- Azevedo, E. e Conci, A., Computação Gráfica - Teoria e Prática, São Paulo: Elsevier,
369p. 2007.
4- Boldrini, J. L., Costa, S. I. R., Figueiredo, V. L. e Wetzler, H. G., Álgebra Linear. São
Paulo: Harper e Row do Brasil, 3ª edição, 421p., 1986.
6- Cohen, M. e Manssour, I. H., OpenGL: Uma abordagem prática e objetiva. São Paulo:
Novatec, 478p. , 2006.
7- Foley, J. D., van Dam, A., Feiner, S. K., e Hughes, J. F., Computer Graphics:
Principles and Pratice in C. Nova Iorque: Addison – Wesley, 2ª edição, The System
Programming Series: 1174p., 1990.
8- Gomes, J., Costa, B., Darsa, L. e Velho, L – Graphical Objects. The Visual Computer,
12, 269-282, 1996.
9- Gomes, J. e Velho, L., Abstraction Paradigms for Computer Graphics. The Visual
Computer, 11, 227-249, 1995.
10- Gomes, J. e Velho, L., Fundamentos da Computação Gráfica. Rio de Janeiro: IMPA,
624p. , 2006.
11- Hoffman, K. e Kunze, R., Álgebra Linear. São Paulo: Polígono, 400p., 1971.
12- Lima, E. L., Álgebra Linear. Rio de Janeiro: IMPA, 5ª edição, 357p., 2001.
13- Lima, E. L., Curso de Análise. Volume 2, Rio de Janeiro: IMPA, CNPq, 557p. , 1981.
14- Requicha, A. A. G., Representations for Rigid Solids: Theory, Methods, and Systems.
Computing Surveys, Vol. 12, No. 4, 437 – 464, 1980.
16- Velho, L. e Gomes, J., Sistemas gráficos 3D. Rio de Janeiro: IMPA, Série computação
e Matemática, 336p., 2001.