Sunteți pe pagina 1din 76

UNIVERSIDADE CATÓLICA DE GOIÁS

DEPARTAMENTO DE COMPUTAÇÃO
BACHARELADO EM ENGENHARIA DA COMPUTAÇÃO

UM ESTUDO DE COMPUTAÇÃO GRÁFICA 2D:


MODELAGEM GEOMÉTRICA

MARCELLO MARINHO RIBEIRO

NOVEMBRO
2008
UNIVERSIDADE CATÓLICA DE GOIÁS
DEPARTAMENTO DE COMPUTAÇÃO
GRADUAÇÃO EM ENGENHARIA DA COMPUTAÇÃO

UM ESTUDO DE COMPUTAÇÃO GRÁFICA 2D:


MODELAGEM GEOMÉTRICA

Trabalho de conclusão de curso apresentado por Marcello


Marinho Ribeiro à Universidade Católica de Goiás como
requisito parcial para obtenção do título de bacharel em
Engenharia da Computação aprovado em 27/11/2008 pela
Banca Examinadora:
Professor Marco Antonio Figueiredo Menezes, Dr. UCG –
Orientador
Professor Nilson Cardoso Amaral, Dr. UCG
Professor Pedro Araújo Valle, MsC. UCG

ii
UM ESTUDO DE COMPUTAÇÃO GRÁFICA 2D:
MODELAGEM GEOMÉTRICA

MARCELLO MARINHO RIBEIRO

Trabalho de conclusão de curso apresentado por Marcello Marinho Ribeiro à


Universidade Católica de Goiás como requisito parcial para obtenção do título de bacharel em
Engenharia da Computação .

_______________________________ _________________________________

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

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 gráfica OpenGL para a implementação da modelagem de objetos gráficos.

Palavras-Chave: Computação gráfica 2D, OpenGL, modelagem geométrica, paradigma dos


quatro universos, objetos gráficos.

vii
ABSTRACT

The objective of this work is to write geometric modeling 2D with exceptions of


surfaces and fractals, from the point of view of the paradigms of the four universes and the
use of graphic API OpenGL to the implementation of graphics objects modeling.

Key-Words: Computer graphic 2D, OpenGL, geometric modeling, paradigm of four


universes, graphics objects.

viii
SUMÁRIO

LISTA DE FIGURAS ...............................................................................................................xi


LISTA DE TABELAS .............................................................................................................xii
LISTA DE ABREVIATURAS E SIGLAS ............................................................................xiii
1. INTRODUÇÃO ...................................................................................................................1
2. PRELIMINARES EM ÁLGEBRA LINEAR ......................................................................3

2.1. Matrizes .........................................................................................................................3


2.2. Espaços vetoriais ...........................................................................................................5
2.3. Transformações lineares, afins e projetivas ..................................................................8

3. UMA INTRODUÇÃO À COMPUTAÇÃO GRÁFICA ...................................................15

3.1. Cores ...........................................................................................................................15


3.2. Definições ...................................................................................................................18
3.3. Objetos gráficos planares ............................................................................................23
3.3.1. Hipóteses ..........................................................................................................24
3.4. Paradigma dos quatro universos .................................................................................25

4. PRELIMINARES EM OPENGL .......................................................................................27

4.1. Introdução ...................................................................................................................27


4.2. Instalação da OpenGL ................................................................................................28
4.2.1. Os arquivos necessários.....................................................................................28
4.2.2. Configurando o ambiente de programação .......................................................29
4.3. Nomes das funções e tipos de dados ...........................................................................35
4.4. Desenhando com OpenGL ..........................................................................................37
4.5. Criação de janelas .......................................................................................................39
4.5.1. Funções de inicialização de janelas ..................................................................39
4.6. Interações com teclado e mouse .................................................................................43
4.6.1. Callback do teclado ..........................................................................................43
4.6.2. Callback do mouse ...........................................................................................43
4.7. Transformações geométricas ......................................................................................47

5. MODELAGEM GEOMÉTRICA 2D ................................................................................51

5.1. O que é modelagem geométrica? ................................................................................51

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

Figura 1 – Transformação linear de escala ................................................................................9


Figura 2 – Transformação afim (linear) de translação .............................................................12
Figura 3 - Transformação projetiva: espaço (a) e plano (b) .....................................................14
Figura 4 - Percepção de cores ..................................................................................................16
Figura 5 - O olho humano ........................................................................................................18
Figura 6 - Imagem (monocromática) .......................................................................................19
Figura 7 - Objeto gráfico: ponto vermelho ..............................................................................20
Figura 8 - Objeto gráfico: circunferência e campos de vetores normal e tangente .................21
Figura 9 - Dados e processos da computação gráfica ..............................................................22
Figura 10 - Paradigma dos quatro universos ............................................................................25
Figura 11 - Tela inicial do Visual Studio 2005 ........................................................................29
Figura 12 - Iniciando um novo projeto ....................................................................................30
Figura 13 - Inserindo o tipo, o nome e a localização do projeto ..............................................30
Figura 14 - Opções do projeto - clique em Next para prosseguir ............................................31
Figura 15 - Opções de projeto - escolha as opções conforme a figura ....................................31
Figura 16 - Área de trabalho do projeto ...................................................................................32
Figura 17 - Adicionando um arquivo de código fonte .............................................................32
Figura 18 - Escolhendo o tipo, nome e localização do novo código fonte ..............................33
Figura 19 - Adicionando o nome das bibliotecas ao projeto ....................................................34
Figura 20 - Primeira janela OpenGL ........................................................................................42
Figura 21 - Desenho em janela GLUT .....................................................................................46
Figura 22 – Interação do mouse ...............................................................................................46
Figura 23 - Aplicação de translação .........................................................................................50
Figura 24 - Translação após 5 interações .................................................................................50
Figura 25 - Circunferência, triângulo e linha ...........................................................................54
Figura 26 - Um exemplo de árvore CSG .................................................................................56
Figura 27 - Uma representação para a individualidade humana ..............................................61

xi
LISTA DE TABELAS

Tabela 1 - Arquivos e pastas de instalação OpenGL ...............................................................28


Tabela 2 - Tipos de argumentos das funções OpenGL ............................................................35
Tabela 3 - Tipo de dados OpenGL ...........................................................................................36
Tabela 4 - Primitivas gráficas da OpenGL ...............................................................................37
Tabela 5 - Parâmetros da função glutInitDisplayMode(·) ........................................................40
Tabela 6 - Valores do parâmetro int botao ...............................................................................43
Tabela 7 - Valores do parâmetro int estado .............................................................................43

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

da API OpenGL, introduzida no capítulo anterior, para as nossas implementações. No


capítulo 6, apresentamos as nossas considerações finais, enquanto que no capítulo 7
apresentamos as referências bibliográficas.
3

CAPÍTULO II
PRELIMINARES EM ÁLGEBRA LINEAR

O objetivo deste capítulo é estudar alguns tópicos da disciplina álgebra linear do


ponto de vista da computação gráfica. Dessa forma, estudaremos matrizes, espaços vetoriais e
transformações lineares, afins e projetivas.
Neste capítulo, sugerimos os livros de Boldrini, Costa, Figueiredo e Weltz [4],
Gomes e Velho [10], Hoffman e Kunze [11] e Lima [12].
Para dar início aos nossos estudos de álgebra linear, definiremos algumas estruturas
algébricas básicas para trabalharmos com a computação gráfica. Iniciaremos com o estudo de
matrizes.

2.1 Matrizes

Uma matriz A é uma tabela com coeficientes reais dispostos em m-linhas e n-


colunas, denotada por:
 a11 a12 L a1n 
a a22 L a2 n 
A = [ aij ] = 
21
.
 M M O M
 
am1 am 2 L amn 

Dizemos que uma matriz A, m x n e B, p x q são iguais, quando têm o mesmo


número de linhas e colunas e a ij = bij , para i = 1, 2,..., m e j =1, 2,..., n. Dizemos que uma

matriz A, m x n, é uma matriz quadrada quando m = n. Quando todos os elementos de uma


matriz são iguais a 0, dizemos matriz nula. Quando temos uma matriz com uma única linha,
dizemos que esta é uma matriz linha, já quando temos uma única coluna dizemos que esta é
uma matriz coluna. Uma matriz linha também é designada por vetor linha e a matriz coluna
pode ser dita vetor coluna (ou simplesmente vetor).
Seja A uma matriz quadrada. A diagonal principal de uma matriz quadrada A = [ aij ] é

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 ].

A operação de multiplicação de um escalar α por uma matriz A é dada por:

[ d ij ] = α [ a ij ].

Ainda, a matriz transposta de uma matriz A, denotada por A T , é dada por:

[ e ji ] = [ aij ].

Sejam uma matriz A, m x n, e uma matriz B, p x q, com n = p. A operação de


multiplicação entre as matrizes A e B é dada por:

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 .

A seguir estudaremos espaços vetoriais e suas propriedades.


5

2.2 Espaços vetoriais

Iniciaremos esta seção definindo espaço vetorial real, ou simplesmente espaço


vetorial.

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,

e multiplicação por um escalar


⋅ : R x V →V
(α,u) a α ⋅ u.

Para quaisquer que sejam α, β ∈ R e u,v,w ∈V , as operações de adição e multiplicação por


escalar gozam das seguintes propriedades:
i) comutatividade: u + v = v + u;
ii) associatividade: (u + v)+ w = u+(v + w) e (αβ)⋅ v = α ⋅ (β ⋅ v);
iii) vetor nulo: existe 0 ∈ V , tal que v + 0 = 0 + v = v;
iv) inverso aditivo: para cada v ∈ V existe - v ∈ V , tal que -v +v = v +(-v) = 0;
v) distributividade: (α + β)⋅ v = α ⋅ v +β ⋅ v e α ⋅ (v + w) = α ⋅ v + α ⋅ w;
vi) multiplicação por 1: 1 ⋅ v = v .

Um exemplo de espaço vetorial é o conjunto R n com suas operações usuais de


adição e multiplicação por escalar.

Definição 2.2 Seja V um espaço vetorial. Um subespaço de V é um subconjunto


W ⊂ V que possui as seguintes propriedades:

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

Um subespaço vetorial do espaço vetorial V é um subconjunto W de V que


relativamente às operações de V é ainda um espaço vetorial. Por exemplo, R é um subespaço
vetorial do espaço vetorial R n .
Uma maneira de discretizarmos um espaço vetorial é através de uma estrutura
denominada base de um espaço vetorial, que definiremos agora.

Definição 2.3 Seja V um espaço vetorial.

a) Dizemos que o vetor v ∈ V é uma combinação linear dos vetores


v1 , v 2 ,..., v n ∈ V , quando existem escalares α 1 , α 2 ,..., α n ∈ R , tais que

v = α 1v 1 + α 2 v 2 + ... + α n v n .

b) Dizemos que o vetor v ∈ V é combinação afim dos vetores v1 , v 2 ,..., v n ∈ V ,


quando v é uma combinação linear e

α 1 + α 2 + ... + α n = 1 .
Em particular, quando α j ∈ [0,1] , j = 1,2,...,n, dizemos que v é uma combinação

convexa dos vetores v1 , v 2 ,..., v n ∈ V .

c) Sejam dados um vetor não nulo u ∈ V , denominado vetor normal, e um


escalar α ∈ R . O conjunto

H = {v ∈ V ; u T v = α }
é denominado um hiperplano.

d) O conjunto de vetores v1 ,v 2 ,...,v n de V, será dito linearmente independente,


quando

α 1v 1 + α 2 v 2 + ... + α n v n = 0 ⇒ α 1 =α 2 = L = α n = 0 .
7

e) Seja W um subconjunto de V. O subespaço vetorial de V gerado por W é o


n
conjunto de todas as combinações lineares de vetores v1 ,v 2 ,...,v ∈ W , que
denotaremos por

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.

g) A dimensão de V é o número de elementos em uma base de V, denotada por


dim V.

Neste trabalho, vamos manter o foco em espaços vetoriais de dimensão finita. A


propósito, dim R n = n. Em particular, dim R 2 = 2 , que dizemos 2D (dimensão dois).
Considere W1 e W2 subespaços vetoriais de V. Definimos o subespaço soma, a saber:

W1 + W2 = {v = w1 + w2 ∈ V ; w 1 ∈ W1 e w 2 ∈ W2 } .

Podemos agora enunciar um teorema sobre a soma das dimensões de subespaços


vetoriais que será útil no estudo de espaço projetivo adiante.

Teorema 2.1 Sejam W1 e W2 subespaços vetoriais de V. Então,

dim( W1 +W2 ) = dim W1 + dim W2 - dim( W1 ∩W2 ).

A seguir estudaremos transformações e suas propriedades.


8

2.3 Transformações lineares, afins e projetivas

Vamos iniciar esta seção definindo transformações lineares. Aqui, omitiremos a


notação “ ⋅ ” de multiplicação de um vetor v ∈ W por um escalar α ∈ R , isto é, α ⋅ v = αv .

Definição 2.4 Sejam V e W espaços vetoriais. Uma função T : V → W é chamada


transformação linear, quando possui as seguintes propriedades:

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,

T(0) = T(0 + 0) = T(0) + T(0) ⇒ T(0) = 0.

Iremos agora enunciar um teorema que associa transformações lineares e matrizes.


Este teorema é importante para a computação gráfica, porque ao transformar objetos no
computador, podemos fazê-los através de operações com matrizes.

Teorema 2.2 Toda transformação linear T : R n → R m corresponde a uma matriz


m x n e vice-versa.
Considere duas transformações lineares,
T1 : R n → R m
u a T1(u) = A1u
e
T2 : R p → R q
v a T2(v) = A2 v ,

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 .

Isso significa que a composição de transformações lineares corresponde ao produto de


matrizes e a adição de transformações lineares corresponde à adição de matrizes.

Exemplo 2.1 Considere o conjunto definido por


S = {( x, y ) ∈ R 2 ; 0 ≤ x ≤ 1, 0 ≤ y ≤ 1}

e uma transformação linear definida por


T : R2 → R2
2 0   x 
( x, y ) a T(x, y) =    .
0 0,5  y 
O conjunto S define o quadrado conforme a figura 2.1(a). A transformação linear T aplicada
aos pontos de S, em particular sobre os pontos extremos de S fornece

T (0, 0) = (0, 0), T (1, 0) = ( 2, 0), T (1, 1) = ( 2, 1 ), T (0, 1) = (0, 1 );


2 2

conforme a figura 2.1(b).

Figura 2.1 - Transformação linear de escala.

O exemplo 2.1 fornece uma transformação linear denominada transformação de


escala. Em computação gráfica, pretendemos aumentar ou diminuir o tamanho de objetos,
rotacioná-los, mudá-los de posição (transladá-los). Todavia, apesar de transformações de
10

escala e de rotação serem uma transformação linear em um espaço vetorial, a transformação


de translação não é. O nosso problema aqui é a origem (vetor nulo). Isto porque um ponto
parte da origem, mas um vetor não necessariamente. Resolveremos este problema mudando a
origem de lugar.
Um espaço afim pode ser definido como um par (P,V), onde P é o espaço de pontos e
V é o espaço de vetores. Seja A um espaço afim de dimensão n, o um ponto do espaço e
{v1 , v 2 ,..., v n } uma base de A. A lista F = {o, v 1 , v 2 ,..., v n } é um referencial de A. Um
referencial define um sistema de coordenadas do espaço afim. Ou seja, considere um ponto
p = o + v ∈ A , onde v é um vetor. Como os vetores v i , i = 1, 2, ... , n , formam uma base de A,
o ponto p pode ser escrito de modo único, na forma

p = o + c1v 1 + c 2 v 2 + .... + c n v n = c1 v 1 + c 2 v 2 + ... + c n v n + o ,

onde os n+1 escalares c1 , c 2 ,..., c n , 1, representam as coordenadas afins do ponto p no

referencial F de A. Geometricamente, a representação afim do R n é obtida colocando uma


cópia do R n no hiperplano x n +1 = 1 do espaço R n +1 . Isso tira o privilégio gozado pela origem

do R n que causa toda a confusão entre ponto e vetor.

Definição 2.5 Uma transformação T : A1 → A2 entre dois espaços afins,

A1 = ( P1 ,V1 ) e A2 = ( P2 , V2 ) , é chamada transformação afim, quando:

i) T preserva vetores e, além disso, a restrição

T /V :V → V

é uma transformação linear;


ii) T preserva pontos e, além disso,

T ( p + v ) = T ( p ) + T (v) .

Considere dois referenciais


11

F = (o, u 1 , u 2 ,..., u n ) e G = (o1 , v1 , v 2 ,..., v n ) ,

e um ponto x = o + x1u 1 + x 2 u 2 + .... + x n u n no espaço afim R n . Seja T uma transformação


afim e suponhamos que

n n
T (u j ) = ∑ aij v i e T (o) = ∑ a in +1v i .
i =1 i =1

O valor de T(x) no referencial G é obtido por

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

 a11 a12 ... a1n a1n +1   x1 


a a 22 ... a 2n a 2 n +1   x 2 
 21
 M M O M M  M  .
  
a n1 an2 ... a nn a nn +1   x n 
 0 0 ... 0 1   1 

Exemplo 2.2 Considere o conjunto definido por


S = {( x, y ) ∈ R 2 ; 0 ≤ x ≤ 1, 0 ≤ y ≤ 1}
e uma transformação afim obtida por
T : R3 → R3
1 0 1  x 
(x,y,1 ) a T(x,y,1 ) = 0 1 0  y .
0 0 1  1 

O conjunto S define o quadrado conforme a figura 2.2(a). A transformação afim T aplicada


aos pontos extremos de S, fornece
12

T( 0 ,0 ,1 ) = ( 1,0 ,1 ),T( 1,0 ,1 ) = ( 2 ,0 ,1 ),T( 1,1,1 ) = ( 2 ,1,1 ),T ( 0 ,1,1 ) = ( 1,1,1 );

conforme a figura 2.2(b) no plano.

Figura 2.2 - Transformação afim (linear) de translação.

O exemplo 2.2 fornece uma transformação linear denominada transformação de


translação. Em particular, T define uma transformação afim tal que os n = 2 primeiros
elementos da última coluna na matriz de transformação afim representa um vetor de
translação no R n = R 2 .
Em computação gráfica, pretendemos ver em perspectiva. Todavia, apesar da
translação de objetos ser realizada por uma transformação afim, a transformação afim
preserva o paralelismo. Resolvemos esse problema em um outro espaço que nos possibilita
retornar para o espaço afim quando necessário.
Tomando um ponto o como sendo a origem de R n +1 , definimos o espaço projetivo de
n +1
dimensão n como o conjunto das retas passando pela origem de R , eliminando-se a origem.

Indicamos esse espaço projetivo n-dimensional por RP . Dado um ponto p ∈ RP , tomamos


n n

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

as coordenadas euclidianas ( x1 ,..., x n , x n +1 ) como sendo as coordenadas projetivas do ponto p.

Ocorre que se λ ∈ R é um número não nulo, λ q representa o mesmo ponto projetivo p. Desse

modo λ ( x1 ,..., x n , x n+1 ) também representam coordenadas de p. Ou seja, as coordenadas


projetivas de um ponto são determinadas a menos de uma multiplicação por um escalar não
nulo, e por isso são chamadas de coordenadas homogêneas. Em particular, os hiperplanos
n
projetivos de RP são definidos pela equação linear homogênea
a1 x1 + ... + a n x n + a n +1 x n+1 = 0.
13

Uma base do espaço projetivo RP n é um conjunto de n + 2 pontos em R n +1 tal que

qualquer subconjunto com n + 1 elementos é linearmente independente. A base canônica de


RP n é dada por
e1 = (1,0,...,0),..., en = (0,...,0,1,0), en +1 = (0,...,0,1), en + 2 = (1,...,1,1).

Definição 2.6 Uma transformação projetiva

T : RP n → RP n

é dada por uma transformação linear invertível

T : R n +1 → R n +1

cuja matriz associada é uma matriz de ordem n + 1 invertível

A T 
M = ,
P S 

onde A é uma matriz n x n que corresponde às transformações lineares do espaço afim R n de

RP n , T é uma matriz n x 1 das translações de R n , P é uma matriz 1 x n que define os


chamados n pontos de fuga principais ( um ponto de fuga para cada direção de um eixo), e S
é uma matriz 1 x 1.

A projeção cônica de um ponto p ∈ R n+1 , p ≠ 0 , no plano Π é o ponto q ∈ R n +1 onde


a reta r que passa por o e p intersecta o plano Π.

Exemplo 2.3 Considere o conjunto definido por


S = {( x, y ) ∈ R 2 ; 0 ≤ x ≤ 1, 0 ≤ y ≤ 1}
e uma transformação projetiva obtida por
14

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

q 1 = p 1 = (0,0,1), q 2 = λp 2 = ( 1 ,0,1), q 3 = λp 3 = ( 1 , 1 ,1), q 4 = p 4 = (0,1,1);


2 2 2

conforme a figura 2.3 (b) no plano.

Figura 2.3 - Transformação projetiva: espaço (a) e plano (b).

No próximo capítulo faremos uma introdução à computação gráfica.


15

CAPÍTULO III
UMA INTRODUÇÃO À COMPUTAÇÃO GRÁFICA

O objetivo deste capítulo é introduzir o estudo da computação gráfica. Sobre um bom


histórico da computação gráfica sugerimos o capítulo 1 do livro clássico Foley, van Dam,
Feiner e Hughes [7]. Aqui, em particular, introduziremos o estudo de cores, desenvolveremos
algumas definições básicas, enunciaremos as nossas hipóteses para este trabalho e
finalizaremos apresentando o paradigma dos quatro universos.
Uma vez que vivemos no espaço, que é um ambiente 3D (três dimensões), a
utilização da computação gráfica é solicitada, principalmente, para 3D. Por outro lado, os
dispositivos de saída ainda bastante atuais nos computadores pessoais são o monitor e a
impressora. Isto nos leva a uma limitação inerente à computação gráfica, que é desenhar 3D
em 2D. Na tentativa de vencer essa limitação, a computação gráfica se aproxima da arte (veja
por exemplo Beever [3]) e das novas tecnologias.
Iniciaremos este capítulo introduzindo o estudo de cores.

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

pelas pessoas em faixa específica (espectro visível, zona do visível – aproximadamente


380nm, violeta, a 740nm, vermelho) através dos órgãos de visão. Um objeto terá determinada
cor se não absorver justamente os raios correspondentes à freqüência daquela cor. Por
exemplo, um objeto é vermelho se absorve preferencialmente as freqüências fora do
vermelho. Por outro lado, considerando as cores como luz, a cor branca resulta da
sobreposição de todas as cores, enquanto o preto é a ausência de luz. Veja a figura 3.1, onde
as setas representam ondas eletromagnéticas.

Figura 3.1 – Percepção de cores.

Podemos medir a luminosidade (ou intensidade da luz, ou irradiância), L, em função


do comprimento de onda, λ, a saber: a luminosidade é igual a potência P dividida pela área
que a luminosidade atinge, a qual é dada por A = 4πr2, onde r é o raio da esfera. A potência é
igual a energia, E, dividida pelo intervalo de tempo, ∆t, por exemplo, de uma lâmpada acesa,
conforme figura 3.1. A energia por sua vez é igual a freqüência da onda eletromagnética, f
(em terahertz, THz), vezes a constante de Planck, h (aproximadamente 6,6 x 10 −34 Js). A
freqüência é igual a velocidade da luz c dividida pelo comprimento de onda λ. Segue-se que,
para um intervalo de tempo ∆t e um raio r dados,

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

Iniciaremos esta seção definindo imagem, o que ressaltará a importância do estudo


de cores da seção anterior.

Definição 3.1 Uma imagem consiste de um conjunto bidimensional no qual, para


cada ponto, associamos uma informação de cor.

Pela definição 3.1, podemos utilizar como modelo matemático de imagem uma
função
f :U ⊂ R2 → C ,
19

onde C é um espaço de cor. O conjunto U é chamado suporte da imagem e o conjunto f(U) é


chamado de conjunto de cores da imagem ( ou gamute da imagem).
Geralmente temos C = R n . Os dois casos mais comuns são n=3 e n=1. Para n=3, o
contra-domínio é um espaço tricromático, por exemplo, um espaço com base nas primárias
RGB (red, green e blue). Neste caso a imagem é colorida. Quando n=1, dizemos que a
imagem é monocromática.

Exemplo 3.1 Considere o conjunto


{ }
U = ( x, y ) ∈ R 2 ; 1 ≤ x ≤ 3, 1 ≤ y ≤ 2 ,
e o conjunto C = R . Defina
f :U ⊂ R2 → C
1, x > 2
(x,y) a f(x,y) = 
0, caso contrário.
Tome no espaço de cor C, preto para o valor 0 e branco para o valor 1. Assim, a imagem é
aquela representada na figura 3.3.

Figura 3.3 - Imagem (monocromática).

A próxima definição é mais geral do que aquela de imagem. Definiremos objeto


gráfico, segundo Gomes e Velho [10]; que é uma variante conforme Gomes, Costa, Darsa e
Velho [8].

Definição 3.2 Sejam dados um subconjunto S ⊂ R m e uma função

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

b) S é chamado suporte geométrico do objeto gráfico e a função f é chamada a


função de atributos do objeto gráfico. A dimensão do suporte geométrico S é
chamada a dimensão do objeto gráfico.

Cada um dos atributos do objeto gráfico (cor, textura, campo de vetores, etc.) é
definido por uma função
fj :S → R j,
n

onde j = 1, 2.,.., k tal que n1 + n 2 + ... + n k = n , e a função de atributo é definida por

f = ( f1 , f 2 ,..., f k ) . Observe que R j , j= 1, 2,..., k, é uma representação de um conjunto de


n

atributos, isto é, cor, textura, etc.

Exemplo 3.2 Ponto. Considere um ponto definido em


{
S = (1,1) ∈ R 2 }
e a função atributo definida por
f :S → R
(1,1) a f( 1,1 ) = 1,
tal que f(1,1) = 1 corresponde, por exemplo, à cor vermelha no espaço de cor representado
pelo conjunto dos números reais R. Assim, o par ({1,1}, f) é um objeto gráfico, conforme
figura 3.4. O suporte geométrico é o conjunto unitário S.

Figura 3.4 - Objeto gráfico: ponto vermelho.

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.

Figura 3.5 - Objeto gráfico: circunferência e campos de vetores normal e tangente.

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

A definição comumente encontrada da computação gráfica é aquela segundo a ISO


(International Organization for Standardization – Organização internacional para
Padronização): “Computação gráfica é um conjunto de métodos e técnicas para transformar
dados em imagem através de um dispositivo gráfico”.
Em Velho e Gomes [16] podemos encontrar: “A computação gráfica é a área que
estuda os processos computacionais envolvendo modelos geométricos e imagens digitais”.
Estas definições sugerem as relações entre os dados e processos da computação
gráfica, a saber: figura 3.6.

Figura 3.6 - Dados e processos da computação gráfica ( página 1 em Velho e Gomes [16] ).

Conforme a figura 3.6, a visualização (ou síntese de imagens) faz a transformação de


modelos em imagens, enquanto a transformação inversa é feita pela visão computacional (ou
análise de imagens). Temos ainda os processos que atuam exclusivamente sobre um dos tipos
de dados, seja para analisá-los ou para modificá-los. Eles correspondem, respectivamente, à
modelagem geométrica e ao processamento de imagem. A propósito, lembramos que para este
trabalho objetivamos o estudo de modelagem geométrica, apenas.
Neste ponto, a definição 3.2 de objeto gráfico sugere a definição seguinte.

Definição 3.3 Computação gráfica é a disciplina que estuda os processos


computacionais de objetos gráficos.

Na próxima seção definiremos objetos gráficos planares e enunciaremos as nossas


hipóteses.
23

3.3 Objetos gráficos planares

Considere um objeto gráfico (S, f), S ⊂ R m e f : S → R n . Quando a dimensão do


espaço ambiente é 2 ( m = 2) temos os objetos gráficos planares. Os objetos gráficos planares
podem ter dimensão 0, 1 ou 2.
Uma bola (disco) aberta de centro em p ∈ R n e raio ε > 0 é definida por

B( p, ε ) = {v ∈ R n ; v − p < ε }.

Um homeomorfismo do conjunto X ⊂ R m sobre o conjunto Y ⊂ R n é uma bijeção contínua


−1
f : X → Y cuja inversa f : Y → X também é contínua. Por exemplo, a bola aberta

B = (0,1) ⊂ R 2 é homeomorfa ao espaço R 2 . Com efeito, defina as funções contínuas

f : R2 → B g : R2 → B
x e y
x a f ( x) = y a g ( y) = .
1+ x 1− y

Pela propriedade de quociente de normas e 1 + x > 0 , temos que

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 .

Ainda, usando novamente a propriedade de quociente de normas,


y
 y  1− y
f ( g ( y )) = f  =
 = y.
1− y  1+ y
1− y
−1
Portanto, f = g . Isto é, B é homeomorfa a R 2 (vide Lima[13]).

Definição 3.4 Um subconjunto c ⊂ R 2 é uma curva plana, quando dado um ponto


p ∈ c , existe uma bola aberta B(p,ε) de centro em p e raio ε > 0, tal que B(p,ε) I c é
homeomorfo ao intervalo (0,1) ou homeomorfo ao intervalo (0,1]. Uma curva plana é dita
fechada quando ela é homeomorfa à circunferência.
24

Exemplo 3.6 No exemplo 3.3,


S = {( x, y ) ∈ R 2 ; x 2 + y 2 = 1}
é uma curva plana. Sua dimensão é um.

Um subconjunto S ⊂ R 2 é uma região aberta, quando para todo ponto p ∈ S existe


ε > 0 tal que
B ( p, ε ) ⊂ S .

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.

Definição 3.5 Um subconjunto do plano S ⊂ R 2 é chamado uma região plana ou


sólido 2D, quando S contém todos os pontos de fronteira e é limitado.

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

isto é, a função de atributos é constante. Isto significa que estudaremos pontos,


curvas e regiões planares.
(4) dim S ∈ {0,1,2} .

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].

3.4 Paradigma dos quatro universos

O paradigma dos quatro universos se baseia no fato de que para estudar um


determinado fenômeno natural ou problema real no computador, associamos ao mesmo um
modelo matemático, em seguida procuramos uma representação finita desse modelo que seja
passível de uma implementação no computador.
Na figura 3.7, o universo físico contém os objetos que pretendemos estudar; o
universo matemático contém uma descrição abstrata dos objetos do universo físico; o
universo de representação é constituído por descrições discretas e finitas associadas aos
objetos do universo matemático; e no universo de implementação associamos as descrições do
universo de representação às estruturas de dados, com a finalidade de obter uma representação
do objeto no computador.

Figura 3.7 - Paradigma dos quatro universos.

Para utilizar os paradigmas de abstração efetivamente, necessitamos entender os


elementos de cada universo e relacioná-los. Em computação gráfica, os objetos gráficos têm a
propriedade de unificar toda essa variedade de elementos no universo matemático, tais como
pontos, curvas, etc. A partir daí, o paradigma dos quatro universos pode ser aplicado em cada
processo da computação gráfica.
26

Exemplo 3.8 Considere o problema de encontrar o maior elemento em uma lista


finita de inteiros. No universo físico temos, por exemplo, uma caixa com divisórias e, em
cada divisória, uma bola numerada. No universo matemático, um vetor v ∈ Z n . No universo
de representação temos os números v j ∈ Z n , j=1, 2, ..., n. No universo de implementação

temos uma estrutura de dados do tipo vetor (array).

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 o surgimento do mercado de placas gráficas para computadores pessoais,


surgiram também algumas ferramentas que possibilitaram a elaboração de aplicações gráficas
sem um grande conhecimento de hardware e software. Uma dessas ferramentas é a OpenGL.
OpenGL é uma API que tem como principal função dar suporte à criação de
programas 2D e 3D. Desenvolvida em 1992 pela Silicon Graphics, possui suas especificações
gerenciadas por um consórcio independente, o ARB (Architeture Review Board), formado por
grandes empresas que são líderes na área da computação gráfica como a Apple Computer,
3DLabs, NVIDIA e a SUN. Este consórcio é responsável pela evolução da OpenGL que está
atualmente na versão 2.1.
Devemos ressaltar que apesar de ter um uso relativamente simples, podendo ser
utilizada como uma biblioteca em C por exemplo, a OpenGL não é uma linguagem de
programação. Quando se diz que algum programa é baseado em OpenGL, significa que foi
escrito em alguma linguagem de programação como Java, C, C++, e utilizou uma ou mais
bibliotecas OpenGL.
Além de facilitar a implementação de aplicações gráficas, a OpenGL tem como uma
forte característica a portabilidade, podendo ter o mesmo código utilizado em vários sistemas
operacionais que suportem suas rotinas. Essas características acabam por fazer da OpenGL
um padrão em diversos setores.
Apesar da OpenGL ser uma API com vários recursos, ela não possui funções para
trabalhar eventos do mouse e teclado, assim como também não possui funções para gerenciar
janelas. Isto porque ela possui bibliotecas complementares diferentes para gerenciar estes
eventos em cada sistema operacional. As mais comuns são a GLUT (Graphic Library Utilities
Toolbox) e a GLU (Graphic Library Utilities). OpenGL, GLUT e GLU, possuem juntas
cerca de 250 funções que facilitam o desenvolvimento de aplicações gráficas.
28

A seguir faremos a instalação passo a passo para a utilização da OpenGL.

4.2 Instalação da OpenGL

OpenGL pode ser utilizada em vários sistemas operacionais, em vários ambientes de


desenvolvimento e com várias linguagens de programação. Para este trabalho, optamos por
utilizar o sistema operacional Windows Vista Home Premium, o ambiente de
desenvolvimento Visual Studio 2005 (usaremos a sigla VS), e a linguagem C. Os motivos que
levaram a estas escolhas foram a praticidade e a experiência.

4.2.1 Os arquivos necessários


Para que possamos criar programas usando a API OpenGL no ambiente VS,
precisamos que os arquivos que compõe a OpenGL (estamos incluindo também os
complementos GLU e GLUT) estejam devidamente instalados em pastas pré-determinadas.
Os arquivos e as pastas são encontrados na tabela 4.1; que diante do computador o usuário
deve verificar.

Tabela 4.1 - Arquivos e pastas de instalação OpenGL.


opengl32.dll
glu32.dll C:/ WINDOWS/System 32/
glut32.dll
opengl32.lib C:\Arquivos de
glu32.lib Programas\Microsoft Visual Studio
glut3.lib 8\VC\Platform SDK\Lib
opengl.h C:\Arquivos de
glu.h Programas\Microsoft Visual Studio
glut.h 8\VC\ Platform SDK \Include\gl

Os arquivos referentes à OpenGL e ao GLU já vêm devidamente instalados no


próprio Windows e no ambiente VS. Será necessário apenas baixar os arquivos referentes ao
GLUT. Estes arquivos podem ser encontrados no link
http://www.opengl.org/resources/libraries/glut/glut_downloads.php.
29

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.

4.2.2 Configurando o ambiente de programação


Após a instalação dos arquivos, ainda precisamos configurar o ambiente de trabalho
no Visual Studio 2005. O primeiro passo é iniciar o VS. A figura 4.1 mostra a tela de abertura
do VS.

Figura 4.1 - Tela inicial do Visual Studio 2005.

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

Figura 4.2 - Iniciando um novo projeto.

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.

Figura 4.3 Inserindo o tipo, o nome e a localização do projeto.

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 (a) - Opções do projeto - clique em Next para prosseguir.

.
Figura 4.4 (b) – Opções de projeto - escolha as opções conforme a figura.

Em Application type iremos marcar a opção Console application e na opção


Additional Options iremos escolher a opção Empty project. Finalizaremos esta etapa clicando
no botão Finish. Feito isso, a área de trabalho deverá ficar como vemos na figura 4.5.
32

Figura 4.5 - Área de trabalho do projeto.

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.

Figura 4.6 - Adicionando um arquivo de código fonte.


33

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.

Figura 4.7 - Escolhendo o tipo, nome e localização do novo código fonte.

Selecionaremos o tipo C++ File (.cpp). Deixaremos a localização do arquivo no


lugar sugerido pelo VS e, quanto ao nome, vamos colocar o mesmo do projeto: Teste
OpenGL. Em seguida, clique em Add, o que provocará o retorno ao ambiente de trabalho da
aplicação.
A próxima etapa consiste em configurar as propriedades do nosso projeto para que o
VS consiga compilar os comandos OpenGL. Na barra de menu principal, conforme figura 4.5,
clique na opção Project e, em seguida, selecione a opção Teste OpenGL Properties. O VS
exibirá a janela Teste OpenGL Property Pages (figura 4.8). Selecione a opção Configuration
Properties, em seguida selecione a opção Linker e depois Input. No campo Additional
Dependencies, adicione os nomes das bibliotecas opengl32.lib, glu32.lib e glut 32.lib (não
necessariamente nessa ordem), conforme mostrado na figura 4.8.
34

Figura 4.8 - Adicionando o nome das bibliotecas ao projeto.

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

Com o VS devidamente configurado para compilar aplicações baseadas em OpenGL,


apresentaremos na próxima seção nomes das funções e tipos de dados em OpenGL, que serão
úteis para a programação em computação gráfica.

4.3 Nomes das funções e tipos de dados

Para facilitar o uso e a padronização, as funções da OpenGL seguem uma convenção,


a saber:
<Prefixo_biblioteca><Comando_raiz><Número_argumentos><Tipo_argumentos>.

O prefixo da biblioteca referencia a qual biblioteca OpenGL estamos utilizando. Em


particular, gl para OpenGL, glu para GLU e glut para GLUT. O comando raiz referencia a
ação que a função irá executar. O número de argumento e o tipo são opcionais podendo ser
ocultados.
Um exemplo de função OpenGL é a glColor3f , em que identificamos a biblioteca gl
(OpenGL), o comando Color ( que trata cores), o número de argumentos que esta função
recebe (no caso 3) e o tipo deste argumentos que é f (de float). Ainda, um exemplo de função
que não utiliza um dos argumentos, é a função glTranslatef , onde identificamos a biblioteca
de origem sendo a OpenGL, a função raiz sendo a translação e, apesar de ter em seu nome o
tipo de argumentos que ela recebe (float), não menciona a quantidade destes.
Funções dos complementos GLU e GLUT não levam no nome as informações
referentes ao tipo e quantidade de argumentos, ficando apenas com o nome da biblioteca de
origem e o comando raiz. Como exemplo, temos a função glutInitWindowSize, que possui a
biblioteca de origem sendo a GLUT.
Alguns tipos de argumentos que podem ser usados para nomear as funções estão
descritos na tabela 4.2.

Tabela 4.2 - Tipos de argumentos das funções OpenGL.


Argumento Descrição
b Para argumentos do tipo signed char.
s Para argumentos do tipo short.
i Para argumentos do tipo integer.
f Para argumentos do tipo float.
36

d Para argumentos do tipo double.


ub Para argumentos do tipo unsigned
char.
us Para argumentos do tipo unsigned
short.
ui Para argumentos do tipo unsigned
integer.

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.

Tabela 4.3 - Tipo de dados OpenGL.

Tipo de dado OpenGL Representação interna Tipo equivalente em C Sufixo.


GLbyte Inteiro de 8 bits signed char b
GLshort Inteiro de 16 bits int ou long s
GLint, GLsize Inteiro de 32 bits short i
GLfloat, GLclampf Ponto flutuante de 32 bits Float f
GLDouble, GLclampd Ponto flutuante de 64 bits Double d
GLubyte, GLboolean Inteiro de 8 bits sem sinal unsigned char ub
GLushort Inteiro de 16 bits sem unsigned short us
sinal
GLuint, GLenum, Inteiro de 32 bits sem unsigned long ou ui
GLbitfield sinal unsigned int

A seguir estudaremos os desenhos usando OpenGL.

4.4 Desenhando com OpenGL


37

Antes de estudarmos os desenhos em OpenGL, precisamos entender o conceito de


funções callback.
As funções callbacks são utilizadas para tratar eventos durante a execução de uma
aplicação. Para cada tipo de evento (do mouse, do teclado, de desenho), devemos ter uma
callback diferente, bem como uma função para chamá-las. A propósito, quem faz a chamada
das callbacks é GLUT, à medida que os eventos vão acontecendo durante a execução do
programa.
A função responsável pela chamda à callback de desenho na OpenGL é a função
glutDisplayFunc(·), e o protótipo da função callback de desenho deve ser do tipo void
Desenha (void), e deverá conter a imagem a ser desenhada.
Para desenhar usando a OpenGL, utilizamos uma família de primitivas (formas
básicas que podem ser combinadas para gerar formas mais complexas) que a OpenGL nos
fornece, como pontos, retas, quadrados e triângulos. Estas primitivas são desenhadas por
segmentos de retas ligados aos seus vértices (com a exceção de pontos). Por isso, devemos
informar quando estamos iniciando e terminando o conjunto de vértices da primitiva, usando
as funções glBegin ( parâmetro) e glEnd( ). Os vértices são informados através do comando
glVertex2tipo(·) (onde o tipo varia conforme a tabela 4.2) . Os parâmetros das primitivas
utilizados pela função glBegin(·) estão presentes na tabela 4.4.

Tabela 4.4 - Primitivas gráficas da OpenGL.

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

GL_QUAD_STRIP Usado para desenhar quadriláteros conectados.

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>

void Desenha (void)


{
//Seleciona a cor do fundo da janela
glClearColor(1,1,1,0);

//Pinta o fundo da janela com a cor selecionada


glClear(GL_COLOR_BUFFER_BIT);

//Define como preta a cor do desenho


glColor3f(0,0,0);

//Define a posição de cada vértice do quadrado


glBegin(GL_QUADS);
glVertex2f(1.3,1.3);
glVertex2f(1.7,1.3);
glVertex2f(1.7,1.7);
glVertex2f(1.3,1.7);
glEnd();

//Executa os códigos OpenGL


glFlush();
}
*
*
*
int main (void)
39

{
*
*
//Função que faz chamado a callback de desenho
glutDisplayFunc(Desenha);

*
*
return 0;
}

Na próxima seção, iremos estudar a criação de estruturas que exibirão nossos


desenhos. Estudaremos a criação de janelas.

4.5 Criação de janelas

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.

4.5.1 Funções de inicialização de janelas


As funções de inicialização definem o modo de operação do complemento GLUT,
isto é, esquemas de cores e quantidades de buffer usada em uma aplicação; a posição do canto
superior esquerdo da janela; a largura e altura da janela; e cria e intitula a janela propriamente
dita.

• void glutInitDisplayMode(·): define o modo de operação do complemento


GLUT.
• void glutInitWindowPosition( int x, int y): indica a posição onde o canto
superior esquerdo da janela será exibido no início da aplicação. Os
parâmetros int x e int y, são referentes aos valores das coordenadas x e y do
pixel referente ao canto superior esquerdo da janela.
• void glutInitWindowSize( int widith, int height): determina a partir do pixel
inicial especificado na função glutInitWindowPosition(·,·) a largura (widith) e
a altura da janela (height) em pixels.
• void glutCreateWindow( char *string): cria a janela na posição indicada pela
função glutInitWindowPosition(·,·) do tamanho indicado na função
40

glutInitWindowSize(·). Através do parâmetro char *string devemos dar um


nome a esta janela.

A tabela 4.5 lista alguns parâmetros que podemos utilizar junto à função
glutInitDisplayMode(·), sendo estes separados pelo caractere “|” .

Tabela 4.5 - Parâmetros da função glutInitDisplayMode(·).


Parâmetro Descrição
GLUT_SINGLE Define apenas um buffer de cor, passando a usar
para a exibição da imagem na tela o comando
glFlush(). Usada para aplicações que não utilizam
animações.
GLUT_RGB Define que o sistema de cores utilizado pelo
aplicativo será R, G, B e A , os quais definem os
valores de vermelho, verde e azul, além do nível
de transparência presente na cor.

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 Desenha (void)


{
//define a cor de fundo da tela como BRANCA
glClearColor(1.0f, 1.0f, 1.0f,1.0f);

//Limpa a janela e pinta com a cor de fundo selecionada


glClear(GL_COLOR_BUFFER_BIT);

//Executa os códigos OpenGL


glFlush();
}

void Inicializa(void)
{
//Define-se o uso da matriz de projeção
glMatrixMode(GL_PROJECTION);
41

//Define-se o modo de projeção sendo o modo paralelo


//ortográfico exibição 2D
gluOrtho2D(0.0f, 3.0f, 0.0f, 3.0f);

//Define-se o uso da matriz de modelagem


glMatrixMode(GL_MODELVIEW);
}

int main (void)


{
// Função de inicialização da GLUT que define o modo de operação
//da GLUT
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);

// Função que especifica a posição inicial da janela


glutInitWindowPosition(40,40);

// Função que define o tamanho e a altura da janela (em Pixels)


glutInitWindowSize(400,400);

// Função que cria a janela, e usa como argumento o nome da


//janela a ser criada
glutCreateWindow("Primeira janela OpenGL");

// Função de callback responsável por desenhar e redesenhar na


//janela
glutDisplayFunc(Desenha);

//Inicia algumas variáveis de estados necessárias


Inicializa();

//Agurda as interações od usuário


glutMainLoop();

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

modelagem e visualização da OpenGL. A propósito, os parâmetros 0.0f, 3.0f, 0.0f, 3.0f da


função gluOrtho2D definem, respectivamente, 0 ≤ x ≤ 3 e 0 ≤ y ≤ 3 .
Finalmente, a função glutMainLoop( ) faz com que a aplicação aguarde as interações
do usuário. Deve-se sempre vir depois de todas as funções de chamada às callbacks do
programa.
Na figura 4.9 temos o resultado do código fonte acima, ou seja, uma janela gerada
através da GLUT.

Figura 4.9 - Primeira Janela OpenGL.

Iremos agora estudar as funções callback responsáveis pela interação do usuário


através do teclado e do mouse.
43

4.6 Interações com teclado e mouse

Para permitir as interações do usuário através do teclado e do mouse com aplicações


baseadas em OpenGL, também usamos callbacks.

4.6.1 Callback do teclado


A função void glutKeyboardFunc(·) é usada para chamar a callback que tratará
evento com teclas que estão presentes na tabela ASCII (American Standard Code for
Information Interchange). A propósito, este evento pode ser tanto o pressionar quanto o
liberar de uma tecla . A função callback possui o seguinte protótipo: void Nome_Funcao(
unsigned char tecla, int x, int y), onde os parâmetros int x e int y indicam respectivamente as
coordenadas da posição do mouse na tela no momento em que a tecla é pressionada.

4.6.2 Callback do mouse


A função void glutMouseFunc(·) é responsável por chamar a callback que tratará
eventos referentes ao pressionamento e a liberação dos botões do mouse. O protótipo da
função callback é: void Nome_Funcao(int botao, int estado, int x, int y). O parâmetro int
botao recebe o botão que está sendo pressionado, conforme tabela 4.6, enquanto int estado
recebe o valor do estado (se pressionado ou liberado), conforme tabela 4.7. Os parâmetros int
x e int y recebem o valor da posição do mouse com relação ao sistema de coordenadas do
monitor.

Tabela 4.6 - Valores do parâmetro int botao.


Valor Descrição
GLUT_LEFT_BUTTON Informa que o botão esquerdo foi pressionado.
GLUT_MIDDLE_BUTTON Informa que o botão do meio foi pressionado.
GLUT_RIGHT_BUTTON Informa que o botão direito foi pressionado.

Tabela 4.7 - Valores do parâmetro int estado.


Valor Descrição
GLUT_DOWN Indica que o botão está pressionado.
GLUT_UP Indica que o botão foi solto.
44

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>

void Desenha (void)


{
//define a cor de fundo da tela como PRETO
glClearColor(1.0f, 1.0f, 1.0f,1.0f);

//Limpa a janela e pinta com a cor de fundo selecioada


glClear(GL_COLOR_BUFFER_BIT);

//Função que altera a cor corrente para preta


glColor3f(0,0,0);

//Defini o conjunto de vértices pertencentes a um quadrado


glBegin(GL_QUADS);
glVertex2f(1.3,1.3);
glVertex2f(1.7,1.3);
glVertex2f(1.7,1.7);
glVertex2f(1.3,1.7);
glEnd();

//Executa os códigos OpenGL


glFlush();
}

// Função que define as ações com relaçòa ao teclado


void Teclado (unsigned char tecla, int x, int y)
{
if (tecla ==27)
{
exit(0);
}
}

//Função que define as ações com relação ao mouse


void Mouse (int botao, int estado, int x, int y)
{
if (botao == GLUT_LEFT_BUTTON)
{
if(estado == GLUT_DOWN)
{
printf ("O Botao esquerdo foi pressionado!\n");
}
}
}
void Inicializa(void)
{
//Define-se o uso da matriz de projeção
glMatrixMode(GL_PROJECTION);

//Define-se o modo de projeção sendo o modo paralelo ortográfico


//exibição 2D
45

gluOrtho2D(0.0f, 3.0f, 0.0f, 3.0f);

//Define-se o uso da matriz de modelagem


glMatrixMode(GL_MODELVIEW);
}

int main (void)


{
// Função de inicialização da GLUT que define o modo de operação da
//GLUT
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);

// Função que especifica a posição inicial da janela


glutInitWindowPosition(40,40);

// Função que define o tamanho e a altura da janela (em Pixels)


glutInitWindowSize(400,400);

// Função que cria a janela, e usa como argumento o nome da janela a


//ser criada
glutCreateWindow("Interação com mouse e teclado");

// Função de callback responsável por desenhar e redesenhar na


//janela
glutDisplayFunc(Desenha);

//Funçào de callback que trata eventos do teclado


glutKeyboardFunc(Teclado);

//Funçào de callback que trata eventos do mouse


glutMouseFunc(Mouse);

//Inicia algumas variáveis de estados necessárias


Inicializa();

//Agurada as interações do usuário


glutMainLoop();

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

Figura 4.11 - Desenho em janela GLUT.

Figura 4.12 - Interação do mouse.


47

4.7 Transformações geométricas

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

recuperar a antiga matriz que permanece no topo da pilha, através do comando


glPopMatrix(void). Isto será ilustrado no próximo código fonte.
O código fonte a seguir ilustra o uso de uma transformação de translação aplicada em
apenas um objeto da imagem. Na figura 4.12 (a), temos a imagem inicial gerada pelo
programa. Já a imagem 4.12(b), temos a imagem gerada após cinco interações com o usuário,
através do pressionamento da tecla t realizada pela função glutPostRedisplay( ) no código.
#include<stdio.h>
#include<stdlib.h>
#include<GL\glut.h>

GLfloat Tx=0;
void Desenha (void)
{
//Aplica as transformações sobre a imagem
glMatrixMode(GL_MODELVIEW);

//Transforma a matriz de transfomraçõa corrente na matriz identidade


glLoadIdentity();

//define a cor de fundo da tela como branco


glClearColor(1.0f, 1.0f, 1.0f,1.0f);

//Limpa a janela e pinta com a cor de fundo selecionada


glClear(GL_COLOR_BUFFER_BIT);

//Define a cor corrente como sendo a cor preta


glColor3f(0,0,0);

//Empilha matriz de transformação corrente


glPushMatrix();

//Translada o objeto gráfico em Tx


glTranslatef(Tx,0,0);

//Define os vértices do triângulo


glBegin(GL_TRIANGLES);
glVertex2f(0.0,0.0);
glVertex2f(0.4,0.0);
glVertex2f(0.2,0.5);
glEnd();

//recupera matriz de transformação da pilha


glPopMatrix();

//define o conjunto de vértices do quadrado


glBegin(GL_QUADS);
glVertex2f(1.3,1.3);
glVertex2f(1.7,1.3);
glVertex2f(1.7,1.7);
glVertex2f(1.3,1.7);
glEnd();

glFlush();
}
49

// Função que define as ações com relação ao teclado


void Teclado (unsigned char tecla, int x, int y)
{
if (tecla ==27)
{
exit(0);
}
else if (tecla == 't')
{
Tx=Tx+0.1;
}
glutPostRedisplay();
}

void Inicializa(void)
{
//Define-se o uso da matriz de projeção
glMatrixMode(GL_PROJECTION);

//Define-se o modo de projeção sendo o modo paralelo ortográfico


//exibição 2D
gluOrtho2D(0.0f, 3.0f, 0.0f, 3.0f);

//Define-se o uso da matriz de modelagem


glMatrixMode(GL_MODELVIEW);
}

int main (void)


{
// Função de inicialização da GLUT que define o modo de operação da
//GLUT
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);

// Função que especifica a posição inicial da janela


glutInitWindowPosition(40,40);

// Função que define o tamanho e a altura da janela (em Pixels)


glutInitWindowSize(400,400);

// Função que cria a janela, e usa como argumento o nome da janela a


//ser criada
glutCreateWindow("Interações com mouse e teclado");

// Função de callback responsável por desenhar e redesenhar na


//janela
glutDisplayFunc(Desenha);

//Funçào de callback que trata eventos do teclado


glutKeyboardFunc(Teclado);

//Inicia algumas variáveis de estados necessárias


Inicializa();

//Aguarda as interações do usuário


glutMainLoop();
50

Figura 4.14(a) - Aplicação de translação.

Figura 4.12(b) - Translação após 5 interações.

Após o estudo da API gráfica OpenGL e seus complementos, iremos estudar a


modelagem geométrica 2D no próximo capítulo.
51

CAPÍTULO V
MODELAGEM GEOMÉTRICA 2D

O objetivo deste capítulo é introduzir o estudo de modelagem geométrica 2D, do


ponto de vista do paradigma dos quatro universos, com as hipóteses enunciadas no capítulo 3.
Utilizaremos a API gráfica OpenGL vista no capítulo anterior. Para um estudo mais
aprofundado de modelagem geométrica recomendamos Gomes e Velho[10], Velho e Gomes
[16] e Azevedo e Conci [2].

5.1 O que é modelagem geométrica?

A modelagem geométrica trata do problema de descrever e estruturar objetos


gráficos (aqui, também chamados de modelos) em sistemas computacionais. Em geral, esses
objetos gráficos são objetos manufaturados como, por exemplo, casas, uma boneca, uma bola
de futebol. A propósito, objetos naturais como, por exemplo, nuvens, uma cachoeira, são
tratados em modelagem procedural (ou modelagem algorítmica); o que não veremos aqui.

5.1.1 Universo físico


O processo de modelagem geométrica começa no universo físico através da
caracterização da forma dos objetos associados a um problema específico. Ainda no universo
físico, a interface do usuário com o sistema computacional pode ser realizada pelo modo
textual não interativo, usando, por exemplo, a API gráfica OpenGL, ou pelo modo gráfico
interativo, usando, por exemplo, um editor de imagens (Photoshop, Flash, etc.).
Considere o problema de se tentar criar uma representação para a questão da
individualidade humana1. Uma idéia razoável seria representar uma mulher sobre o globo
terrestre. Inicialmente, devemos criar um local para exibirmos a nossa representação.
Utilizaremos uma janela do sistema operacional para exibirmos o nosso modelo. No
capítulo 4 já discutimos como se cria janelas utilizando o complemento GLUT da OpenGL,
conforme figura 4.9.

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

5.1.2 Universo matemático


No universo matemático, definimos os objetos gráficos para a geometria desses
objetos do universo físico. Neste ponto, suponhamos que modelamos estes objetos como
curvas planas (dimensão 1). A descrição geométrica funcional é de dois tipos: paramétrica e
implícita. Ambas, são adequadas para especificar concretamente os objetos gráficos.
Considere J um intervalo da reta. Na descrição paramétrica a curva é definida por
uma função
c : J ⊂ R → R2
t a c(t ) = ( x(t ), y (t )).
A equação paramétrica define uma curva como sendo a trajetória de um ponto. A descrição
implícita descreve uma curva como o conjunto das raízes de uma equação nas variáveis x e y.
Mais especificamente, temos uma função
F :U ⊂ R2 → R
( x , y ) a F ( x , y ) = 0.
O conjunto das raízes da equação F(x, y) = 0 é chamado de imagem inversa de 0 pela função
F e é indicado por F −1 (0) , ou seja,

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

//Função responsável por desenhar o circulo


void DrawCirculo(GLint raio, GLint segmentos, GLint posx, GLint posy)
{
GLint i;
GLfloat angulo;
angulo = 2*PI/segmentos;

glBegin(GL_LINE_LOOP);
for(i=0; i<=segmentos; i++)
{
glVertex2f(posx+cobs(i*angulo)*raio,posy+sin(i* angulo)*raio);
}
glEnd();
}

//Função responsável por desenhar (no caso pintar o fundo da janela de


//branco)
void Desenho(void)
{
//Pinta o fundo da janela de branco
glClearColor(1.0f,1.0f,1.0f,1.0f);
glClear(GL_COLOR_BUFFER_BIT);

//Seleciona a cor preta como cor corrente


glColor3f(0.0f,0.0f,0.0f);

//Desenha o circulo com raio =1, composto por 40 segmentos de retas


//em LOOP centrado no ponto posx=1 e posy=1
DrawCirculo(1,40,2,5);

//desenha um tiângulo ao lado direito da circunferência


glBegin(GL_TRIANGLES);
glVertex2f(5,4);
glVertex2f(7,4);
glVertex2f(6,6);
glEnd();

//Desenha uma linha


glBegin(GL_LINES);
glVertex2f(1,3);
glVertex2f(6,3.5);
glEnd();

//Força a exibição dos comandos na janela


glFlush();
}

//Função responssável pelos parâmetros de inicalização


void Inicializa(void)
{
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0,7,0,7);
glMatrixMode(GL_MODELVIEW);
}

//Programa Principal
54

void main (void)


{
//Define os parâmetros de buffer e 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 selecinoado
glutCreateWindow("Circunferência e primitivas");
//Exibe o cena na janela
glutDisplayFunc(Desenho);
//Tratamento do teclado
Inicializa();
//Aguarda interação através de eventos
glutMainLoop();
}

O código fonte acima gera a figura 5.1 a seguir.

Figura 5.1 - Circunferência, triângulo e linha.

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

S 3 = {( x, y ) ∈ R ; (x,y ) = (1,3) + t (5, 1 ), t ∈ R}


2
2
S = S1 U S 2 U S 3 ,
f :S →C
( x, y ) a f ( x, y ) = 0.

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]}.

5.1.3 Universo de representação


No universo de representação, criamos esquemas e parâmetros associados aos
objetos gráficos definidos no universo matemático. Esses esquemas são técnicas de
modelagem que definem regras de composição utilizadas para aplicar operações necessárias
aos elementos geométricos.
Podemos dividir os esquemas de representação em duas categorias: representação
por decomposição – o que não faremos aqui -, e representação por construção, isto é, construir
a partir de primitivas geométricas. Nesta subseção apresentamos o esquema de representação
CSG (Constructive Solid Geometry – Geometria Sólida Construtiva), seguindo a seção 2.5 do
artigo de Requicha [ 14]. Em particular, primitivas baseadas sobre conjuntos limitados e de
acordo com a definição 3.5.

5.1.3.1 Representação CSG


Considere o plano denotado por 2D.
O esquema de representação é uma árvore binária que utiliza três ingredientes
básicos: primitivas geométricas, transformações (projetivas) e operações booleanas
(regularizadas).
As primitivas geométricas são, em geral, objetos simples de descrever e representar
no computador, e constituem os blocos básicos da construção dos objetos gráficos. No
exemplo anterior, conforme a figura 5.1, as primitivas geométricas foram o triângulo e o
56

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.

Figura 5.2 - Um exemplo de árvore CSG.

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;

//Função responsável por desenhar a circnferência


void DrawCirculo(GLint raio, GLint segmentos, GLint posx, GLint posy)
{
GLint i;
GLfloat angulo;

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();
}

//Função que desenha a boneca


void DrawDoll(void)
{
//Desenha a cabeça da boneca
DrawCirculo(2,40,25,45);

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();

//Pinta o fundo da janela de branco


glClearColor(1.0f,1.0f,1.0f,1.0f);
glClear(GL_COLOR_BUFFER_BIT);

//Seleciona a cor preta como cor corrente


glColor3f(0.0f,0.0f,0.0f);

//Desenha o circulo com raio =1, composto por 40 segmentos de retas


//em LOOP centrado no ponto posx=1 e posy=1

//Empilha amatriz de transformação corrrente


glPushMatrix();
//Translada o modelo
glTranslatef(Tx,Ty,0);
//Altera a escala do modelo
glScalef(Sx,Sy,1);
//Desenha o modelo
individualidade();

//Restarua a matriz de transformação no topo da pilha


glPopMatrix();

glFlush();
}

void Teclado(unsigned char tecla, int x, int y)


{

//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();
}

//Função responsável pelos parâmetros de inicalização


void Inicializa(void)
{
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0,50,0,50);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
translacao = escala = 0;
Tx=Ty=0;
Sx=Sy=1;

}
//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

Figura 5.3 - Uma representação para a individualidade humana.

5.1.4 Universo de implementação


No universo de implementação, estabelecemos estruturas de dados e procedimentos
para suportar essas representações no computador. No esquema de representação CSG, bem
como no uso de vínculos hierárquicos, uma estrutura de dados adequada para ambas seria
uma árvore binária. Todavia, com a utilização da API gráfica OpenGL essa tarefa não é
visível para o usuário no caso da representação CSG, enquanto que no caso dos vínculos
hierárquicos, basta criarmos funções que agrupem os objetos da maneira desejada; o que não
aconteceria se estivéssemos programando em uma linguagem de programação C, por
exemplo.
No próximo capítulo faremos nossas considerações finais.
62

CAPÍTULO VI
CONCLUSÕES

Inicialmente, como afirmamos na introdução a motivação para esse trabalho foi a


construção de um jogo 2D, onde tínhamos uma idéia através da utilização de métodos de
programaçã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 acadêmico.
Nossos resultados para este trabalho foram os seguintes: no capítulo 3, reescrevemos
a definição de cor, de objetos gráficos, e definimos computação gráfica em termos de objetos
gráficos. No capítulo 5, escrevemos a modelagem geométrica 2D, com exceção de superfícies
e fractais, de uma maneira unificada conforme Gomes e Velho [10], através do paradigma dos
quatro universos e, também com a utilização da API gráfica OpenGL para a implementação
da modelagem geométrica de objetos gráficos planares.
Uma sugestão que pode se interessante é o estudo da visualização, processamento de
imagens e visão computacional com a mesma estratégia teórica e prática utilizada quando da
modelagem geométrica 2D. As dificuldades que encontramos para a realização desta sugestão
são o estudo de visão computacional 2D e a aplicação do paradigma dos quatro universos
sobre visualização, processamento de imagens e visão computacional de forma unificada.
A elaboração desta monografia contribuiu para melhorar meus conhecimentos como
estudante e, também, ajudou no amadurecimento como pesquisador, reforçando o meu desejo
em continuar o estudo do tema em um curso de mestrado.
63

CAPÍTULO VII
BIBLIOGRAFIA

1- Amabis, J. M. e Martho, G. R., Biologia dos Organismos. Volume 2. A diversidade


dos seres vivos – Anatomia e fisiologia de plantas e animais. São Paulo: Moderna, 2ª
edição, 624p., 2004.

2- Azevedo, E. e Conci, A., Computação Gráfica - Teoria e Prática, São Paulo: Elsevier,
369p. 2007.

3- Beever, J. - http://users.skynet.be/J.Beever/pave.htm. Acessado dia 18/09/2008.

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.

5- Borges, A. N. e Rodrigues, C. G., Introdução à Física Acústica. Goiânia: Produção


independente, 175p. , 2006.

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.

15- Silva, M. F. F., Esclarecendo o significado de "cor" em física. Física na Escola, v. 8, n.


1, 25-26, 2007.

16- Velho, L. e Gomes, J., Sistemas gráficos 3D. Rio de Janeiro: IMPA, Série computação
e Matemática, 336p., 2001.

S-ar putea să vă placă și