Sunteți pe pagina 1din 153

1

Captulo I Introduo a Linguagem JAVA ____________________________3


1. Estrutura Bsica de um Programa em Java ______________________________ 3
1.1 - Primeiro Programa ______________________________________________________ 3 1.2 - Variveis _____________________________________________________________ 4 1.3 - Operadores ___________________________________________________________ 5 1.4 - Constantes ____________________________________________________________ 6 1.5 - Comentrios___________________________________________________________ 7 1.6 - Fluxo de Controle_______________________________________________________ 7 Comando if () {} __________________________________________________________ 8 Comando for( ; ; ) {} _______________________________________________________ 9 O mtodo de Simpson ____________________________________________________ 11 Comando break e continue ________________________________________________ 13

2 - VETORES E MATRIZES _____________________________________________ 14


2.1 - Vetores______________________________________________________________ 2.2 - Declarao ___________________________________________________________ 2.3 - Inicializando vetores____________________________________________________ 2.4 Exemplo: Mtodo de Ordenao__________________________________________ 2.5 - Matrizes _____________________________________________________________ 2.6 Exemplo: Produto de uma matriz por um vetor_______________________________ 3.1 Membros da Classe ___________________________________________________ 3.2 Construtores _________________________________________________________ 3.3 Mtodos_____________________________________________________________ 3.3.1 - Introduo ________________________________________________________ 3.3.2 Modificadores do Mtodo____________________________________________ 3.3.3 Campos Static ____________________________________________________ 3.3.4 Exemplo de uma Classe Vetor________________________________________ 14 16 16 16 18 18 19 21 23 23 24 24 27

3 OBJETOS E CLASSES _____________________________________________ 19

Captulo I Introduo a Linguagem JAVA


Java uma linguagem de programao orientada a objeto com grande popularidade entre os usurios de internet. Uma das razes de sua popularidade na web que o Java gera applets para a web. Um applet um aplicativo para ser executado nas pginas web. Porm o Java tambm amplamente utilizado em outros domnios alm da internet principalmente por sua caracterstica multi-plataforma e no aspecto segurana.

1. Estrutura Bsica de um Programa em Java


A linguagem Java tem uma estrutura muito semelhante a C++ e por esta razo os usurios que aprendem Java como primeira linguagem de programao no tem dificuldades de futuramente programar em C++ tambm.

1.1 - Primeiro Programa


Em Java os programas so escritos utilizando-se classes. Inicialmente vamos aprender os comandos bsicos do Java e na seo 4 discutiremos o funcionamento das classes e a orientao a objeto. Como primeiro exemplo, consideremos o programa: HelloWorld.java class Hello { public static void main(String[] args) { System.out.println("Ola"); } } Para compilar execute: javac HelloWorld.java O resultado ser a gerao do arquivo: Hello.class Observe que o nome do arquivo gerado tem extenso .class e o nome corresponde ao nome da classe (Hello.class), e no ao original nome do arquivo compilado (HelloWorld.java)

E finalmente para executar: java Hello O resultado ser a exibio da mensagem: Hello. Possveis problemas: 1) Se na compilao ocorrer o seguinte erro:
'javac' is not recognized as an internal or external command, operable program or batch file.

soluo: verifique se o java est instalado e acrescente no path do windows o diretrio C:\jdk5.0\bin. Para alterar o path v para: Control Panel-> System -> Advanced -> Environment Variables. No primeiro quadro, User variables for ... edit a varivel path e acrescente o diretrio do java. 2) Se na compilao ocorrer o seguinte erro:
Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorldApp

soluo: v para: Control Panel-> System -> Advanced -> Environment Variables. No primeiro quadro, User variables for ... pressione new e acrescente: variable name: CLASSPATH variable value: . (obs:apenas um ponto)

1.2 - Variveis
O programa a seguir exibe como feita a declarao de algumas variveis e sua utilizao. public class Input { public static void main(String[] args) { int n = 1; float a = 2.3e10f; double b = 34.5e200; } } System.out.println("n = " + n + " a = " + a + " b = " + b);

As primeiras linhas declaram as variveis e os tipos: int Tipo da varivel n; Nome da varivel

Em seguda atribuimos o valor 1 para a varivel: n = 1; O Java tem diferentes tipos de variveis: boolean char byte short int long float double TRUE ou FALSE 16-bit Unicode 2.1 character 8-bit inteiro (signed) 16-bit inteiro (signed) 32-bit inteiro (signed) 64-bit inteiro (signed) 32-bit floating-point 64-bit floating point

1.3 - Operadores
Os operadores aritmticos sobre as variveis so os seguintes: + Soma * / % Subtrao Multiplicao Diviso Resto da diviso

A operao de incremento de uma unidade tem tambm um formato reduzido, ou seja, o comando: i = i + 1; E freqentemente representado por: i++; Da mesma forma i = i-1; pode ser escrito como i--; Como exemplo dos operadores, o programa abaixo calcula as razes reais de um polinmio de segundo grau:

Raizes.java class Raizes { public static void main(String[] args) { double a,b,c; double x1,x2; a = 1; b = -5; c = 6; x1 = (-b + Math.sqrt(b*b - 4*a*c)) / (2 * a); x2 = (-b - Math.sqrt(b*b - 4*a*c)) / (2 * a); System.out.println("x1 = " + x1 + " } } x2 = " + x2);

1.4 - Constantes
Uma constante um valor constante que definido no programa de forma que no ser alterado durante toda a execuo. Assim por exemplo, no programa anterior no pretendemos alterar os valores de a, b e c, e gostaramos que estes valores ficassem registrados por alguma referncia que pudesse auxiliar futuramente seu significado. Para declararmos uma constante utilizamos o prefixo final, como no exemplo: Raizes.java class Raizes { public static void main(String[] args) { final double a = 1; final double b = -5; final double c = 6; double x1,x2; x1 = (-b + Math.sqrt(b*b - 4*a*c)) / (2 * a); x2 = (-b - Math.sqrt(b*b - 4*a*c)) / (2 * a); System.out.println("x1 = " + x1 + " } } x2 = " + x2);

1.5 - Comentrios
possvel introduzir comentrios dentro de um programa em Java, bastando para isso coloc-los nos seguintes formatos: /* Comentario pode prosseguir por varias linhas e so termina ao encontar a marca de fim de comentario */ /** Normalmente usado no inicio das classes */ // Comentario somente at o final da linha Observe o exemplo abaixo: class Raizes { /** Solues reais da equao ax*x + b*x + c = 0 public static void main(String[] args) { double a,b,c; double x1,x2;

*/

a = 1; // Valores arbitrarios para a,b, e c b = -5; c = 6; x1 = (-b + Math.sqrt(b*b - 4*a*c)) / (2 * a); x2 = (-b - Math.sqrt(b*b - 4*a*c)) / (2 * a); System.out.println("x1 = " + x1 + " } } x2 = " + x2);

1.6 - Fluxo de Controle


O comando principal de deciso o if() { }. Os dois dos formatos mais utilizados de laos so: while() {} for( ; ;) { }

Comando if () {} Atravs deste comando o fluxo do programa pode ser desviado para executar ou no um conjunto de comandos. Considere o exemplo abaixo: class ExemploIf { /** Testa se um numero e par ou impar */ public static void main(String[] args) { int i,n; n = 7; // Entre com n

i = n % 2; if (i == 0) { System.out.println("\n n e um numero par\n"); } else { System.out.println("\n n e um numero impar\n"); } } } Neste exemplo a varivel i armazena o resto da diviso de n por 2. Caso seja zero, ento o programa passa a execuo do comando println("\n n e um numero par\n"). Se a condio falha, o comando else indica que o programa deve executar o comando println("\n n e um numero impar\n"). Observe que o else um comando opcional. Caso voc no o inclua, o programa segue para o prximo comando aps o if. Os testes utilizam os seguintes operadores relacionais: < > <= >= == != && ! || Menor Maior Menor ou igual Maior ou igual Igual Diferente e negao ou

Comando for( ; ; ) {} O for um comando apropriado quando queremos executar um conjunto de operaes um nmero fixo de vezes, como no exemplo da seqncia de fibonacci:

Fibonacci2.java class Fibonacci2 { public static void main(String[] args) { int n; int lo = 1; int hi = 1; final int MAX = 10; System.out.println("1: 1"); for(n = 2;n <= MAX; n++) { System.out.println(n + ": " + hi); hi = lo + hi; lo = hi - lo; } } } O resultado ser: 1: 1 2: 1 3: 2 4: 3 5: 5 6: 8 7: 13 8: 21 9: 34 10: 55

O comando for composto de trs argumentos: for( n=0 ; n<= 10 ; n++ Expresso de inicializao Expresso de teste Incremento

Expresso de inicializao Inicializa a varivel do lao. A inicializao feita uma nica vez quando o lao inicia. Expresso de teste Esta expresso testa (a cada vez que o conjunto de comandos no interior do for finaliza), se o lao deve ser encerrado. Enquanto a expresso for verdadeira o lao repetido. Para realizar teste utilizamos os operadores relacionais. Expresso de incremento A cada repetio do lao, o terceiro argumento (n++) incrementa a varivel n.

Exemplo: Mtodos numricos de integrao (ponto a esquerda)


Como aplicao do comando for o exemplo abaixo ilustra a implementao do mtodo do ponto a esquerda. Podemos utilizar os mtodos de integrao para obter uma aproximao para a expanso decimal de . Se calcularmos:

obteremos aproximaes para

class Integral { /** Integracao Numerica: Ponto a Esquerda */ public static void main(String[] args) { int i; int n; double x,dx ; double a,b ; double soma; a = -1; // Extremo inferior do intervalo b = 1; // Extremo superior do intervalo n = 100000; // Numero de particoes soma = 0.0; dx = (b-a)/n; x = a; for(i=0; i < n; i++) { soma = soma + Math.sqrt(1-x*x) * dx; x = x + dx; } System.out.println("\nIntegral = "+ 2*soma); }

10

Exemplo: Mtodos numricos de integrao (Monte Carlo)


Neste mtodo utilizamos um sorteio de pontos em uma certa regio. O quociente do nmero de pontos que so sorteados no interior pelo nmero total de pontos uma estimativa para a integral.
import java.util.*; public class MonteCarlo { public static void main(String[] args) { Random rn = new Random(); double x,y,f; long cont = 0; final long points = 500000; for (long i = 0; i < points; i++) { x = rn.nextDouble(); y = rn.nextDouble(); if ((x*x+y*y-1) < 0) cont++; } f = 4.0*cont/points; System.out.println("Pi = "+ String.valueOf(f) } }

Exemplo: Mtodos numricos de integrao (Mtodo de Simpson)


O mtodo de Simpson refina o mtodo do trapzio [Malta,Pesco,Lopes, Clculo a uma varivel Vol II].
public class Simpson { public static void main(String[] args) { int i; int n; double x,dx ; double a,b ; double soma; a = -1; // Extremo inferior do intervalo b = 1; // Extremo superior do intervalo n = 100000; // Numero de particoes soma = 0.0; dx = (b-a)/n; x = a; soma = Math.sqrt(1-x*x); for(i=1; i < n; i++) { x = x + dx; if (i % 2 == 0) soma = soma + 2 * Math.sqrt(1-x*x);

11

else soma = soma + 4 * Math.sqrt(1-x*x); } x = b; soma = soma + Math.sqrt(1-x*x); soma = soma * dx/3; System.out.println("\nIntegral = "+ 2*soma); System.out.println("\nErro = " + (2*soma-Math.PI)); } }

Comando while() {} Este segundo tipo de lao adequado para situaes onde no sabemos ao certo quantas vezes o lao deve ser repetido. Neste exemplo, primeiro feito o teste: while (n < 10) e somente em caso verdadeiro os comando dentro do while so executados. Assim se a condio for falsa a primeira vez, em nenhum momento os comandos dentro do lao sero executados. O exemplo abaixo ilustra a utilizao do comando: Exemplo: Mtodo de Newton O programa abaixo determina as razes da funo: utilizando o mtodo de Newton, ou seja, dada uma condio inicial x0, e um erro mximo, a seqncia abaixo pode convergir para uma das razes:

class Newton { /** Metodo de Newton */ public static void main(String[] args) { int i = 0 ; double xn,x0,xn_1 ; double erro ; x0 = 2; // Condicao inicial erro = 0.0000001; // Erro maximo xn = x0; xn_1 = xn + 2 * erro; // Garante a entrada no while

12

while (Math.abs(xn - xn_1) > erro) { xn_1 = xn; xn = xn_1 - (xn_1 * xn_1 - 2) / (2 * xn_1); i++; System.out.println("\nx[" + i + "] =" + xn); } System.out.println("\n A raiz obtida: "+ xn + "\n"); } } Comando break e continue Estes dois comando sservem para auxiliar na interrupo do lao, cumprindo diferentes tarefas: - O comando break; interrompe o lao (Qualquer dos formatos apresentados) e o programa continua no primeiro comando aps o lao. Exemplo: Exemplobreak.java
class Exemplobreak { public static void main(String[] args) { int n = 0; while (n < 10) { System.out.println("n = " + n); if (n > 3) break; n++; } System.out.println("Fim do programa \n"); } }

O resultado deste programa ser:


n = n = n = n = n = Fim 0 1 2 3 4 do programa

- O comando continue; transfere a execuo do programa para o teste do lao, que pode ou no prosseguir caso a condio seja verdadeira ou falsa. Exemplo: Mtodo da Bisseo
13

O programa abaixo determina as solucoes da equacao:

Para isso utilizaremos o mtodo da bisseo. No mtodo da bisseo procuramos uma raiz contida em certo intervalo [a,b] dado. A raiz existe desde que a funo seja contnua e o sinal da funo troque de um extremo para outro (ou seja f(a) * f(b) < 0). Bissecao.java
class Bissecao { public static void main(String[] args) { double a,b,c; double fa,fb,fc; final double erro = 0.0000001; a = 0; // Entre com o extremo a b = 2; // Entre com o extremo b fa = a*a - 2; fb = b*b - 2; c=0; if ((fa * fb) > 0) { System.out.println("\nCondicao inicial nao contem raiz !\n"); return; } while(Math.abs(a-b) > erro) { c = (a+b)/2.0; fc = c*c - 2.0; if (fa * fc < 0) { b = c; (fb * fc < 0) a = c;

} else { if else

break; } System.out.println("\n Raiz parcial = " + c); } System.out.println("\n\n Raiz obtida = " + c); return; } }

2 - VETORES E MATRIZES
2.1 - Vetores

14

Quando voc deseja representar uma coleo de dados semelhantes, pode ser muito inconveniente utilizar um nome de varivel diferente para cada dado. Para ilustrar vamos considerar o seguinte exemplo: Montar um programa que armazena as notas de 15 alunos e calcula a mdia obtida pela turma. As notas sero armazenadas em uma varivel do tipo float, porm ao invs de criarmos 15 variveis, utilizamos uma varivel do tipo vetor, definida como abaixo:
float notas[15];

o programa completo seria:


public class notas { public static void main(String[] args) { int i ; float media ; float soma = 0 ; float[] notas = new float[5]; for(i=0;i < 15;i++) { System.out.println(" Aluno " + (i+1)2 + ":"); notas[i] = TextIO.getlnFloat();; } for(i=0;i<15;i++) soma = soma + notas[i]; media = soma / 15; System.out.println("\n A media final foi: " + media); } }

Ns podemos melhorar o programa anterior, solicitando ao usurio o nmero de alunos da turma e s ento alocando o vetor de notas. Veja abaixo:
public class notas1 { public static void main(String[] args) { int i,n float media float soma = 0 float[] notas ; ; ; ;

System.out.println("Numero de alunos:"); n = TextIO.getInt(); notas = new float[n]; for(i=0; i < notas.length ;i++) { System.out.println(" Aluno " + (i+1) + ":"); notas[i] = TextIO.getlnFloat();;

15

} for(i=0;i< notas.length;i++) soma = soma + notas[i]; media = soma / notas.length; } } System.out.println("\n A media final foi: " + media);

2.2 - Declarao
Um vetor uma coleo de variveis de certo tipo, alocadas seqencialmente na memria. Para Java um declarao de varivel vetor do tipo: int[] n = new int[5]; reserva o espao de 5 variveis do tipo inteira, onde cada varivel pode ser referenciada conforme abaixo:
n[0] n[1] n[2] n[3] n[4]

IMPORTANTE: Observe que a declarao anterior cria cinco variveis, porm o primeiro elemento n[0]. A declarao de vetor inicia com o ndice 0 e finaliza no ndice 4. Se voc quer atribui um valor a um dos componentes do vetor basta referenci-lo: n[3] = 29; resulta em: 29
n[0] n[1] n[2] n[3] n[4]

2.3 - Inicializando vetores


Assim como possvel atribuir valores a uma varivel na mesma linha da declarao, o mesmo pode ser feito para vetores. Observe o exemplo abaixo: int [] n = {23, 3, -7, 288, 14};

2.4 Exemplo: Mtodo de Ordenao

16

Como exemplo vamos apresentar um programa que ordena uma seqncia de 10 nmeros reais.
public class Bolha { /* * * * * * * * * * * * * * * * * * * * * */ /* Metodo da Bolha (ordenacao de um vetor) */ /* * * * * * * * * * * * * * * * * * * * * */ public static void main(String[] args) { int i,n ; int flag; double swap; double[] x; /* Entrada de Dados */ System.out.println("Numero de elementos:"); n = TextIO.getInt(); x = new double[n]; System.out.println("Entre com os numeros para ordenacao"); for(i=0;i<n;i++) { System.out.println("x[" + i + "]: "); x[i] = TextIO.getDouble(); } /* Ordena a sequencia de numeros */ flag = 1; while(flag == 1) { flag = 0; for(i=0;i < n-1 ;i++) { if (x[i] > x[i+1]) { swap = x[i] ; x[i] = x[i+1]; x[i+1] = swap ; flag = 1 ; } } } /* Imprime a sequencia de numeros ordenada */ System.out.println("Sequencia ordenada : "); for(i=0; i<x.length; i++) System.out.println(" " + x[i]); } }

17

2.5 - Matrizes
Para representar uma matriz 3x4 (3 linha e 4 colunas) de nmeros reais utilizamos a seguinte declarao: float[][] A = new float[3][4]; Assim fica reservado um espao de memria conforme a figura abaixo: A[0][0] A[1][0] A[2][0] A[0][1] A[1][1] A[2][1] A[0][2] A[1][2] A[2][2] A[0][3] A[1][3] A[2][3]

2.6 Exemplo: Produto de uma matriz por um vetor


Vamos montar um programa que multiplica um vetor por uma matriz.
public class produto { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub int i,j; double[][] A = {{ 1.0, 1.5, 2.1}, { 3.4, 2.2, 9.1}, {-1.2, -3.4, 0.9}}; double[] v = {2.0, 1.0, 0.5}; double[] p = new double[3]; for(i=0;i<3;i++) { p[i] = 0; for(j=0;j<3;j++) { p[i] += A[i][j] * v[j]; } } for(i=0;i<3;i++) { System.out.print("["); for(j=0;j<3;j++) System.out.print(" " + A[i][j]); System.out.print(" ] "); System.out.println(" [" + v[i] + "]"); } for(i=0;i<3;i++) System.out.println(" p[" + i + "] =" + p[i]); } }

18

3 OBJETOS E CLASSES
3.1 Membros da Classe
Uma classe tem dois tipos principais de membros: 1. Campos: correspondem aos dados, representados pelas variveis da classe. 2. Mtodos: contm o cdigo executvel e define o comportamento dos objetos. Vamos iniciar com um exemplo, definindo um crculo: circulo.class public class circulo { public double raio; public double centrox,centroy; }

O programa abaixo utiliza a classe circulo: main.class


public class main { public static void main(String[] args) { circulo A; A = new circulo(); A.raio = 2.5; A.cx = 1.0; A.cy = 1.0; System.out.println("Circulo de Raio = " + A.raio); System.out.println("Circulo e Centro = ( " + A.cx + " , " + A.cy + " )"); } }

19

Inicializao da classe A declarao feita no programa main:


circulo A;

no cria o objeto crculo, apenas estabelece que a varivel A ser uma referncia para um objeto do tipo circulo. Somente com o comando:
A = new circulo();

foi criado o objeto crculo. Modificadores da Classe Na definio da classe podemos definir quatro modificadores da classe: 1) public: a classe tem acesso pblico 2) abstract: uma classe incompleta, que possui abstract mtodos que necessitam ser implementados por alguma subclasse. 3) final: no pode seu um asubclasse. 4) strict floating point: strictfp tem todas as operaes aritmticas em ponto flutuante definidas dentro da classe. Controle de Acesso aos Campos Observe que todos os campos definidos na classe crculo possuem o prefixo public. Este elemento define o controle de acesso ao campo, definindo assim se um dado campo da classe pode ou no ser alterado por outra classe. Existem quatro modificadores de acesso: 1) private: campos definidos private somente so acessveis na prpria classe. 2) public: so acessveis por qualquer classe. 3) package: acessveis em classe do mesmo pacote (ser definido posteriormente). 4) protected: so acessveis em subclasses, classes do mesmo pacote e na prpria classe. Modificadores de Campo Observe que todos os campos definidos na classe crculo possuem o prefixo public. Este elemento define o controle de acesso ao campo, definindo assim se um dado campo da classe pode ou no ser alterado por outra classe. Alm dos quatro modificadores de acesso, temos tambm modificadores de acesso: 1) static: o campo static instanciado somente uma vez para todos os objetos da classe. 2) final: no pode ser trocado aps a inicializao. 3) transient. 4) volatile.

20

3.2 Construtores
Quando um objeto criado pelo comando new, seus campos so iniciados com valores default. Muitas vezes gostaramos de definir como os campos devem ser iniciados, e possivelmente executar alguns comandos especficos da criao do objeto. Neste caso utilizamos os construtores. Algumas caractersticas importantes do construtor: 1) Tem sempre o mesmo nome da classe 2) Pode ou no ter argumentos 3) No retorna nenhum campo (ou seja, no possui return). Exemplo 1 (Construtor sem parmetros):
public class circulo { public double raio; public double cx,cy; circulo() { raio = 1.0; cx = 0; cy = 0; }

public class main { public static void main(String[] args) { circulo A,B; A = new circulo(); B = new circulo(); A.raio = 2.5; A.cx = 1.0; A.cy = 1.0; System.out.println("Circulo A de Raio = " + A.raio); System.out.println("Circulo A de Centro = ( " + A.cx + " , " + A.cy + " )"); System.out.println("Circulo B de Raio = " + B.raio); System.out.println("Circulo B de Centro = ( " + B.cx + " , " + B.cy + " )"); } }

21

Exemplo 2 (com parmetros):


public class circulo { public double raio; public double cx,cy; circulo() { raio = 1.0; cx = 0; cy = 0; } circulo(double r,double x,double y) { raio = r; cx = x; cy = y; }

public class main { public static void main(String[] args) { circulo A,B,C; A = new circulo(); B = new circulo(); C = new circulo(5, -1, 2.34); A.raio = 2.5; A.cx = 1.0; A.cy = 1.0; System.out.println("Circulo A de Raio = " + A.raio); System.out.println("Circulo A de Centro = ( " + A.cx + " , " + A.cy + " )"); System.out.println("Circulo B de Raio = " + B.raio); System.out.println("Circulo B de Centro = ( " + B.cx + " , " + B.cy + " )"); System.out.println("Circulo C de Raio = " + C.raio); System.out.println("Circulo C de Centro = ( " + C.cx + " , " + C.cy + " )"); } }

22

3.3 Mtodos

3.3.1 - Introduo
Um mtodo da classe uma rotina (cdigo) que atua sobre o objeto como, por exemplo, alterando seus campos, respondendo propriedades sobre o objeto, etc. No nosso exemplo, implementamos um mtodo que responde a rea do objeto crculo.
Exemplo 3 (metodo area): public class circulo { public double raio; public double cx,cy; circulo() { raio = 1.0; cx = 0; cy = 0; } circulo(double r,double x,double y) { raio = r; cx = x; cy = y; } public double area() { double a; a = Math.PI * raio * raio; return(a);

} }

public class main { public static void main(String[] args) { circulo A,B,C; A = new circulo(); B = new circulo(); C = new circulo(5, -1, 2.34); A.raio = 2.5; A.cx = 1.0; A.cy = 1.0; System.out.println("Circulo A de Raio = " + A.raio); System.out.println("Circulo A de Centro = ( " + A.cx + " , " + A.cy + " )"); System.out.println("Circulo A de Area = " + A.area()); System.out.println("Circulo B de Raio = " + B.raio);

23

System.out.println("Circulo B de Centro = ( " + B.cx + " , " + B.cy + " )"); System.out.println("Circulo B de Area = " + B.area()); System.out.println("Circulo C de Raio = " + C.raio); System.out.println("Circulo C de Centro = ( " + C.cx + " , " + C.cy + " )"); System.out.println("Circulo C de Area = " + C.area()); } }

3.3.2 Modificadores do Mtodo


Observe que na definio de nosso mtodo:
public double area() {

existem dois elementos a serem destacados: 1) public double area() O elemento double indica que nosso mtodo retorna um campo double, pois estamos retornando um valor no double no comando: return(a) 2) public double area() O elemento public denominado modificador do mtodo e semelhante aos modificadores de campo. Para o mtodo existem os seguintes modificadores: private: mtodos definidos private somente so acessveis na prpria classe. public: so acessveis por qualquer classe. package: acessveis em classe do mesmo pacote (ser definido posteriormente). protected: so acessveis em subclasses, classes do mesmo pacote e na prpria

abstract: o corpo do mtodo no definido nesta classe. Uma subclasse fica responsvel pela implementao do mtodo. static: veja na prxima seo. final: no permite ser sobreposto por uma subclasse. synchronized: ser discutido em outras sees. native: ser discutido em outras sees. strictfp: strict floating point tem todas as operaes de ponto flutuante avalias estritamente.

3.3.3 Campos Static

24

O exemplo abaixo ilustra a utilizao de um campo static. Exemplo 4: (static)


public class circulo { public double raio; public double cx,cy; private static long Id = 0; circulo() { raio = 1.0; cx = 0; cy = 0; Id++; } circulo(double r,double x,double y) { raio = r; cx = x; cy = y; Id++; } public double area() { double a; a = Math.PI * raio * raio; return(a);

public long getId() { return Id; }

public class main { public static void main(String[] args) { circulo A,B,C; A = new circulo(); B = new circulo(); C = new circulo(5, -1, 2.34); A.raio = 2.5; A.cx = 1.0; A.cy = 1.0; System.out.println("Circulo System.out.println("Circulo + A.cy + " )"); System.out.println("Circulo System.out.println("Circulo A de Raio = " + A.raio); A de Centro = ( " + A.cx + " , " A de Area = " + A.area()); No = " + A.getId());

25

System.out.println("Circulo System.out.println("Circulo + B.cy + " )"); System.out.println("Circulo System.out.println("Circulo System.out.println("Circulo System.out.println("Circulo + C.cy + " )"); System.out.println("Circulo System.out.println("Circulo } }

B de Raio = " + B.raio); B de Centro = ( " + B.cx + " , " B de Area = " + B.area()); No = " + B.getId()); C de Raio = " + C.raio); C de Centro = ( " + C.cx + " , " C de Area = " + C.area()); No = " + C.getId());

Por que todos os Id so iguais ? Porque Id static ! Para enumerarmos as esferas ser necessrio criar um campo no static na classe.
Exemplo 5: (enumerando cada esfera) public class circulo { public double raio; public double cx,cy; private static long Id = 0; private long MyId; circulo() { raio = 1.0; cx = 0; cy = 0; MyId = Id++; } circulo(double r,double x,double y) { raio = r; cx = x; cy = y; MyId = Id++; } public double area() { double a; a = Math.PI * raio * raio; return(a);

public long getId() { return Id; } public long getMyId() { return MyId; }

public class main {

26

public static void main(String[] args) { circulo A,B,C; A = new circulo(); B = new circulo(); C = new circulo(5, -1, 2.34); A.raio = 2.5; A.cx = 1.0; A.cy = 1.0; System.out.println("Circulo System.out.println("Circulo + A.cy + " )"); System.out.println("Circulo System.out.println("Circulo System.out.println("Circulo System.out.println("Circulo + B.cy + " )"); System.out.println("Circulo System.out.println("Circulo System.out.println("Circulo System.out.println("Circulo + C.cy + " )"); System.out.println("Circulo System.out.println("Circulo A de Raio = " + A.raio); A de Centro = ( " + A.cx + " , " A de Area = " + A.area()); No = " + A.getMyId()); B de Raio = " + B.raio); B de Centro = ( " + B.cx + " , " B de Area = " + B.area()); No = " + B.getMyId()); C de Raio = " + C.raio); C de Centro = ( " + C.cx + " , " C de Area = " + C.area()); No = " + C.getMyId()); " + A.getId());

System.out.println("Total de crculos = } }

3.3.4 Exemplo de uma Classe Vetor


O exemplo abaixo ilustra a implementao de uma classe vetor de double. Exemplo 6: Vetores public class Vetor { private double[] v; private int dim; Vetor(int n){ dim = n; v = new double[n]; }

27

Vetor(double[] C){ dim = C.length; v = new double[dim]; for(int j=0;j<dim;j++) v[j]=C[j]; } // Metodos de Acesso public void set(int i,double x){ if ((i >= 0) && (i<dim)) v[i]=x; } public double get(int i) { if ((i >= 0) && (i<dim)) return (v[i]); else return 0; } }

public class main { public static void main(String[] args) { Vetor x = new Vetor(4); x.set(0,1.2); x.set(1,-2); x.set(2,-4); x.set(3,3.2); for(int i=0;i<4;i++){ System.out.println("v[" + i + "]= " + }

x.get(i)); } }

28

CAPTULO II VISUALIZAO E APLICAES GRFICAS 2D __________ 3


1 - PONTOS E RETAS NO OPENGL ______________________________________ 3 1.1 A Tela do Computador ___________________________________________ 3 1.2 Cores_________________________________________________________ 3 1.3 Introduo ao JoGL______________________________________________ 4
1.3.1 Apresentao______________________________________________________ 4 1.3.2 Instalao_________________________________________________________ 4

1.4 Exemplo: Criando a janela OpenGL _________________________________ 6 1.5 Exemplo: Plotar um ponto na tela utilizando as bibliotecas do OpenGl ______ 6 1.5 Comando: gluOrtho2D ___________________________________________ 9 1.6 Exemplo: Plotar uma reta unindo dois pontos ________________________ 10
1.6.1 Algoritmo ingnuo _________________________________________________ 10 1.6.3 Retas no Opengl __________________________________________________ 12

1.7 Exemplo: Plotar o grfico de uma funo ____________________________ 12 2 TECLADO E MOUSE (Callbacks) ____________________________________ 19 2.1 Introduo ____________________________________________________ 19 2.2 Teclado ______________________________________________________ 19 2.3 Exemplo: Utilizao do teclado no programa funes. __________________ 19 2.4 Mouse _______________________________________________________ 21
2.4.1- Interrupes a partir do mouse ________________________________________ 21 2.4.2- Aplicaes: Realizando o zoom do grfico ______________________________ 26

3 CURVAS PARAMTRICAS _________________________________________ 32 3.1 Introduo ____________________________________________________ 32 3.2 Exemplo: Visualizao de Curvas Paramtricas ______________________ 32
3.2.1 Mdulo main.java__________________________________________________ 32 3.2.2 Mdulo curva _____________________________________________________ 35 3.2.4 Exerccio _________________________________________________________ 37

3.3 Curvas na forma Polar __________________________________________ 37 3.4 Exemplo: Visualizao de Curvas Polares ___________________________ 38 3.5 Exerccios ____________________________________________________ 39 4 CURVAS IMPLCITAS _____________________________________________ 40 4.1 Introduo ____________________________________________________ 40 4.2 Visualizao de Curvas Implcitas _________________________________ 40 4.3 Programa Curva Implcita ________________________________________ 41 4.4 Exerccio _____________________________________________________ 42 5 RETAS E POLGONOS NO OPENGL _________________________________ 43 5.1 Retas e Polgonos______________________________________________ 43 5.2 Exemplo: Visualizao dos Mtodos Numricos de Integrao ___________ 44 6 PROCESSAMENTO DE IMAGEM ____________________________________ 46 6.1 Introduo ____________________________________________________ 46 7 FRACTAIS ______________________________________________________ 53
1

7.1 Conjuntos auto-semelhantes _____________________________________ 53 7.2 Dimenso Hausdorff e o conceito de fractal __________________________ 54 7.3 Exemplos de fractais ____________________________________________ 54
7.3.1- Tringulo de Sierpinski ______________________________________________ 7.3.2- Tringulo de Sierpinski utilizando Monte Carlo ____________________________ 7.3.3- Fern ____________________________________________________________ 7.4 Conjunto de Julia ___________________________________________________ 55 61 62 65

CAPTULO II VISUALIZAO E APLICAES GRFICAS 2D 1- PONTOS E RETAS NO OPENGL


1.1 A Tela do Computador
A tela do computador pode ser considerada uma matriz de clulas discretas (Pixels), cada qual pode estar acesa ou apagada.

0,1 1,1 0,0 1,0

2,1 2,0

A definio da tela varia conforme o monitor e a placa grfica. As definies bsicas encontradas na maioria dos monitores so: 640 x 480 800 x 600 1024 x 768 1280 x 1024

1.2 Cores
A cada pixel associamos uma cor. Para obter uma cor, o monitor envia certa combinao de vermelho, verde e azul (RGB). O nmero de cores possveis varia conforme o hardware. Cada pixel tem uma mesma quantidade de memria para armazenar suas cores. O buffer de cores (Color Buffer) uma poro da memria reservada para armazenar as cores em cada pixel. O tamanho deste buffer usualmente medido em bits. Um buffer de 8 bits pode exibir 256 cores diferentes simultaneamente. Conforme a capacidade da placa grfica podemos ter: 8 bits 256 cores (High Color) 16 bits 65.536 cores (True Color) 24 bits 16.777.216 cores (True Color) 32 bits 4.294.967.296 cores Existem duas formas bsica de acessar as cores no OpenGL: RGB e Modo Indexado. Trabalharemos sempre em formato RGB. No formato RGB voc deve informar as intensidades de Vermelho, Verde e Azul desejadas. Estas intensidades devem variar entre 0.0 a 1.0. A tabela abaixo mostra como obter as cores bsicas:

Cores
Vermelho Verde Azul Amarelo Cyan Magenta Branco Preto

R
1.0 0.0 0.0 1.0 0.0 1.0 1.0 0.0

G
0.0 1.0 0.0 1.0 1.0 0.0 1.0 0.0

B
0.0 0.0 1.0 0.0 1.0 1.0 1.0 0.0

1.3 Introduo ao JoGL


1.3.1 Apresentao O sistema grfico OpenGL (GL significa Graphics Library) uma biblioteca (de aproximadamente 350 comandos) para aplicaes grficas. O OpenGL foi desenvolvido pela Silicon Graphics (SGI) voltado para aplicaes de computao grfica 3D, embora possa ser usado tambm em 2D. As rotinas permitem gerar primitivas (pontos, linhas, polgonos, etc) e utilizar recursos de iluminao 3D. O OpenGL independente do sistema de janelas, ou seja, suas funes no especificam como manipular janelas. Isto permite que o OpenGL possa ser implementado para diferentes sistemas: X Window System (Unix), Windows 95 e NT, OS/2 , Macintosh, etc. Vrias tentativas foram feitas no sentido de desenvolver uma verso do OpenGL para Java com algum sucesso, mas somente agora com a parceria entre a Sun (criadora do Java) e a Silicon Graphics (criadora do OpenGL) esta sendo desenvolvido uma verso oficial. 1.3.2 Instalao Inicialmente voc deve obter duas bibliotecas na internet, no link: https://jogl.dev.java.net/servlets/ProjectDocumentList?folderID=3631&expandFolder=3631&folderID=4 843 Os programa executados e testados nestas notas de aulas foram feitos utilizando-se: Release Builds2005(0) - > 1.1 June 24 (12) (veja abaixo)

jogl (0)/ o o o o o o o o Release Builds 2003 (6)/ Release Builds 2004 (0)/ Release Builds 2005 (0)/ 1.1.1 - July 12 (12)/ 1.1b08 - February 7 (11)/ 1.1b09 - February 15 (11)/ 1.1b10 - February 27 (11)/ 1.1b11 - May 11 (12)/ 1.1 b12 - May 27 (12)/ 1.1 - June 24 (12)/ JSR-231 beta 01 - October 27 (11)/ Release Builds 2006 (0)/ Temporary Files (4

So necessrios dois pacotes (em destaque na tabela abaixo): 1. jogl.jar 2. jogl-natives-win32.jar (para usurios do windows XP)

1.1 - June 24

JOGL 1.1 release build


Filter this list Name javadoc_public.zip Status Draft Modified by Size Reservations Description JOGL Javadoc Info

kbr on Friday, June 1004.52 24, 2005 at 5:01:27 kB PM kbr on Friday, June 24, 2005 at 5:02:02 1.12 mB PM kbr on Friday, June 258.32 24, 2005 at 5:06:43 kB PM kbr on Friday, June 24, 2005 at 5:07:13 7.49 mB PM kbr on Friday, June 24, 2005 at 5:07:43 7.8 mB PM kbr on Friday, June 139.06 24, 2005 at 7:03:14 kB PM kbr on Friday, June 300.06 24, 2005 at 5:03:22 kB PM kbr on Friday, June 146.79 24, 2005 at 5:03:49 kB PM kbr on Friday, June 268.07 24, 2005 at 5:04:18 kB PM kbr on Friday, June 241.16 24, 2005 at 5:04:58 kB PM kbr on Friday, June 24, 2005 at 5:05:26 60.1 kB PM kbr on Friday, June 24, 2005 at 5:05:56 1.09 mB PM

jogl.jar

Draft

JOGL classes

Info

jogl-demos.jar

Draft

JOGL demo classes

Info

jogl-demos-data.jar Draft

JOGL demo data files

Info

jogl-demos-src.zip

Draft

JOGL demo source code Info JOGL demo utility classes JOGL native libraries for Linux/x86 JOGL native libraries for Mac OS X 10.3+

jogl-demos-util.jar jogl-nativeslinux.jar jogl-nativesmacosx.jar jogl-nativessolsparc.jar jogl-nativessolx86.jar jogl-nativeswin32.jar jogl-src.zip

Draft

Info

Draft

Info

Draft

Info

Draft

JOGL native libraries Info for Solaris/SPARC 2.8+ JOGL native libraries for Solaris/x86 2.9+ JOGL native libraries for Windows/x86 JOGL source code Info

Draft

Draft

Info

Draft

Info

Passos para a instalao (usando o Eclipse): 1) D download nos dois arquivos citados. 2) Copie o arquivo jogl.jar para o diretrio: C:\Programs Files\Java\j2re1.4.2_10\lib\ext 3) Utilizando o WinRAR (por exemplo), descomprima o arquivo jogl-natives-win32.jar (o resultado sero dois arquivos: jogl.dll e jogl_cg.dll e o diretorio META-INF. Copie estes arquivos para o diretrio: C:\Programs Files\Java\j2re1.4.2_10\bin OBS: O diretorio .../j2re1.4.2_10/... pode ser diferente conforme a verso do java. Voce pode verificar executando o Eclipse e verificando o campo JRE_System Library que aparece em qualquer dos projetos.

1.4 Exemplo: Criando a janela OpenGL


import java.awt.*; import java.awt.event.*; import net.java.games.jogl.*; public class canvas { /** * @param args */ public static void main(String[] args) { Frame frame = new Frame("Hello World"); GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); frame.add(canvas); frame.setSize(300, 300); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.show(); } }

1.5 Exemplo: Plotar um ponto na tela utilizando as bibliotecas do OpenGl


import java.awt.*; import java.awt.event.*; import net.java.games.jogl.*; public class ponto { public static void main(String[] args) { Frame frame = new Frame("Ponto"); GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); canvas.addGLEventListener( new JoglRender() ); frame.add(canvas); frame.setSize(300, 300); frame.setLocation(50,50); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); }

}); frame.setVisible(true); } static class JoglRender implements GLEventListener { public void init(GLDrawable drawable) { GLU glu = drawable.getGLU(); glu.gluOrtho2D(0,399,0,399); } public void display(GLDrawable drawable) { GL gl = drawable.getGL(); gl.glClearColor(1.0f,1.0f,1.0f,1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glColor3f(1.0f,0.0f,0.0f); gl.glBegin(GL.GL_POINTS); gl.glVertex2f(200.0f,200.0f); gl.glEnd(); gl.glFlush(); } public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} } }

Vamos comentar alguns comandos: Frame frame = new Frame("Ponto"); A classe Frame somente cria uma janela. Este um recurso do Java e fornecido pelo pacote java.awt
GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); Cria a rea de rendering do OpenGL no frame anteriormente criado. canvas.addGLEventListener( new JoglRender() ); Interrupo quando ocorre um evento no canvas do OpenGL frame.add(canvas); Adiciona o canvas do OpenGL no frame do java frame.setSize(300, 300); frame.setLocation(50,50); Define parmetros de inicializao do frame frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); Interrupo do frame do Java. Existem outras interrupes alm do windowClosing. static class JoglRender implements GLEventListener { public void init(GLDrawable drawable) {

Esta a funo ser executada sempre que a janela for criada.


GLU glu = drawable.getGLU(); glu.gluOrtho2D(0,399,0,399);

Este comando estabelece a escala da tela. Sua sintaxe : gluOrtho2D(GLdouble left, Gldouble right, Gldouble bottom, Gldouble top);
} public void display(GLDrawable drawable) {

Esta a funo ser executada sempre que a janela necessita ser redesenhada.
GL gl = drawable.getGL();

gl.glClearColor(1.0f,1.0f,1.0f,1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glColor3f(1.0f,0.0f,0.0f); gl.glBegin(GL.GL_POINTS); gl.glVertex2f(200.0f,200.0f); gl.glEnd(); gl.glFlush(); }

Quando a funo display executada temos o seguinte resultado:


gl.glClearColor(1.0f,1.0f,1.0f,1.0f);

Indica cor para ser utilizada no fundo da tela.


gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

Pinta os buffers indicados com a cor do glClearColor() glColor3f(1.0,0.0,0.0); Define o vermelho como cor atual. glBegin(GL_POINTS); glVertex2f(200.0f,200f.0); glEnd(); Plota um ponto na posio (200,200) na tela. glFlush(); Imprime o contedo do buffer na tela.

public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} public void reshape(GLDrawable drawable, int x, int y, int width, int height) {}

Mtodos que no foram implementados e correspondem respectivamente as interrupes de alterao do display e mudana de dimenso da tela. Exerccios: 1) Acrescente um contador para verificar quantas vezes a funo display chamada. static class JoglRender implements GLEventListener { static int i = 0; public void init(GLDrawable drawable) { GLU glu = drawable.getGLU(); glu.gluOrtho2D(0,399,0,399); } public void display(GLDrawable drawable) { GL gl = drawable.getGL(); gl.glClearColor(1.0f,1.0f,1.0f,1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glColor3f(1.0f,0.0f,0.0f); gl.glPointSize(5.0f); gl.glBegin(GL.GL_POINTS); gl.glVertex2f(200.0f,200.0f); gl.glEnd(); gl.glFlush(); 8

System.out.println(i); i++;

public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} }

1.5 Comando: gluOrtho2D


Na maioria de nossas aplicaes desejamos nos referenciar a um ponto na tela, no por coordenadas correspondendo as dimenses informadas no comando frame.setSize(300, 300), mas sim levando-se em conta o domnio de visualizao relacionado ao problema. Para isso, o comando gluOrtho2D() realiza a mudana para o sistema de coordenadas desejado. Esta tarefa realizada fazendo a correspondncia entre os intervalos em questo:

Assim: e segue que e identicamente para a coordenada y: O programa abaixo ilustra o efeito do gluOrttho2D.
import java.awt.*; import java.awt.event.*; import net.java.games.jogl.*; public class ortho { public static void main(String[] args) { Frame frame = new Frame("Ortho"); GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); canvas.addGLEventListener( new JoglRender() ); frame.add(canvas); frame.setSize(300, 300); frame.setLocation(50,50); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); } static class JoglRender implements GLEventListener { public void init(GLDrawable drawable) { GLU glu = drawable.getGLU(); glu.gluOrtho2D(0,300,0,300); } public void display(GLDrawable drawable) { GL gl = drawable.getGL(); float x = -0.5f;

float float float float float

y L R T B

= 0.5f; = -1.0f; = 1.0f; = 1.0f; = -1.0f;

gl.glClearColor(1.0f,1.0f,1.0f,1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glColor3f(1.0f,0.0f,0.0f); gl.glPointSize(4.0f); float xo = float yo = ((x - L)/(R-L)*(299)); ((y - B)/(T-B)*(299));

gl.glBegin(GL.GL_POINTS); gl.glVertex2f(xo,yo); gl.glEnd(); gl.glFlush(); } public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} } }

1.6 Exemplo: Plotar uma reta unindo dois pontos


Como exemplo vamos desenhar uma reta (no vertical) unindo dois pontos (x0,y0) e (x1,y1). A equao da reta que passa por dois pontos :

1.6.1 Algoritmo ingnuo


A primeira idia de como resolver este problema proposto pelo programa abaixo. Este um exemplo ingnuo de como desenhar a reta que passa por dois pontos dados. Vamos discutir a seguir os principais problemas deste programa e as possveis solues. /* -------------------------------------------------------------- */ /* Exemplo ingnuo de como plotar a reta definida por dois pontos */ /* -------------------------------------------------------------- */ import java.awt.*; import java.awt.event.*; import net.java.games.jogl.*; public class reta { public static void main(String[] args) { Frame frame = new Frame("Reta"); GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); canvas.addGLEventListener( new JoglRender() ); frame.add(canvas); frame.setSize(300, 300); frame.setLocation(50,50);

10

frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); } static class JoglRender implements GLEventListener { public void init(GLDrawable drawable) { GLU glu = drawable.getGLU(); glu.gluOrtho2D(-3,3,-3,3); } public void display(GLDrawable drawable) { double y; GL gl = drawable.getGL(); gl.glClearColor(1.0f,1.0f,1.0f,1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glColor3f(1.0f,0.0f,0.0f); gl.glBegin(GL.GL_POINTS); for (double x = -3;x <= 3;x+=0.001) { y = 2*x - 1; gl.glVertex2f((float)x,(float)(y)); } gl.glEnd(); gl.glFlush(); } public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} } } Algumas desvantagens do programa proposto: 1) Este mtodo requer operaes em ponto flutuante (float ou double) para cada pixel. Isto acarreta em um algoritmo lento, se comparado a um algoritmo que opera somente com nmeros inteiros. Para o caso da reta, existe um tal algoritmo que utiliza somente aritmtica com nmeros inteiros. Este algoritmo foi desenvolvido por Jack E. Bresenham na dcada de 60 e ser descrito adiante. 2) O usurio estabelece o nmero de pontos da reta a serem plotados entre os dois pontos. Podem ocorrer dois casos: faltarem pontos (a reta fica pontilhada), sobrarem pontos (neste caso o algoritmo faz contas desnecessrias). O ideal o prprio programa se encarregar de determinar o nmero de pontos necessrios e suficientes para resolver o problema. 3) O caso particular da reta vertical (onde K constante) no pode ser plotado. Exerccio: Desenhe vrias retas preeenchendo a tela e teste a velocidade, como por exemplo: ... gl.glColor3f(1.0f,0.0f,0.0f); gl.glBegin(GL.GL_POINTS); for (double b = -10; b <= 10; b+=0.01) { for (double x = -3;x <= 3; x+=0.001) { y = 2*x + b;

11

gl.glVertex2f((float)x,(float)(y)); } } gl.glEnd(); gl.glFlush(); ...

1.6.2 Retas no Opengl


O OpenGL dispe em sua biblioteca interna de um comando que plota uma reta por dois pontos dados P0(x0,y0) e P1(x1,y1): gl.glBegin(GL.GL_LINES); gl.glVertex2f(x0, y0)); gl.glVertex2f(x1, y1); gl.glEnd(); Compare a velocidade com o exerccio anterior:: public void display(GLDrawable drawable) { GL gl = drawable.getGL(); gl.glClearColor(1.0f,1.0f,1.0f,1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glColor3f(1.0f,0.0f,0.0f); for (double b = -10; b<= 10;b+=0.01) { gl.glBegin(GL.GL_LINES); gl.glVertex2f(-3.0f,(float)(-6f+b)); gl.glVertex2f( 3.0f,(float)( 6f+b)); gl.glEnd(); } gl.glFlush(); }

1.7 Exemplo: Plotar o grfico de uma funo


Vamos comear com uma verso bem simplificada, para plotar o grfico de uma funo y=f(x). import java.awt.*; import java.awt.event.*; import net.java.games.jogl.*; public class funcao { public static void main(String[] args) {

12

Frame frame = new Frame("Funcao"); GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); canvas.addGLEventListener( new JoglRender() ); frame.add(canvas); frame.setSize(600, 600); frame.setLocation(50,50); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); } static class JoglRender implements GLEventListener { public void init(GLDrawable drawable) { GLU glu = drawable.getGLU(); glu.gluOrtho2D(-3,3,-3,3); } public void display(GLDrawable drawable) { double y; GL gl = drawable.getGL(); gl.glClearColor(0.0f,0.0f,0.0f,1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glColor3f(1.0f,0.0f,0.0f); gl.glBegin(GL.GL_POINTS); for (double x = -3; x<= 3;x+=0.01) { y = x*x; // Esta a funcao gl.glVertex2f((float)x,(float)(y)); } gl.glEnd(); gl.glFlush(); } public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} } } Vamos aprimorar nosso cdigo: 1) Acrescentando os eixos. 2) Criando uma varivel pontos que permita selecionar a discretizao. 3) Criar uma classe funcao que trate da definio da funo e das tarefas especficas de plotar o grfico da funo. main.java import java.awt.*; import java.awt.event.*; import net.java.games.jogl.*; public class main { static funcao f; 13

public static void main(String[] args) { Frame frame = new Frame("Funcao"); GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); canvas.addGLEventListener( new JoglRender() ); frame.add(canvas); frame.setSize(600, 600); frame.setLocation(50,50); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); } static class JoglRender implements GLEventListener { public void init(GLDrawable drawable) { f = new funcao(400,-3.0f,-3.0f,3.0f,3.0f); } public void display(GLDrawable drawable) { GL gl = drawable.getGL(); GLU glu = drawable.getGLU(); gl.glLoadIdentity(); glu.gluOrtho2D(f.get_xmin(),f.get_xmax(),f.get_ymin(),f.get_ymax()); gl.glClearColor(0.0f,0.0f,0.0f,1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glColor3f(1.0f,0.0f,0.0f); f.plota_eixo(drawable); f.plota_funcao(drawable); gl.glFlush(); } public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} } } /* * * * * * * * * * * * * * * */ /* Modulo: funcao.java */ /* * * * * * * * * * * * * * * */ import net.java.games.jogl.*; public class funcao { int pontos; float xmin,xmax,ymin,ymax; funcao() pontos xmin = xmax = } { = 300; ymin = -1; ymax = 1;

funcao(int p) { pontos = p; 14

xmin = ymin = -1; xmax = ymax = 1; } funcao(int p,float xm,float ym,float xM,float yM) { pontos = p; xmin = xm; ymin = ym; xmax = xM; ymax = yM; } public public public public float float float float get_xmin() get_ymin() get_xmax() get_ymax() { { { { return return return return xmin; ymin; xmax; ymax; } } } }

public float f(float x) { return (float) Math.sin((double)x); } public void plota_eixo(GLDrawable drawable) { GL gl = drawable.getGL(); gl.glColor3f (0.0f, 1.0f, 0.0f); gl.glBegin (GL.GL_LINES); gl.glVertex2f (xmin,0); gl.glVertex2f (xmax,0); gl.glVertex2f (0,ymin); gl.glVertex2f (0,ymax); gl.glEnd();

public void plota_funcao(GLDrawable drawable) { GL gl = drawable.getGL(); int i; float dx; float x, y; dx = (xmax - xmin)/pontos; gl.glColor3f (1.0f, 0.0f, 0.0f); x = xmin; for (i = 0; i < pontos; i++) { y = f(x); gl.glBegin (GL.GL_POINTS); gl.glVertex2f (x,y); gl.glEnd(); x = x + dx; }

} }

Nossa prxima etapa permitir que o usurio possa alterar o domnio de visualizao da funo interativamente. Na prxima sesso apresentamos algumas das principais interrupes usando o mouse que nos permitiro executar esta tarefa. Exerccio: Entre com o domnio atravs do teclado.

15

main.java
import java.awt.*; import java.awt.event.*; import net.java.games.jogl.*; public class main { static funcao f; public static void main(String[] args) { Frame frame = new Frame("Funcao"); GLCanvas canvas GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); canvas.addGLEventListener( new JoglRender() ); frame.add(canvas); frame.setSize(600, 600); frame.setLocation(50,50); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); } static class JoglRender implements GLEventListener { public void init(GLDrawable drawable) { GLU glu = drawable.getGLU(); GL gl = drawable.getGL(); f = new funcao(400); f.dominio(); gl.glLoadIdentity(); double a,b,c,d; a = (double)(f.get_xmin()); b = (double)(f.get_xmax()); c = (double)(f.get_ymin()); d = (double)(f.get_ymax()); glu.gluOrtho2D(a,b,c,d); } public void display(GLDrawable drawable) { GL gl = drawable.getGL(); gl.glClearColor(0.0f,0.0f,0.0f,1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT GL.GL_DEPTH_BUFFER_BIT); gl.glColor3f(1.0f,0.0f,0.0f); | =

gl.LoadIdentity(); glu.gluOrtho2D(f.get_xmin(),f.get_xmax(),f.get_ymin(),f.get_ymax());
f.plota_eixo(drawable); f.plota_funcao(drawable); gl.glFlush(); } public void displayChanged(GLDrawable modeChanged, boolean deviceChanged) {} drawable, boolean

public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} }

16

funcao.java
import net.java.games.jogl.*; public class funcao { int pontos; float xmin,xmax,ymin,ymax; funcao() { pontos = 300; xmin = ymin = -1; xmax = ymax = 1; } funcao(int pontos xmin = xmax = } funcao(int pontos xmin = ymin = xmax = ymax = } public public public public p) { = p; ymin = -1; ymax = 1; p,float xm,float ym,float xM,float yM) { = p; xm; ym; xM; yM; get_xmin() get_ymin() get_xmax() get_ymax() { { { { return return return return xmin; ymin; xmax; ymax; } } } }

float float float float

//

public float f(float x) { return x*x; return (float) Math.sin((double)x); } public void dominio() { System.out.print("xmin = "); xmin = TextIO.getFloat(); System.out.print("ymin = "); ymin = TextIO.getFloat(); System.out.print("xmax = "); xmax = TextIO.getFloat(); System.out.print("ymax = "); ymax = TextIO.getFloat(); } public void plota_eixo(GLDrawable drawable) { GL gl = drawable.getGL(); gl.glColor3f (0.0f, 1.0f, 0.0f); gl.glBegin (GL.GL_LINES); gl.glVertex2f (xmin,0); gl.glVertex2f (xmax,0); gl.glVertex2f (0,ymin); gl.glVertex2f (0,ymax); gl.glEnd(); } public void plota_funcao(GLDrawable drawable) { GL gl = drawable.getGL(); int i; float dx; float x, y;

17

dx = (xmax - xmin)/pontos; gl.glColor3f (1.0f, 0.0f, 0.0f); x = xmin; for (i = 0; i < pontos; i++) { y = f(x); gl.glBegin (GL.GL_POINTS); gl.glVertex2f (x,y); gl.glEnd(); x = x + dx; } } }

18

2 TECLADO E MOUSE (Callbacks)


2.1 Introduo
O usurio pode interagir com o programa de duas formas principais: atravs do Mouse ou Teclado. Para isso o Jogl dispe de dois tipos de funes (que denominamos Callbacks) especficas para habilitar a utilizao do teclado e do mouse. Vamos descrev-las a seguir.

2.2 Teclado
Para registrar ocorrncias no teclado o Jogl dispe da funo: canvas.addKeyListener ( new JoglKey() );

Esta funo determina que quando uma tecla for pressionada, o controle do programa deve passar a classe JoglKey que reimplementa trs mtodos: public void keyPressed (KeyEvent e) public void keyReleased(KeyEvent e) public void keyTyped (KeyEvent e) O exemplo abaixo exemplifica uma aplicao para o programa funes.

2.3 Exemplo: Utilizao do teclado no programa funes.


Como exemplo vamos acrescentar no programa funes a possibilidade de alterarmos o domnio da funo durante a execuo do programa. Assim podemos estabelecer que quando o usurio pressionar a tecla D ou d, o programa interrompe e solicita na janela de concole do Eclipse as novas informaes sobre o domnio da funo. A unica alterao ocorre no main. import java.awt.*; import java.awt.event.*; import net.java.games.jogl.*; public class main { public static void main(String[] args) { Frame frame = new Frame("Funcao"); GLCanvas canvas GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); canvas.addGLEventListener( new JoglRender() ); canvas.addKeyListener ( new JoglKey() ); frame.add(canvas); frame.setSize(600, 600); frame.setLocation(50,50); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); } static funcao f; static class JoglRender implements GLEventListener public void init(GLDrawable drawable) { f = new funcao(400); f.dominio(); } 19 { =

public void display(GLDrawable drawable) { GL gl = drawable.getGL(); GLU glu = drawable.getGLU(); gl.glClearColor(0.0f,0.0f,0.0f,1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glColor3f(1.0f,0.0f,0.0f); gl.glLoadIdentity(); glu.gluOrtho2D(f.get_xmin(),f.get_xmax(),f.get_ymin(),f.get_ymax()); f.plota_eixo(drawable); f.plota_funcao(drawable); gl.glFlush(); } public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} } static class JoglKey implements KeyListener {

public void keyPressed (KeyEvent e) { if (e.getKeyChar() == 'd' || e.getKeyChar() == 'D') f.dominio(); } public void keyReleased(KeyEvent e) {} public void keyTyped (KeyEvent e) { } } }

20

2.4 Mouse
O Jogl capaz de obter trs tipos de ocorrncias diferentes a partir do mouse. Vamos descrev-las em seguida e discutir uma interessante aplicao para o estudo de grficos de funes.

2.4.1- Interrupes a partir do mouse

a) MouseListener
Este evento contm cinco mtodos bsicos de controle do mouse: void mouseClicked(MouseEvent e) Registra quando um boto for pressionado e solto. void mouseEntered(MouseEvent e) Registra quando o mouse entra no componente. void mouseExited(MouseEvent e) Registra quando o mouse sai do componente. void mousePressed(MouseEvent e) Registra quando um boto do mouse pressionado. void mouseReleased(MouseEvent e) Registra quando o boto do mouse solto sobre o componente. Para testar qual boto foi pressionado: Primeiro boto: e.getButton() == 1 Segundo boto: e.getButton() == 2 Terceiro boto: e.getButton() == 3 Como exemplo, vamos alterar o programa funo anterior, e acrescentar outra forma de interrupo para alterar o domnio. Assim se o usurio pressionar o boto direito do mouse, o programa solicita no console o novo domnio de visualizao. Se pressionar o boto esquerdo, o programa informa em qual coordenada da tela o mouse se encontra. Para implementar esta alterao s precisamos mudar o programa main.java. Seu novo cdigo apresentado a seguir: main.java import java.awt.*; import java.awt.event.*; import net.java.games.jogl.*; public class main { static funcao f; public static void main(String[] args) { Frame frame = new Frame("Funcao"); GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); canvas.addGLEventListener( new JoglRender() ); canvas.addKeyListener ( new JoglKey() ); canvas.addMouseListener ( new JoglMouse() ); frame.add(canvas); frame.setSize(600, 600); frame.setLocation(50,50);

21

frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); } static class JoglRender implements GLEventListener { public void init(GLDrawable drawable) { f = new funcao(400,-1,-1,1,1); } public void display(GLDrawable drawable) { GL gl = drawable.getGL(); GLU glu = drawable.getGLU(); gl.glLoadIdentity(); glu.gluOrtho2D(f.get_xmin(),f.get_xmax(), f.get_ymin(),f.get_ymax()); gl.glClearColor(0.0f,0.0f,0.0f,1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glColor3f(1.0f,0.0f,0.0f); f.plota_eixo(drawable); f.plota_funcao(drawable); gl.glFlush(); } public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} } static class JoglKey implements KeyListener {

public void keyPressed (KeyEvent e) { if (e.getKeyChar() == 'd' || e.getKeyChar() == 'D') f.dominio(); System.out.println("Pressed"); } public void keyReleased(KeyEvent e) { System.out.println("Released"); } public void keyTyped (KeyEvent e) { System.out.println("Typed"); } }

static class JoglMouse implements

MouseListener { 22

public void mouseEntered(MouseEvent e) { System.out.println("Mouse Entra"); } public void mouseExited (MouseEvent e) { System.out.println("Mouse Sai"); } public void mousePressed(MouseEvent e) { if (e.getButton()==3) { f.dominio(); } } public void mouseReleased(MouseEvent e) { if (e.getButton()==1) { System.out.print("x = "); System.out.print(e.getX()); System.out.print(" y = "); System.out.println(e.getY()); } } public void mouseClicked(MouseEvent e) { System.out.println("Mouse botao"); }

} }

b) MouseMotionListener
Este evento detecta o movimento do mouse em dois casos: void mouseDragged(MouseEvent e) Quando o boto do mouse est pressionado e em movimento sobre a componente. void mouseMoved(MouseEvent e) Quando o mouse movimentado sobre a componente.

c) MouseWheelListener
void mouseWheelMoved(MouseWheelEvent e)

main.java

import java.awt.*; import java.awt.event.*; import net.java.games.jogl.*; public class main { static funcao f; /** Main Class **/

23

public static void main(String[] args) { Frame frame = new Frame("Funcao"); GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); canvas.addGLEventListener( new JoglRender() ); canvas.addKeyListener ( new JoglKey() ); canvas.addMouseListener( new JoglMouse() ); canvas.addMouseMotionListener( new JoglMouseMotion() ); canvas.addMouseWheelListener( new JoglMouseWheel() ); frame.add(canvas); frame.setSize(600, 600); frame.setLocation(50,50); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); } /** OpenGL Eventos **/ static class JoglRender implements GLEventListener { public void init(GLDrawable drawable) { f = new funcao(400,-1,-1,1,1); } public void display(GLDrawable drawable) { GL gl = drawable.getGL(); GLU glu = drawable.getGLU(); gl.glLoadIdentity(); glu.gluOrtho2D(f.get_xmin(),f.get_xmax(),f.get_ymin(),f.get_ymax()); gl.glClearColor(0.0f,0.0f,0.0f,1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glColor3f(1.0f,0.0f,0.0f); f.plota_eixo(drawable); f.plota_funcao(drawable); gl.glFlush(); } public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} } /** Teclado Eventos static class JoglKey implements **/ KeyListener {

public void keyPressed (KeyEvent e) { if (e.getKeyChar() == 'd' || e.getKeyChar() == 'D') f.dominio();

24

System.out.println("Pressed"); } public void keyReleased(KeyEvent e) { System.out.println("Released"); } public void keyTyped (KeyEvent e) { System.out.println("Typed"); } } /** Mouse Eventos **/ static class JoglMouse implements MouseListener { public void mouseEntered(MouseEvent e) { System.out.println("Mouse Entra"); } public void mouseExited (MouseEvent e) { System.out.println("Mouse Sai"); } public void mousePressed(MouseEvent e) { if (e.getButton()==2) { f.dominio(); } } public void mouseReleased(MouseEvent e) { if (e.getButton()==3) { System.out.print("x = "); System.out.print(e.getX()); System.out.print(" y = "); System.out.println(e.getY()); } } public void mouseClicked(MouseEvent e) { System.out.println("Mouse botao"); } } /** Movimento do Mouse Eventos static class JoglMouseMotion implements **/ MouseMotionListener {

public void mouseDragged(MouseEvent e) { System.out.println("Dragged: " + e.getX() + "," + e.getY()); } public void mouseMoved(MouseEvent e) { System.out.println("Moved: " + e.getX() + "," + e.getY()); } }

/**

Mouse Eventos

**/

25

static class JoglMouseWheel implements

MouseWheelListener {

public void mouseWheelMoved(MouseWheelEvent e) { System.out.println("Wheel Moved: " + e.getX() + "," + e.getY()); } } }

2.4.2- Aplicaes: Realizando o zoom do grfico


Verso Inicial No processo de visualizao das funes, ou mesmo da integrao numrica, muitas vezes desejamos alterar o domnio do nosso grfico. Para isso selecionamos a tecla D e d como uma interrupo do teclado para que pudssemos informar o novo domnio. Uma forma mais gil seria selecionar com o mouse interativamente um retngulo que gostaramos de visualizar. o que faremos no prximo programa. Para isso utilizaremos as interrupes do mouse para selecionarmos a regio desejada. Quando o boto direito do mouse pressionado, marcamos o ponto inicial da regio. Enquanto o mouse est em movimento (com o boto direito pressionado), desenhamos o retngulo desejado. Quando o boto do mouse solto, obtemos o ponto final da regio e atualizamos o domnio da funo. Observe que as coordenadas obtidas pelo eventos do mouse precisam ser convertidas para o sistema de coordendas indicado nos parmetros do gluOrtho2D. Para isso, basta considerarmos a transformao inversa a aplicada na seo 1.5: e segue que e identicamente para a coordenada y. main.java
import java.awt.*; import java.awt.event.*; import net.java.games.jogl.*; public class main { static funcao f; static int mov = 0; /* Detecta movimento do mouse */ static int xv1, yv1, xv2, yv2; /* Domnio da nova janela */ static GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); public static void main(String[] args) { Frame frame = new Frame("Funcao"); canvas.addGLEventListener( new JoglRender() ); canvas.addMouseListener( new JoglMouse() ); canvas.addMouseMotionListener( new JoglMouseMotion() ); frame.add(canvas); frame.setSize(600, 600); frame.setLocation(50,50); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); }

26

}); frame.setVisible(true); } static class JoglRender implements GLEventListener { public void init(GLDrawable drawable) { f = new funcao(400,-1,-1,1,1); } public void display(GLDrawable drawable) { GL gl = drawable.getGL(); GLU glu = drawable.getGLU(); gl.glLoadIdentity(); glu.gluOrtho2D(f.get_xmin(),f.get_xmax(),f.get_ymin(),f.get_ymax()); gl.glClearColor(0.0f,0.0f,0.0f,1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glColor3f(1.0f,0.0f,0.0f); if (mov == 1) { System.out.println("mov = 1"); f.plota_retangulo (drawable, xv1,yv1,xv2,yv2); } f.plota_eixo(drawable); f.plota_funcao(drawable); gl.glFlush(); } public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) { } public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} } static class JoglMouse implements MouseListener { public void mouseEntered(MouseEvent e) { // System.out.println("Mouse Entra"); } public void mouseExited (MouseEvent e) { // System.out.println("Mouse Sai"); } public void mousePressed(MouseEvent e) { if (e.getButton()==3) { System.out.println("Entra"); xv1 = e.getX(); yv1 = e.getY(); mov = 1; } } public void mouseReleased(MouseEvent e) { if (e.getButton()==3) { System.out.println("Sai"); xv2 = e.getX(); yv2 = e.getY(); mov = 0; f.recalcula_dominio (xv1,yv1,xv2,yv2); canvas.display(); } } public void mouseClicked(MouseEvent e) { System.out.println("Mouse botao");

27

} } static class JoglMouseMotion implements MouseMotionListener {

public void mouseDragged(MouseEvent e) { if ((e.getModifiers() & InputEvent.BUTTON3_MASK) != 0) { xv2 = e.getX(); yv2 = e.getY(); System.out.println("Dragged: " + e.getX() + "," + e.getY()); canvas.display(); } } // } } public void mouseMoved(MouseEvent e) { System.out.println("Moved: " + e.getX() + "," + e.getY()); }

funcao.java import net.java.games.jogl.*; public class funcao { int pontos; float xmin,xmax,ymin,ymax; funcao() { pontos = 300; xmin = ymin = -1; xmax = ymax = 1; } funcao(int pontos xmin = xmax = } funcao(int pontos xmin = ymin = xmax = ymax = } public public public public p) { = p; ymin = -1; ymax = 1; p,float xm,float ym,float xM,float yM) { = p; xm; ym; xM; yM; get_xmin() get_ymin() get_xmax() get_ymax() { { { { return return return return xmin; ymin; xmax; ymax; } } } }

float float float float

//

public float f(float x) { return x*x; return (float) Math.sin((double)x); } public void dominio() { System.out.print("xmin = ");

28

xmin = TextIO.getFloat(); System.out.print("ymin = "); ymin = TextIO.getFloat(); System.out.print("xmax = "); xmax = TextIO.getFloat(); System.out.print("ymax = "); ymax = TextIO.getFloat(); } public float converte(float p, float min, float max, int dim) { float x; x = min + ( (p * (max-min))/(dim - 1) ); return (x); } public xv_2,float yv_2) { void recalcula_dominio (float xv_1,float yv_1,float

float xmin1,xmax1; float ymin1,ymax1; xmin1 = converte(xv_1,xmin,xmax,600); xmax1 = converte(xv_2,xmin,xmax,600); xmin = xmin1; xmax = xmax1; ymin1 = converte(yv_2,ymax,ymin,600); ymax1 = converte(yv_1,ymax,ymin,600); ymin = ymin1; ymax = ymax1; } public void plota_eixo(GLDrawable drawable) { GL gl = drawable.getGL(); gl.glColor3f (0.0f, 1.0f, 0.0f); gl.glBegin (GL.GL_LINES); gl.glVertex2f (xmin,0); gl.glVertex2f (xmax,0); gl.glVertex2f (0,ymin); gl.glVertex2f (0,ymax); gl.glEnd(); } public void plota_funcao(GLDrawable drawable) { GL gl = drawable.getGL(); int i; float dx; float x, y; dx = (xmax - xmin)/pontos; System.out.print(xmax + " " + xmin); gl.glColor3f (1.0f, 0.0f, 0.0f); x = xmin; for (i = 0; i < pontos; i++) { y = f(x); gl.glBegin (GL.GL_POINTS); gl.glVertex2f (x,y); gl.glEnd(); x = x + dx; } } public void plota_retangulo (GLDrawable drawable, int x1, int y1, int x2, int y2) { GL gl = drawable.getGL();

29

float retxmin,retxmax,retymin,retymax; retxmin retxmax retymin retymax = = = = converte converte converte converte (x2,xmin,xmax,600); (x1,xmin,xmax,600); (y1,ymax,ymin,600); (y2,ymax,ymin,600);

gl.glColor3f(1.0f,1.0f,1.0f); gl.glBegin(GL.GL_LINE_LOOP); gl.glVertex2f(retxmin,retymin); gl.glVertex2f(retxmin,retymax); gl.glVertex2f(retxmax,retymax); gl.glVertex2f(retxmax,retymin); gl.glEnd(); }

Verso Pilha Em uma segunda verso gostariamos de voltarmos ao domnio original. Para isso, precisamos armazenar as alteraes anteriores do domnio. Uma estrutura adequada para esta situao seria montar uma pilha. O Java j dispes desta estrutura, porm podemos montar uma verso ilustrativa da Classe Pilha. Tambm vamos criar uma classe Window que armazena o domnio de visualizao da janela. Windows.java public class Window { float xmin; float xmax; float ymin; float ymax; Window(float xm,float ym,float xM,float yM) { xmin = xm; ymin = ym; xmax = xM; ymax = yM; } float get_xmin() return xmin; } float get_ymin() return ymin; } float get_xmax() return xmax; } float get_ymax() return ymax; } { { { {

Pilha.java public class Pilha { private No topo; 30

private static class No { private Window a ; private No prox; } public void push(Window a) { No novo_topo = new No(); novo_topo.a = a; novo_topo.prox = topo; topo = novo_topo; } public Window pop() { if (Vazia()) throw new RuntimeException("Pilha Vazia"); Window a = topo.a; topo = topo.prox; return a; } public boolean Vazia() { if (topo == null) return (true); else return(false); } } Na classe funcao.java precisamos agora armazenar a cada mudana de janela, o novo dominio. Tambem precisamos inserir um novo metodo que retorna o dominio anterior. funcao.java ... public void recalcula_dominio (float xv_1,float yv_1, float xv_2,float yv_2) { float xmin1,xmax1; float ymin1,ymax1; Window W = new Window(xmin,ymin,xmax,ymax); xmin1 = converte(xv_1,xmin,xmax,600); xmax1 = converte(xv_2,xmin,xmax,600); ymin1 = converte(yv_2,ymax,ymin,600); ymax1 = converte(yv_1,ymax,ymin,600); w.push(W); xmin = xmin1; xmax = xmax1; ymin = ymin1; ymax = ymax1; } public void retorna_dominio () { Window W = w.pop(); xmin = W.get_xmin(); xmax = W.get_xmax(); ymin = W.get_ymin(); ymax = W.get_ymax();

} ...

main.java

31

public void mouseReleased(MouseEvent e) { if (e.getButton()==3) { System.out.println("Sai"); xv2 = e.getX(); yv2 = e.getY(); mov = 0; f.recalcula_dominio (xv1,yv1,xv2,yv2); canvas.display(); } if (e.getButton()==1) { System.out.println("Volta Zoom"); f.retorna_dominio(); canvas.display();

} }

3 CURVAS PARAMTRICAS
3.1 Introduo
Considere uma curva C representando a trajetria de uma partcula P, de tal forma que a posio P(x,y) da partcula conhecida em cada instante de tempo t. Assim as coordenadas x e y so conhecidas como funes da varivel t de modo que: x = x(t) y = y(t) Estas so as equaes paramtricas da curva C e t denominado parmetro. Como exemplo de curvas temos: a) Circunferncia de centro na origem e raio 1: x = cos(t) y = sen(t) onde 0 <= t <= 2*Pi

b) Ciclide (curva traada por um ponto da circunferncia quando o crculo rola sobre uma reta): x = t - sen(t) y = 1 - cos(t)

3.2 Exemplo: Visualizao de Curvas Paramtricas


Vamos implementar um programa que visualize curvas paramtricas. Observe que a diferena principal para o programa funes que tanto a varivel x, quanto y devem ser calculadas em funo do parmetro t. Vamos aproveitar uma boa parte da estrutura j implementada no programa funo.

3.2.1 Mdulo main.java


Este mdulo idntico ao mdulo main.java. A nica diferena que as chamadas so feitas para as novas funes de desenho das curvas. import java.awt.*; import java.awt.event.*; import net.java.games.jogl.*; public class main { static curva c;

32

static int mov = 0; mouse */ static int xv1, yv1, xv2, yv2; */

/* Detecta movimento do /* Domnio da nova janela

static GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); public static void main(String[] args) { Frame frame = new Frame("Funcao"); canvas.addGLEventListener( new JoglRender() ); canvas.addMouseListener( new JoglMouse() ); canvas.addMouseMotionListener( new JoglMouseMotion() ); frame.add(canvas); frame.setSize(600, 600); frame.setLocation(50,50); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); } static class JoglRender implements GLEventListener { public void init(GLDrawable drawable) { c = new curva(400,-3.0f,3.0f,3.0f,3.0f,0.0f,(float)(2*Math.PI)); } public void display(GLDrawable drawable) { GL gl = drawable.getGL(); GLU glu = drawable.getGLU(); gl.glLoadIdentity(); glu.gluOrtho2D(c.get_xmin(),c.get_xmax(),c.get_ymin(),c.get_ymax()) ; gl.glClearColor(0.0f,0.0f,0.0f,1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glColor3f(1.0f,0.0f,0.0f); if (mov == 1) { System.out.println("mov = 1"); c.plota_retangulo (drawable, xv1,yv1,xv2,yv2); } c.plota_eixo(drawable); c.plota_funcao(drawable); gl.glFlush(); } public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) { }

33

public void reshape(GLDrawable drawable, int x, int y, int width, int height) { } } static class JoglMouse implements MouseListener { public void mouseEntered(MouseEvent e) { // System.out.println("Mouse Entra"); } public void mouseExited (MouseEvent e) { // System.out.println("Mouse Sai"); } public void mousePressed(MouseEvent e) { if (e.getButton()==3) { System.out.println("Entra"); xv1 = e.getX(); yv1 = e.getY(); mov = 1; } } public void mouseReleased(MouseEvent e) { if (e.getButton()==3) { System.out.println("Sai"); xv2 = e.getX(); yv2 = e.getY(); mov = 0; c.recalcula_dominio (xv1,yv1,xv2,yv2); canvas.display(); } } public void mouseClicked(MouseEvent e) { System.out.println("Mouse botao"); } } static class JoglMouseMotion implements { public void mouseDragged(MouseEvent e) { if ((e.getModifiers() & InputEvent.BUTTON3_MASK) != 0) { xv2 = e.getX(); yv2 = e.getY(); System.out.println("Dragged: " + e.getX() + "," + e.getY()); canvas.display(); } } MouseMotionListener

34

// e.getY()); } }

public void mouseMoved(MouseEvent e) { System.out.println("Moved: " + e.getX() + "," + }

3.2.2 Mdulo curva


Neste mdulo implementamos a classe curva.

import net.java.games.jogl.*; public class curva { int pontos; float xmin,xmax,ymin,ymax; float tmax,tmin; curva() { pontos xmin = xmax = tmin = tmax = } curva(int pontos xmin = xmax = tmin = tmax = } curva(int pontos xmin = ymin = xmax = ymax = tmin = tmax = } = 300; ymin = -1; ymax = 1; 0.0f; 1.0f; p) { = p; ymin = -1; ymax = 1; 0.0f; 1.0f; p,float xm,float ym,float xM,float yM) { = p; xm; ym; xM; yM; 0.0f; 1.0f;

curva(int p,float xm,float ym,float xM,float yM,float tm,float tM) { pontos = p; xmin = xm; ymin = ym; xmax = xM; ymax = yM; tmin = tm; tmax = tM; } public float get_xmin() { return xmin; } public float get_ymin() { return ymin; } public float get_xmax() { return xmax; } public float get_ymax() { return ymax; }

35

public float[] c(float t) { float [] v = new float[2]; v[0] = (float)Math.sin(t); v[1] = (float)Math.cos(t); return v; } public void dominio() { System.out.print("xmin = "); xmin = TextIO.getFloat(); System.out.print("ymin = "); ymin = TextIO.getFloat(); System.out.print("xmax = "); xmax = TextIO.getFloat(); System.out.print("ymax = "); ymax = TextIO.getFloat(); } public float converte(float p, float min, float max, int dim) { float x; x = min + ( (p * (max-min))/(dim - 1) ); return (x); } public void recalcula_dominio (float xv_1,float yv_1,float xv_2,float yv_2) { float xmin1,xmax1; float ymin1,ymax1; xmin1 = converte(xv_1,xmin,xmax,600); xmax1 = converte(xv_2,xmin,xmax,600); xmin = xmin1; xmax = xmax1; ymin1 = converte(yv_2,ymax,ymin,600); ymax1 = converte(yv_1,ymax,ymin,600); ymin = ymin1; ymax = ymax1; } public void plota_eixo(GLDrawable drawable) { GL gl = drawable.getGL(); gl.glColor3f (0.0f, 1.0f, 0.0f); gl.glBegin (GL.GL_LINES); gl.glVertex2f (xmin,0); gl.glVertex2f (xmax,0); gl.glVertex2f (0,ymin); gl.glVertex2f (0,ymax); gl.glEnd(); } public void plota_funcao(GLDrawable drawable) { GL gl = drawable.getGL(); int i; float t,dt; float[] v;

36

dt = (tmax - tmin)/pontos; gl.glColor3f (1.0f, 0.0f, 0.0f); t = tmin; for (i = 0; i < pontos; i++) { v = c(t); gl.glBegin (GL.GL_POINTS); gl.glVertex2f (v[0],v[1]); gl.glEnd(); t = t + dt; } } public void plota_retangulo (GLDrawable drawable, int x1, int y1, int x2, int y2) { GL gl = drawable.getGL(); float retxmin,retxmax,retymin,retymax; retxmin retxmax retymin retymax = = = = converte converte converte converte (x2,xmin,xmax,600); (x1,xmin,xmax,600); (y1,ymax,ymin,600); (y2,ymax,ymin,600);

gl.glColor3f(1.0f,1.0f,1.0f); gl.glBegin(GL.GL_LINE_LOOP); gl.glVertex2f(retxmin,retymin); gl.glVertex2f(retxmin,retymax); gl.glVertex2f(retxmax,retymax); gl.glVertex2f(retxmax,retymin); gl.glEnd(); } }

3.2.4 Exerccio
Como exerccio implemente: 1) Curva ciclide (t assume qualquer valor real). 2) x(t) = 3*t*t, y(t)=4*t*t*t (t assume qualquer valor real). 3) x(t) = cos(2*t), y(t)= sin(2*t) (0 <= t <= 2*PI) (Qual a diferena para a curva do programa ?) 4) x(t) = cos(t), y(t)= sin(2*t) 5) x(t) = 2 * cos(t), y(t)= 3 * sin(t) (0 <= t <= 2*PI) . 6) Como voc poderia visualizar grficos de funes em uma varivel y = f(x) com este programa ? Visualize y=x*x, y = sin(x), y = ln(x).

3.3 Curvas na forma Polar


Para formar as coordenadas polares considere um ponto fixo O, denominado origem (ou polo) e um eixo partindo de O, denominado eixo polar. A cada ponto P do plano podemos associar uma par de coordenadas polares (r,theta) onde: r: theta: . distncia orientada da origem ao ponto P. ngulo entre o eixo polar e o segmento OP.

37

As coordenadas polares podem ser relacionadas com as coordenadas retangulares (ou cartesianas) atravs das expresses abaixo:

Como exemplo de curvas na forma polar temos: a) Circunferncia de centro na origem e raio 1: r = 1 b) Reta passando na origem com coeficiente angular m:

c) Circunferncia com centro em P(0, 0.5) e raio 1:

d) Cardiide

e) Espiral

f) Roscea

3.4 Exemplo: Visualizao de Curvas Polares


Para visualizar as curvas polares, podemos utilizar o mesmo programa das curvas paramtricas. Para isso, considere uma curva dada na forma polar:

Em coordenadas cartesianas temos:

Substituindo r nas duas equaes obtemos:

Assim temos uma curva na forma paramtrica. Como exemplo vamos visualizar a curva do cardiide, alterando apenas a rotina curva do programa anterior: 38

public float[] c(float t) { float [] v = new float[2]; v[0] = (float) ((1 + Math.cos(t)) * Math.cos(t) ); v[1] = (float) ((1 + Math.cos(t)) * Math.sin(t) ); return v; }

3.5 Exerccios
1) Como exerccio visualize as demais curvas dadas em coordenadas polares. 2) Visualize a curva dada em coordenadas polares por r = sec(theta).

39

4 CURVAS IMPLCITAS
4.1 Introduo
J aprendemos na seo 3 como representar curvas na forma paramtrica. Vamos discutir agora outro tipo de representao muito utilizada para curvas: a representao implcita. A equao implcita de uma curva descreve uma relao entre as coordenadas x e y dos pontos que pertencem a curva. Assim no plano xy a equao implcita de uma curva tem a forma : Como exemplo a representao implcita de uma circunferncia de raio 1 centrado na origem dado por: Na forma paramtrica a mesma curva representada por:

Qual das duas representaes mais vantajosa em termos computacionais ? Na verdade ambas representaes tm vantagens e desvantagens em comparao uma com a outra. Por exemplo, muito simples determinar se um ponto dado pertence ou no a uma curva dada na forma implcita. J na forma paramtrica simples determinar pontos que pertenam a curva, para que se possa fazer uma representao grfica da curva (como foi feito na seo anterior). Vamos agora resolver este ltimo problema para uma curva dada na forma implcita, ou seja, vamos representar graficamente a curva implcita.

4.2 Visualizao de Curvas Implcitas


Vamos implementar um programa que visualize curvas implcitas. Partindo por exemplo da equao:

Observe que no simples exibir um conjunto de pontos que pertenam a esta curva. Vamos definir uma funo de duas variveis utilizando a equao acima, da seguinte forma:

Assim a curva inicial desejada, ser a curva de nvel A estratgia para obter esta curva ser a seguinte: - Vamos estabelecer um domnio existem ou no pontos da curva nesse domnio). -

. no plano como partida (a priori no sabemos se

Em seguida discretizamos este domnio, determinando uma matriz de 10x10 pontos por exemplo.

A cada trs pontos, definimos um tringulo como na figura abaixo. Para cada ponto calculamos = sinal( . ) obtidos em cada vrtice e temos as

Para cada tringulo, observamos os sinais seguintes situaes: -

Se V1 * V2 < 0, ento a funo se anula em um ponto entre V1 e V2. Este ponto pode ser aproximado linearmente. Se V1 * V3 < 0, ento a funo se anula em um ponto entre V1 e V3.

40

Se V2 * V3 < 0, ento a funo se anula em um ponto entre V2 e V3. Se V1 = 0, ento a funo se anula exatamente sobre o vrtice V1. Se V2 = 0, ento a funo se anula exatamente sobre o vrtice V2. Se V3 = 0, ento a funo se anula exatamente sobre o vrtice V3.

Considerando que exatamente duas das condies acima se verificaram simultaneamente, aproximamos a curva nesse tringulo por um segmento de reta unindo os dois pontos obtidos.

4.3 Programa Curva Implcita


O programa mantm a mesma estrutura do programa curva paramtrica, alterando a classe curva, conforme abaixo. implicito.java import net.java.games.jogl.*; public class Curva {

public float f(float x,float y) { return x*x-y*y-1; // return x*x+y*y-1; } public void curva_implicita(GLDrawable drawable, float[] xf,float[] yf) { GL gl = drawable.getGL(); int j; int i = 0; float t; float[] x = new float[3]; float[] y = new float[3]; float[] s = new float[3]; gl.glColor3f(0,0,1); gl.glBegin(GL.GL_LINE_LOOP); gl.glVertex2f(xf[0],yf[0]); gl.glVertex2f(xf[1],yf[1]); gl.glVertex2f(xf[2],yf[2]); gl.glEnd(); for(j=0;j<3;j++) s[j] = f(xf[j],yf[j]); if ((s[0] * s[1]) < 0) { t = -s[0]/(s[1]-s[0]); x[i] = xf[0] + t * (xf[1]-xf[0]); y[i] = yf[0]; i++; ((s[0] * s[2]) < 0) { t = -s[0]/(s[2]-s[0]); x[i] = xf[0] ; y[i] = yf[0] + t * (yf[2]-yf[0]); i++; 41

} if

} if

((s[1] * s[2]) < 0) { t = -s[1]/(s[2]-s[1]); x[i] = xf[1] + t * (xf[2]-xf[1]); y[i] = yf[1] + t * (yf[2]-yf[1]); i++;

} for(j=0;j<3;j++) { if (s[j] == 0) { x[i] = xf[j]; y[i] = yf[j]; i++; } } if (i == 2) { gl.glLineWidth(2.0f); gl.glColor3f(1.0f,0.0f,0.0f); gl.glBegin(GL.GL_LINES); gl.glVertex2f(x[0],y[0]); gl.glVertex2f(x[1],y[1]); gl.glEnd(); gl.glLineWidth(1.0f);

} } public void plota_curva(GLDrawable drawable) { GL gl = drawable.getGL(); int i,j; float[] tx float[] ty float x,y; float dx = float dy = = new float[3]; = new float[3]; (xmax - xmin)/pontos; (ymax - ymin)/pontos;

gl.glColor3f(1.0f,0.0f,0.0f); x = xmin; for(i=0;i<pontos;i++) { y = ymin; for(j=0;j<pontos;j++) { tx[0] = x; tx[1] = x + dx; tx[2] = x; ty[0] = y; ty[1] = y; ty[2] = y + dy; curva_implicita(drawable,tx,ty); tx[0] = x + dx; tx[1] = x; tx[2] = x + dx; ty[0] = y + dy; ty[1] = y + dy; ty[2] = y; curva_implicita(drawable,tx,ty); y += dy; } x += dx; } }

4.4 Exerccio
1) Como exerccio implemente as seguintes curvas implcitas:

42

a) b) .

. c) d)

2) Implemente no programa uma rotina que imprima simultaneamente varias curvas de nivel de uma mesma funo , ou seja . Por exemplo, .

5 RETAS E POLGONOS NO OPENGL


5.1 Retas e Polgonos
Alm de pontos e retas, o OpenGL possui no total 10 tipos de primitivas teis. Todos os modelos da tabela abaixo devem ser utilizados iniciando com .gl.glBegin(...) e finalizando com gl.glEnd(...), por exemplo para o GL_LINES temos: gl.glBegin(GL_LINES); gl.glVertex2f(1.0,1.0); gl.glVertex2f(1.0,2.0); gl.glVertex2f(2.0,-2.0); ... gl.glEnd(); GL.GL_POINTS GL.GL_LINES GL.GL_POLYGON GL.GL_TRIANGLES GL.GL_QUADS GL.GL_LINE_STRIP GL.GL_LINE_LOOP GL.GL_TRIANGLE_STRIP GL.GL_TRIANGLE_FAN GL.GL_QUAD_STRIP Pontos individuais. Reta entre dois pontos. Polgono convexo . Tripla de vrtices interpretado como um tringulo. Conjunto de quatro vrtices interpretado como quadriltero. Sequncia de retas. Idntico ao anterior, porm com uma reta unindo o primeiro e ltimo vrtice. Lista de tringulos. Lista de tringulos com o primeiro vrtice em comum. Lista de quadrilteros.

43

5.2 Exemplo: Visualizao dos Mtodos Numricos de Integrao


Como exemplo de aplicao dos novos objetos vamos visualizar alguns mtodos numricos de integrao apresentados no capitulo 1. Class Integral.java import net.java.games.jogl.GL; import net.java.games.jogl.GLDrawable; public class Integral { float float funcao int int int a; b; f; particao; visual; metodo; // // // //

0 1 2 3

ponto a esquerda trapezio Simpson Monte Carlo

public Integral (float xi,float xf,int part, int met,funcao func) { a = xi; b = xf; particao = part; metodo = met ; f = func; visual = 1; } public void { GL int float float Integral_esquerda(GLDrawable drawable) gl = drawable.getGL(); i ; x,y; dx;

dx = (b-a)/particao; x = a; for(i=0; i < particao; i++) { y = f.f(x); gl.glColor3f(1.0f,1.0f,0.0f); if (visual == 0) gl.glBegin(GL.GL_LINE_LOOP); 44

else gl.glBegin(GL.GL_POLYGON); gl.glVertex2f(x,y); gl.glVertex2f(x+dx,y); gl.glVertex2f(x+dx,0); gl.glVertex2f(x,0); gl.glEnd(); x = x+dx; } } }

45

6 PROCESSAMENTO DE IMAGEM
6.1 Introduo
Filtro da media e Gradiente Imagem.java import net.java.games.jogl.*; import java.io.*; public class Imagem { float xmin,xmax,ymin,ymax; Pilha w; int dimx,dimy,range; int[][] image; String file; Imagem() { xmin = ymin = 0; xmax = ymax = 512; w = new Pilha(); } Imagem(float xm,float ym,float xM,float yM,String file_name) { xmin = xm; ymin = ym; xmax = xM; ymax = yM; w = new Pilha(); file = file_name; } Imagem(String s) { xmin = 0; ymin = 511; xmax = 511; ymax = 0; w = new Pilha(); file = s; try { Reader q = new FileReader(s); int ch; String p; ch = q.read(); p = String.valueOf((char)ch); while(!Character.isWhitespace((char) ch )) { ch = q.read(); if (Character.isWhitespace((char) ch)) break; p += String.valueOf((char)ch); } dimx = Integer.parseInt(p); while(Character.isWhitespace((char) ch)) ch = q.read(); p = String.valueOf((char)ch); while(!Character.isWhitespace((char) ch)) { ch = q.read();

46

if ch))

(Character.isWhitespace((char)

break; p += String.valueOf((char)ch); } dimy = Integer.parseInt(p); while(Character.isWhitespace((char) ch)) ch = q.read(); p = String.valueOf((char)ch); while(!Character.isWhitespace((char) ch)) { ch = q.read(); if (Character.isWhitespace((char) ch)) break; p += String.valueOf((char)ch); } range = Integer.parseInt(p); image = new int[dimx][dimy]; System.out.println(" " + dimx + " " + dimy + " " + range); for (int i = 0; i<dimx; i++) { for(int j = 0; j<dimy; j++) { while(Character.isWhitespace((char) ch)) ch = q.read(); p = String.valueOf((char)ch); while (!Character.isWhitespace((char) ch)) { if ch)) break; p += String.valueOf((char)ch); // } } } catch (Exception e) { e.printStackTrace(); } } public void media() { int i,j; int[][] B = new int[dimx][dimy]; for(i=0;i<dimx;i++) for(j=0;j<dimy;j++) B[i][j] = image[i][j]; for(i=1;i<dimx-1;i++) for(j=1;j<dimy-1;j++) { image[i][j] = (B[i-1][j-1]+B[i-1][j]+B[i1][j+1]+B[i][j-1]+B[i][j]+B[i][j+1]+B[i+1][j1]+B[i+1][j]+B[i+1][j+1])/9; } } public void filtro_gradiente() } image[i][j] = Integer.parseInt(p); System.out.print(" " + p); ch = q.read(); (Character.isWhitespace((char)

47

{ int i,j; int[][] B = new int[dimx][dimy]; int[][] C = new int[dimx][dimy]; int[][] D = new int[dimx][dimy]; for(i=0;i<dimx;i++) for(j=0;j<dimy;j++) B[i][j] = image[i][j]; for(i=1;i<dimx-1;i++) for(j=1;j<dimy-1;j++) { C[i][j] = (B[i-1][j-1] -B[i-1][j+1] +2*B[i][j-1] -2*B[i][j+1] +B[i+1][j-1] B[i+1][j+1])/4; D[i][j] = (B[i-1][j-1]+2*B[i-1][j]+B[i-1][j+1] -B[i+1][j-1]-2*B[i+1][j] -B[i+1][j+1])/4; image[i][j] = (int)Math.sqrt(D[i][j] * D[i][j] + C[i][j]*C[i][j]); } } public void { int i,j; int[][] B int[][] C int[][] D filtro_mediana() = new int[dimx][dimy]; = new int[dimx][dimy]; = new int[dimx][dimy];

for(i=0;i<dimx;i++) for(j=0;j<dimy;j++) B[i][j] = image[i][j]; for(i=1;i<dimx-1;i++) for(j=1;j<dimy-1;j++) { C[i][j] = (B[i-1][j-1] -B[i-1][j+1] +2*B[i][j-1] -2*B[i][j+1] +B[i+1][j-1] B[i+1][j+1])/4; D[i][j] = (B[i-1][j-1]+2*B[i-1][j]+B[i-1][j+1] -B[i+1][j-1]-2*B[i+1][j] -B[i+1][j+1])/4; image[i][j] = (int)Math.sqrt(D[i][j] * D[i][j] + C[i][j]*C[i][j]); } } public public public public dim) { float x; x = min + ( (p * (max-min))/(dim - 1) ); return (x); float float float float get_xmin() get_ymin() get_xmax() get_ymax() { { { { return return return return xmin; ymin; xmax; ymax; } } } }

public float converte(float p, float min, float max, int

48

} public void recalcula_dominio (float xv_1,float yv_1,float xv_2,float yv_2) { float xmin1,xmax1; float ymin1,ymax1; Window W = new Window(xmin,ymin,xmax,ymax); xmin1 xmax1 ymin1 ymax1 = = = = converte(xv_1,xmin,xmax,600); converte(xv_2,xmin,xmax,600); converte(yv_2,ymax,ymin,600); converte(yv_1,ymax,ymin,600);

w.push(W); xmin xmax ymin ymax } public void retorna_dominio () { Window W = w.pop(); xmin xmax ymin ymax } public void draw_image(GLDrawable draw) { GL gl = draw.getGL(); for (int i=0;i<dimx;i++) for (int j=0;j<dimy;j++) { gl.glColor3f(image[i][j]/(float)range,image[i][j]/(float)range,i mage[i][j]/(float)range); gl.glBegin(GL.GL_POINTS); gl.glVertex2d(j,i); gl.glEnd(); } } public void plota_retangulo (GLDrawable drawable, int x1, int y1, int x2, int y2) { GL gl = drawable.getGL(); float retxmin,retxmax,retymin,retymax; retxmin retxmax retymin retymax = = = = converte converte converte converte (x2,xmin,xmax,600); (x1,xmin,xmax,600); (y1,ymax,ymin,600); (y2,ymax,ymin,600); = = = = W.get_xmin(); W.get_xmax(); W.get_ymin(); W.get_ymax(); = = = = xmin1; xmax1; ymin1; ymax1;

gl.glColor3f(1.0f,1.0f,1.0f); gl.glBegin(GL.GL_LINE_LOOP); gl.glVertex2f(retxmin,retymin); gl.glVertex2f(retxmin,retymax); gl.glVertex2f(retxmax,retymax); gl.glVertex2f(retxmax,retymin); gl.glEnd(); } }

49

main.java import java.awt.*; import java.awt.event.*; import net.java.games.jogl.*; import java.util.*; import java.io.*; public class main { static Imagem g; static int mov = 0; do mouse */ static int xv1, yv1, xv2, yv2; janela */ static GLCanvas canvas GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); { Frame frame = new Frame("Funcao"); canvas.addGLEventListener( new JoglRender() ); canvas.addMouseListener( new JoglMouse() ); canvas.addMouseMotionListener( new JoglMouseMotion() ); canvas.addKeyListener ( new JoglKey() ); frame.add(canvas); frame.setSize(512, 512); frame.setLocation(50,50); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); } static class JoglRender implements GLEventListener { public void init(GLDrawable drawable) { g = new Imagem("gauss.pgm"); } public void display(GLDrawable drawable) { GL gl = drawable.getGL(); GLU glu = drawable.getGLU(); gl.glLoadIdentity(); glu.gluOrtho2D(g.get_xmin(),g.get_xmax(),g.get_ymin(),g.get_ymax ()); gl.glClearColor(0.0f,0.0f,0.0f,1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT GL.GL_DEPTH_BUFFER_BIT); gl.glColor3f(1.0f,0.0f,0.0f); g.draw_image(drawable); | = /* Domnio da nova /* Detecta movimento

public static void main(String[] args) throws IOException

50

if (mov == 1) { System.out.println("mov = 1"); g.plota_retangulo (drawable, xv1,yv1,xv2,yv2); } gl.glFlush(); } public void displayChanged(GLDrawable boolean modeChanged, boolean deviceChanged) { } drawable,

public void reshape(GLDrawable drawable, int x, int y, int width, int height) { } } static class JoglMouse implements MouseListener { public void mouseEntered(MouseEvent e) { // System.out.println("Mouse Entra"); } public void mouseExited (MouseEvent e) { // System.out.println("Mouse Sai"); } public void mousePressed(MouseEvent e) { if (e.getButton()==3) { System.out.println("Entra"); xv1 = e.getX(); yv1 = e.getY(); mov = 1; } } public void mouseReleased(MouseEvent e) { if (e.getButton()==3) { System.out.println("Sai"); xv2 = e.getX(); yv2 = e.getY(); mov = 0; g.recalcula_dominio (xv1,yv1,xv2,yv2); canvas.display(); } if (e.getButton()==1) { System.out.println("Volta Zoom"); g.retorna_dominio(); canvas.display(); } } public void mouseClicked(MouseEvent e) { System.out.println("Mouse botao"); } }

51

static MouseMotionListener {

class

JoglMouseMotion

implements

public void mouseDragged(MouseEvent e) { if ((e.getModifiers() InputEvent.BUTTON3_MASK) != 0) { xv2 = e.getX(); yv2 = e.getY(); System.out.println("Dragged: e.getX() + "," + e.getY()); canvas.display(); } } // + e.getY()); } static class JoglKey implements KeyListener {

&

"

public void mouseMoved(MouseEvent e) { System.out.println("Moved: " + e.getX() + "," }

public void keyPressed (KeyEvent e) { if (e.getKeyChar() == 'g' || e.getKeyChar() == 'G') { g.filtro_gradiente(); canvas.display(); System.out.println("Gradiente"); } if (e.getKeyChar() == 'm' || e.getKeyChar() == 'M') { System.out.println("Media"); g.media(); canvas.display(); } } public void keyReleased(KeyEvent e) { // System.out.println("Released"); } public void keyTyped (KeyEvent e) { // System.out.println("Typed"); } } }

52

7 FRACTAIS
7.1 Conjuntos auto-semelhantes
Definio: Um subconjunto fechado e limitado expresso na forma: onde fator de escala ( , dito ser auto-semelhante se pode ser

so conjuntos no sobrepostos e cada um deles congruente a ).

por mesmo

Exemplo 1: Um tringulo pode ser expresso como a unio de quatro tringulos congruentes e no sobrepostos. Cada um dos tringulos congruente ao original por um fator conjunto auto-semelhante com k = 4. e o tringulo um

Exemplo 2 (Tringulo de Sierpinski): Este exemplo foi apresentado pelo matemtico Waclaw Sierpinski (1882-1969). Neste exemplo, partindo de um tringulo, temos a unio de trs tringulos no sobrepostos

53

(portanto

), cada um dos quais congruente ao original com um fator de escala

. Em

seguida, o processo se repete para cada um dos trs tringulos, e assim sucessivamente.

7.2 Dimenso Hausdorff e o conceito de fractal


Definio: A dimenso Hausdorff de um conjunto auto-semelhante definida por:

onde

denota a dimenso Hausdorff.

Assim, considerando os exemplos anteriores teremos: Exemplo 1: Exemplo 2: Observe que no exemplo 1, a dimenso Hausdorff, coincide com a dimenso topolgica usual, uma vez que uma regio em tem dimenso 2. Porm no exemplo 2, obtemos uma dimenso no inteira para o tringulo de Sierpinski. Partindo desta observao, Mandelbrot sugeriu em 1977 a seguinte definio: Definio: Um fractal um subconjunto do espao euclidiano cuja dimenso Hausdorff diferente da dimenso topolgica.

7.3 Exemplos de fractais


Alguns dos principais exemplos que apresentaremos nesta seo foram gerados utilizando composio de transformaes de rotao e escala seguido de uma possvel translao. O formato geral da funo dado por:

54

onde

7.3.1- Tringulo de Sierpinski


Para obter o tringulo de Sierpinski, utilizaremos uma aplicao que a partir de um tringulo, obtm trs novos tringulos conforme a figura abaixo:

Assim temos trs funes, uma associada a cada tringulo:

main.java import java.awt.*; import java.awt.event.*; import net.java.games.jogl.*; import java.util.*; import java.io.*; public class main { static Fractal g; static int mov = 0; /* Detecta movimento do mouse */ static int xv1, yv1, xv2, yv2; /* Domnio da nova janela */ static GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities());

55

public static void main(String[] args) throws IOException { Frame frame = new Frame("Funcao"); canvas.addGLEventListener( new JoglRender() ); canvas.addMouseListener( new JoglMouse() ); canvas.addMouseMotionListener( new JoglMouseMotion() ); canvas.addKeyListener ( new JoglKey() ); frame.add(canvas); frame.setSize(600,600); frame.setLocation(50,50); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); } static class JoglRender implements GLEventListener { public void init(GLDrawable drawable) { g = new Fractal(); } public void display(GLDrawable drawable) { GL gl = drawable.getGL(); GLU glu = drawable.getGLU(); gl.glLoadIdentity(); glu.gluOrtho2D(g.get_xmin(),g.get_xmax(),g.get_ymin(),g.get_ymax()) ; gl.glClearColor(0.0f,0.0f,0.0f,1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glColor3f(1.0f,0.0f,0.0f); g.plota_fractal(drawable); if (mov == 1) { System.out.println("mov = 1"); g.plota_retangulo (drawable, xv1,yv1,xv2,yv2); } gl.glFlush(); } public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) { } public void reshape(GLDrawable drawable, int x, int y, int width, int height) { } } static class JoglMouse implements MouseListener { public void mouseEntered(MouseEvent e) { // System.out.println("Mouse Entra"); }

56

public void mouseExited (MouseEvent e) { // System.out.println("Mouse Sai"); } public void mousePressed(MouseEvent e) { if (e.getButton()==3) { System.out.println("Entra"); xv1 = e.getX(); yv1 = e.getY(); mov = 1; } } public void mouseReleased(MouseEvent e) { if (e.getButton()==3) { System.out.println("Sai"); xv2 = e.getX(); yv2 = e.getY(); mov = 0; g.recalcula_dominio (xv1,yv1,xv2,yv2); canvas.display(); } if (e.getButton()==1) { System.out.println("Volta Zoom"); g.retorna_dominio(); canvas.display(); } } public void mouseClicked(MouseEvent e) { System.out.println("Mouse botao"); } } static class JoglMouseMotion implements { MouseMotionListener

public void mouseDragged(MouseEvent e) { if ((e.getModifiers() & InputEvent.BUTTON3_MASK) != 0) { xv2 = e.getX(); yv2 = e.getY(); System.out.println("Dragged: " + e.getX() + "," + e.getY()); canvas.display(); } } public void mouseMoved(MouseEvent e) { } } static class JoglKey implements KeyListener {

public void keyPressed (KeyEvent e) {

57

} public void keyReleased(KeyEvent e) { } public void keyTyped (KeyEvent e) { } } }

Fractal.java import net.java.games.jogl.*; import java.io.*; public class Fractal { float Pilha int float xmin,xmax,ymin,ymax; w; n; x1,y1,x2,y2,x3,y3;

Fractal() { xmin = ymin = 0; xmax = ymax = 1; w = new Pilha(); x1 = 0.0f; y1 = 0.0f; x2 = 0.0f; y2 = 1.0f; x3 = 1.0f; y3 = 0.0f; n = 7; } Fractal(float xm,float ym,float xM,float yM, float _x1, float _y1, float _x2, float _y2, float _x3, float _y3, int iter) { xmin = xm; ymin = ym; xmax = xM; ymax = yM; n = iter; x1 = _x1; y1 = _y1; x2 = _x2; y2 = _y2; x3 = _x3; y3 = _y3; }

public public public public

float float float float

get_xmin() get_ymin() get_xmax() get_ymax()

{ { { {

return return return return

xmin; ymin; xmax; ymax;

} } } }

58

public float converte(float p, float min, float max, int dim) { float x; x = min + ( (p * (max-min))/(dim - 1) ); return (x); } public void recalcula_dominio (float xv_1,float xv_2,float yv_2) { float xmin1,xmax1; float ymin1,ymax1; Window W = new Window(xmin,ymin,xmax,ymax); xmin1 xmax1 ymin1 ymax1 = = = = converte(xv_1,xmin,xmax,600); converte(xv_2,xmin,xmax,600); converte(yv_2,ymax,ymin,600); converte(yv_1,ymax,ymin,600); yv_1,float

w.push(W); xmin xmax ymin ymax } public void retorna_dominio () { Window W = w.pop(); xmin xmax ymin ymax } public float[] transform(float x,float y,float e,float f) { float[] v = new float[2]; v[0] = x/2 + e; v[1] = y/2 + f; return v; } public void plota_fractal(GLDrawable draw) { plota_auto_semelhante(draw,x1,y1,x2,y2,x3,y3,n); } public void plota_auto_semelhante(GLDrawable draw, float x0,float y0, float x1,float y1, float x2,float y2, int n) { GL gl = draw.getGL(); int i,j; float[][] x = new float[3][3]; float[][] y = new float[3][3]; float[] e = new float[3]; = = = = W.get_xmin(); W.get_xmax(); W.get_ymin(); W.get_ymax(); = = = = xmin1; xmax1; ymin1; ymax1;

59

float[] f = new float[3]; float[] v; e[1] = 0.5f; f[2] = 0.5f; for(i=0;i<3;i++) { x[i][0] = y[i][0] = x[i][1] = y[i][1] = x[i][2] = y[i][2] = } // y[j][i]); for(i=0;i<3;i++) for (j=0;j<3;j++) { System.out.println("antes = " + x[j][i] + " " + x0; y0; x1; y1; x2; y2;

// y[j][i]); } if

v = transform(x[j][i],y[j][i],e[j],f[j]); x[j][i] = v[0]; y[j][i] = v[1]; System.out.println("depois = " + x[j][i] + " " +

(n == 0) { for (i=0;i<3;i++) { gl.glColor3f(1.0f,0.0f,0.0f); gl.glBegin(GL.GL_TRIANGLES); gl.glVertex2f(x[i][0],y[i][0]); gl.glVertex2f(x[i][1],y[i][1]); gl.glVertex2f(x[i][2],y[i][2]); gl.glEnd(); } return; for(i=0;i<3;i++)

} else { plota_auto_semelhante(draw,x[i][0],y[i][0],x[i][1],y[i][1], x[i][2],y[i][2],n-1); } } public void plota_retangulo (GLDrawable drawable, int x1, int y1, int x2, int y2) { GL gl = drawable.getGL(); float retxmin,retxmax,retymin,retymax; retxmin retxmax retymin retymax = = = = converte converte converte converte (x2,xmin,xmax,600); (x1,xmin,xmax,600); (y1,ymax,ymin,600); (y2,ymax,ymin,600);

gl.glColor3f(1.0f,1.0f,1.0f); gl.glBegin(GL.GL_LINE_LOOP); gl.glVertex2f(retxmin,retymin); gl.glVertex2f(retxmin,retymax); gl.glVertex2f(retxmax,retymax); gl.glVertex2f(retxmax,retymin); gl.glEnd();

60

} }

7.3.2- Tringulo de Sierpinski utilizando Monte Carlo


Este mtodo utiliza iteraes randmicas para gerar fractais utilizando o seguinte processo: 1- Defina as k transformaes (como descrito na seo 6.3) que descrevem o objeto a ser gerado. 2- Escolha um ponto arbitrrio .

3- Escolha arbitrariamente uma das k transformaes e aplique no ponto escolhido:

4- Prossiga escolhendo aleatoriamente uma das k transformaes e aplique no ultimo ponto obtido:

O mdulo main.java, necessita apenas das alteraes no display e no nome da classe. Fractal.java // Monte Carlo import net.java.games.jogl.*; import java.io.*; import java.util.*; public class Fractal { float Pilha int float float float xmin,xmax,ymin,ymax; w; n; x1,y1,x2,y2,x3,y3; x0; y0;

Fractal() { xmin = ymin = 0; xmax = ymax = 1; w = new Pilha(); x1 = 0.0f; y1 = 0.0f; x2 = 0.0f; y2 = 1.0f; x3 = 1.0f; y3 = 0.0f; n = 70000; x0 = 0; y0 = 0; } Fractal(float xm,float ym,float xM,float yM, float _x1, float _y1, float _x2, float _y2, float _x3, float _y3, int iter, float _x0,float _y0) { xmin = xm; ymin = ym; 61

xmax = xM; ymax = yM; n = iter; x1 = _x1; y1 = _y1; x2 = _x2; y2 = _y2; x3 = _x3; y3 = _y3; x0 = _x0; y0 = _y0; }

public float[] transform(float x,float y,float e,float f) { float[] v = new float[2]; v[0] = x/2 + e; v[1] = y/2 + f; return v; } public void plota_fractal(GLDrawable draw) { GL gl = draw.getGL(); int i,j; float[][] x = new float[3][4]; float[][] y = new float[3][4]; Random rn = new Random(); float[] e = new float[3]; float[] f = new float[3]; float[] v; e[1] = 0.5f; f[2] = 0.5f; for(i=0;i<n;i++) { j = (int) (3.0 * rn.nextDouble()); j = ( j > 2) ? 2 : j; v = transform(x0,y0,e[j],f[j]); x0 = v[0]; y0 = v[1]; gl.glColor3f(1.0f,0.0f,0.0f); gl.glBegin(GL.GL_POINTS); gl.glVertex2f(x0,y0); gl.glEnd(); } } ... }

7.3.3- Fern
import net.java.games.jogl.*; import java.io.*; import java.util.*;

62

public class Fractal { float xmin,xmax,ymin,ymax; Pilha w; int n; Fractal() { xmin = ymin = 0; xmax = ymax = 1; w = new Pilha(); n = 3; }

Fractal(float xm,float ym,float xM,float yM, float _x1, float _y1, float _x2, float _y2, float _x3, float _y3, int iter, float _x0,float _y0) { xmin = xm; ymin = ym; xmax = xM; ymax = yM; n = iter; }

public float[] transform(float a11,float a12,float a21,float a22,float e,float f,float x1,float y1) { float[] v = new float[2]; v[0] = a11 * x1 + a12 * y1 + e; v[1] = a21 * x1 + a22 * y1 + f; return v; } public void plota_fractal(GLDrawable draw) { float[] x = new float[4]; float[] y = new float[4]; x[1] = x[2] = 1.0f; y[2] = y[3] = 1.0f; plota_auto_semelhante(draw,x,y,n); } public void plota_auto_semelhante(GLDrawable draw,float[] x,float[] y,int ni) { GL gl = draw.getGL(); int i,j; float[][] xx = new float[4][4]; float[][] yy = new float[4][4]; float[] v;

63

for(i=0;i<4;i++) for(j=0;j<4;j++) { xx[i][j] = x[j]; yy[i][j] = y[j]; } if (ni == 0) { gl.glColor3f(0.0f,1.0f,0.0f); gl.glBegin(GL.GL_LINE_LOOP); gl.glVertex2f(x[0],y[0]); gl.glVertex2f(x[1],y[1]); gl.glVertex2f(x[2],y[2]); gl.glVertex2f(x[3],y[3]); gl.glEnd(); return; } else { for(i=0;i<4;i++) { v = transform( 0.20f,-0.26f, 0.23f, 0.22f,0.400f, 0.045f,xx[0][i],yy[0][i]); xx[0][i] = v[0]; yy[0][i] = v[1]; v = transform( 0.85f, 0.04f,-0.04f, 0.85f,0.075f, 0.180f,xx[1][i],yy[1][i]); xx[1][i] = v[0]; yy[1][i] = v[1]; v = transform( 0.00f, 0.00f, 0.00f, 0.16f,0.500f, 0.000f,xx[2][i],yy[2][i]); xx[2][i] = v[0]; yy[2][i] = v[1]; v = transform(-0.15f, 0.28f, 0.26f, 0.24f,0.575f,-0.086f,xx[3][i],yy[3][i]); xx[3][i] = v[0]; yy[3][i] = v[1]; } plota_auto_semelhante(draw,xx[0],yy[0],ni-1); plota_auto_semelhante(draw,xx[1],yy[1],ni-1); plota_auto_semelhante(draw,xx[2],yy[2],ni-1); plota_auto_semelhante(draw,xx[3],yy[3],ni-1); }

} ... }

64

7.4 Conjunto de Julia


import java.awt.*; import java.awt.event.*; import net.java.games.jogl.*;
public class Julia { int DIM; float dx,dy; float xc,yc,xcl,ycl,xc1,yc1; float xminj,yminj,xmaxj,ymaxj; float xminm,yminm,xmaxm,ymaxm; int n; int m; int lk; Pilha w = new Pilha(); int[][] M ; int[][] o ; Julia() { M = new int[600][600]; o = new int[600][600]; DIM = 600; n = 600; xc1 = 1; yc1 = 1; m = 100; xminm = yminm = xminj = yminj = -2; xmaxm = ymaxm = xmaxj = ymaxj = 2; dx=(xmaxj-xminj)/n; dy=(ymaxj-yminj)/n; }

public void constant(float x,float y) { float t2; t2=(float)x/DIM; xc1=xminm+t2*(xmaxm-xminm); t2=(float)y/DIM; yc1=(ymaxm-t2*(ymaxm-yminm)); System.out.println("\n\n----------\nConstante Atual: " + xc1 + , + yc1); } public public public public float float float float get_xmin() get_ymin() get_xmax() get_ymax() { { { { if if if if (lk (lk (lk (lk == == == == 0) 0) 0) 0) return return return return xminj; yminj; xmaxj; ymaxj; else else else else return return return return xminm;} yminm;} xmaxm;} ymaxm;}

public void set_m(int i) { if (i == 0) m += 10; else m -= 10; System.out.println("iter = " + m); } public int getDIM() { return DIM; } public double[] cores (float ca){ double[] result = new double[3]; double s=m/5.0; if( ca <= s) { result[0]=1.0; result[1]=ca/s; result[2]=0.0; } else if( ca<=2*s ) { result[0]=1.0-(ca-s)/s; result[1]=1.0;

65

result[2]=0.0; } else if( ca<=3*s ) { result[0]=0.0; result[1]=1.0; result[2]=(ca-2*s)/s; } else if( ca<=4*s ) { result[0]=0.0; result[1]=1.0-(ca-3*s)/s; result[2]=1.0; } else if( ca> 4*s) { result[0]=(ca-4*s)/s; result[1]=0.0; result[2]=1.0; } return result; } public void plota_indicador_constante(GLDrawable draw) { GL gl = draw.getGL(); gl.glColor3f(1,1,1); gl.glLineWidth(2); gl.glBegin(GL.GL_LINES); gl.glVertex2f(xc1,yc1+((ymaxm-yminm)/20)); gl.glVertex2f(xc1,yc1+((ymaxm-yminm)/40)); gl.glVertex2f(xc1,yc1-((ymaxm-yminm)/40)); gl.glVertex2f(xc1,yc1-((ymaxm-yminm)/20)); gl.glVertex2f(xc1-((xmaxm-xminm)/20),yc1); gl.glVertex2f(xc1-((xmaxm-xminm)/40),yc1); gl.glVertex2f(xc1+((xmaxm-xminm)/40),yc1); gl.glVertex2f(xc1+((xmaxm-xminm)/20),yc1); gl.glEnd(); } public void set_lk() { lk = (lk + 1) %2; System.out.print(lk); } public int get_lk() { return lk; } public void init() { if (lk == 0) { dx=Math.abs(xmaxj-xminj)/n; dy=Math.abs(ymaxj-yminj)/n; } else { dx=Math.abs(xmaxm-xminm)/n; dy=Math.abs(ymaxm-yminm)/n; } xc=xc1; yc=yc1; } public void plota_fractal(GLDrawable draw) { float xmin,ymin,xmax,ymax; GL gl = draw.getGL(); int x,y,k; float R; float i,j,xz,yz,temp;

66

double[] cor; for(x=0;x<n;x++) { for(y=0;y<n;y++) { M[x][y] = 0; o[x][y] =0; } } if (lk == 0) { xmin xmax ymin ymax } else { xmin xmax ymin ymax }

= = = =

xminj; xmaxj; yminj; ymaxj;

= = = =

xminm; xmaxm; yminm; ymaxm;

i = xmin; for(x=0;x<2*n;x++) { i = i+dx/2; j = ymin; for(y=0;y<2*n;y++) { j = j + dy/2; if(lk==0) { xz=i; yz=j; k=0; } else { xz=0; yz=0; k=0; xc=i; yc=j; } if( ((xc*xc) + (yc*yc))>4) { R=(xc*xc) + (yc*yc); } else{ R=4.0f; } for(k=0;k<m;k++) { if((xz*xz)+(yz*yz)>R)/*Verifica se o ponto escapou e plota na cor de acordo com o nmero de itera es necessrio*/ { M[x/2][y/2] += k; o[x/2][y/2]++; break; } else { temp=((xz*xz) - (yz*yz) + xc); yz=((2*xz*yz) + yc); xz=temp; }

67

} } } for(x=0;x<600;x++) { for(y=0;y<600;y++) { cor = cores((float)M[x][y]/o[x][y]); gl.glColor3d(cor[0],cor[1],cor[2]); gl.glBegin(GL.GL_POINTS); gl.glVertex2i(x,y); gl.glEnd(); } } } public void recalcula_dominio (float xv_1,float yv_1, float xv_2,float yv_2) { float xmin1,xmax1; float ymin1,ymax1; if (lk == 0) { Window W = new Window(xminj,yminj,xmaxj,ymaxj); xmin1 = converte(xv_1,xminj,xmaxj,DIM); xmax1 = converte(xv_2,xminj,xmaxj,DIM); ymin1 = converte(yv_2,ymaxj,yminj,DIM); ymax1 = converte(yv_1,ymaxj,yminj,DIM); w.push(W); xminj = xmin1; xmaxj = xmax1; yminj = ymin1; ymaxj = ymax1; } else { Window W = new Window(xminm,yminm,xmaxm,ymaxm); xmin1 = converte(xv_1,xminm,xmaxm,DIM); xmax1 = converte(xv_2,xminm,xmaxm,DIM); ymin1 = converte(yv_2,ymaxm,yminm,DIM); ymax1 = converte(yv_1,ymaxm,yminm,DIM); w.push(W); xminm = xmin1; xmaxm = xmax1; yminm = ymin1; ymaxm = ymax1; } } public float converte(float p, float min, float max, int dim) { float x; x = min + ( (p * (max-min))/(dim - 1) ); return (x); } public void retorna_dominio () { Window W = w.pop(); if (lk == 0) { xminj = W.get_xmin(); xmaxj = W.get_xmax(); yminj = W.get_ymin(); ymaxj = W.get_ymax(); } else { xminm = W.get_xmin(); xmaxm = W.get_xmax(); yminm = W.get_ymin(); ymaxm = W.get_ymax(); } }

68

69

CAPTULO III VISUALIZAO E APLICAES GRFICAS 3D ____________ 2 1- TRANSFORMAES DE VISUALIZAO ________________________________ 2


1.1 1.2 1.3 - Introduo ____________________________________________________________ 2 Transformaes _______________________________________________________ 6 - Comandos de Auxlio ___________________________________________________ 6

1.4- Exemplo: cubo unitrio ____________________________________________________ 7 1.5 - Transformaes de Modelagem e Visualizao_________________________________ 9


1.5.1- Translao ____________________________________________________________________ 9 1.5.2- Rotao ______________________________________________________________________ 9 1.5.3- Escala _______________________________________________________________________ 9 1.5.4-Exemplo _____________________________________________________________________ 10

1.6- Projeo Ortogrfica _____________________________________________________ 12 1.7- Projeo Perspectiva ______________________________________________________ 12 1.8- ngulos de Euler _________________________________________________________ 13 1.8 - Criando um Ambiente de Visualizao 3D ___________________________________ 14
1.8.1- Mdulo Bsico de Visualizao __________________________________________________ 14 1.8.2- Alterando os ngulos de Euler ___________________________________________________ 16

1.9 Visualizao de grfico de funes

_______________________________ 19

2- ILUMINAO _______________________________________________________ 24
2.1 Criando Fontes de Luz ____________________________________________________ 27
2.1.1 Cor ________________________________________________________________________ 27 2.1.2 Posio _____________________________________________________________________ 28

2.2 Selecionando o Modelo de Iluminao _______________________________________ 28


2.2.1- Luz Ambiente Global __________________________________________________________ 2.2.2 Posio do observador local ou no infinito _________________________________________ 2.2.3 Iluminao nos dois lados das faces ______________________________________________ 2.2.4 Habilitando a iluminao_______________________________________________________ 28 28 28 28

2.3 Selecionando as Propriedades do Material ___________________________________ 29 2.4 Exemplo 1 ______________________________________________________________ 29 2.5 Comando glLookAt ______________________________________________________ 34 2.6 Visualizando as normais __________________________________________________ 36

3- SUPERFCIES PARAMETRIZADAS ____________________________________ 37


3.1 Visualizao de superfcies na forma paramtrica _____________________________ 37 3.2 Exerccios_______________________________________________________________ 39

4- SUPERFCIES IMPLCITAS ___________________________________________ 41 5- TEXTURA ___________________________________________________________ 48

CAPTULO III VISUALIZAO E APLICAES GRFICAS 3D


1- Transformaes de Visualizao
1.1 - Introduo
Nosso objetivo nesta seo descrever a gerao de uma imagem bi-dimensional partindo de um objeto tridimensional. Para isso vamos partir de um exemplo: um cubo. A idia construir algum tipo de visualizao deste cubo, que nos transmita a sensao de estar visualizando um objeto 3-dimensional. Vamos considerar o cubo da figura abaixo: As coordenadas dos vrtices deste cubo so: v0 v1 v2 v3 (0,0,0) (1,0,0) (1,1,0) (0,1,0) v4 v5 v6 v7 (0,0,1) (1,0,1) (1,1,1) (0,1,1)

Para visualizar este modelo, uma primeira estratgia seria definir uma projeo de nosso modelo 3D para o bidimensional. /* * * * * * * * * * * * * * * * * */ /* Modulo: main.java */ /* * * * * * * * * * * * * * * * * */ import java.awt.*; import java.awt.event.*; import net.java.games.jogl.*; public class main { static cubo Q; static GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); public static void main(String[] args) { Frame frame = new Frame("Cubo"); canvas.addGLEventListener( new JoglRender() ); frame.add(canvas); frame.setSize(600, 600); frame.setLocation(50,50); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); } static class JoglRender implements GLEventListener { public void init(GLDrawable drawable) { Q = new cubo(); } public void display(GLDrawable drawable) { 2

GL gl = drawable.getGL(); GLU glu = drawable.getGLU(); gl.glLoadIdentity(); glu.gluOrtho2D(-2,2,-2,2); gl.glClearColor(0.0f,0.0f,0.0f,1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glColor3f(1.0f,0.0f,0.0f); Q.render_cubo(drawable); gl.glFlush(); } public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) {} public void reshape(GLDrawable drawable, int x, int y, int width, int height) {} } }

/* * * * * * * * * * * * * * * * */ /* Modulo: cubo.java */ /* * * * * * * * * * * * * * * * */ import net.java.games.jogl.*; public class cubo { float[][] P; cubo() { P = new float[8][3]; unitario(); } public void unitario() { P[0][0] = 0; P[0][1] = 0; P[0][2] = 0; P[1][0] = 1; P[1][1] = 0; P[1][2] = 0; P[2][0] = 1; P[2][1] = 1; P[2][2] = 0; P[3][0] = 0; P[3][1] = 1; P[3][2] = 0; } P[4][0] P[4][1] P[4][2] P[5][0] P[5][1] P[5][2] P[6][0] P[6][1] P[6][2] P[7][0] P[7][1] P[7][2] = = = = = = = = = = = = 0; 0; 1; 1; 0; 1; 1; 1; 1; 0; 1; 1;

public void render_cubo(GLDrawable drawable) { GL gl = drawable.getGL(); gl.glBegin(GL.GL_LINE_LOOP); gl.glVertex2f(P[0][0],P[0][1]); gl.glVertex2f(P[1][0],P[1][1]); gl.glVertex2f(P[2][0],P[2][1]); 3

gl.glVertex2f(P[3][0],P[3][1]); gl.glEnd(); gl.glBegin(GL.GL_LINE_LOOP); gl.glVertex2f(P[4][0],P[4][1]); gl.glVertex2f(P[5][0],P[5][1]); gl.glVertex2f(P[6][0],P[6][1]); gl.glVertex2f(P[7][0],P[7][1]); gl.glEnd(); gl.glBegin(GL.GL_LINES); gl.glVertex2f(P[0][0],P[0][1]); gl.glVertex2f(P[4][0],P[4][1]); gl.glVertex2f(P[1][0],P[1][1]); gl.glVertex2f(P[5][0],P[5][1]); gl.glVertex2f(P[2][0],P[2][1]); gl.glVertex2f(P[6][0],P[6][1]); gl.glVertex2f(P[3][0],P[3][1]); gl.glVertex2f(P[7][0],P[7][1]); gl.glEnd(); } } Vamos aplicar uma rotao sobre os vrtices do cubo e verificar o resultado. Para isso acrescentaremos um mtodo que aplica uma rotao em cada um dos vrtices do cubo. import net.java.games.jogl.*; public class cubo { float[][] P; cubo() { P = new float[8][3]; unitario(); } public void P[0][0] = P[0][1] = P[0][2] = P[1][0] = P[1][1] = P[1][2] = P[2][0] = P[2][1] = P[2][2] = P[3][0] = P[3][1] = P[3][2] = } unitario() { 0; P[4][0] 0; P[4][1] 0; P[4][2] 1; P[5][0] 0; P[5][1] 0; P[5][2] 1; P[6][0] 1; P[6][1] 0; P[6][2] 0; P[7][0] 1; P[7][1] 0; P[7][2] = = = = = = = = = = = = 0; 0; 1; 1; 0; 1; 1; 1; 1; 0; 1; 1;

public void rotaciona_x(double t) { float y,z; for(int i =0; i < 8 ;i++) { y = P[i][1] * (float)Math.cos(t) P[i][2] * (float)Math.sin(t); z = P[i][1] * (float)Math.sin(t) + 4

P[i][2] * (float)Math.cos(t); P[i][1] = y; P[i][2] = z; } }

public void rotaciona_y(double t) { float x,z; for(int i =0; i < 8 ;i++) { x = P[i][0] * (float)Math.cos(t) P[i][2] * (float)Math.sin(t); z = P[i][0] * (float)Math.sin(t) + P[i][2] * (float)Math.cos(t); P[i][0] = x; P[i][2] = z; } } public void rotaciona_z(double t) { float x,y; for(int i =0; i < 8 ;i++) { x = P[i][0] * (float)Math.cos(t) P[i][1] * (float)Math.sin(t); y = P[i][0] * (float)Math.sin(t) + P[i][1] * (float)Math.cos(t); P[i][0] = x; P[i][1] = y; } } public void render_cubo(GLDrawable drawable) { GL gl = drawable.getGL(); unitario(); rotaciona_z(Math.PI / 4); rotaciona_y(Math.PI / 4); rotaciona_z(Math.PI / 6); gl.glBegin(GL.GL_LINE_LOOP); gl.glVertex2f(P[0][0],P[0][1]); gl.glVertex2f(P[1][0],P[1][1]); gl.glVertex2f(P[2][0],P[2][1]); gl.glVertex2f(P[3][0],P[3][1]); gl.glEnd(); gl.glBegin(GL.GL_LINE_LOOP); gl.glVertex2f(P[4][0],P[4][1]); gl.glVertex2f(P[5][0],P[5][1]); gl.glVertex2f(P[6][0],P[6][1]); gl.glVertex2f(P[7][0],P[7][1]); gl.glEnd(); gl.glBegin(GL.GL_LINES); gl.glVertex2f(P[0][0],P[0][1]); gl.glVertex2f(P[4][0],P[4][1]); gl.glVertex2f(P[1][0],P[1][1]); gl.glVertex2f(P[5][0],P[5][1]); gl.glVertex2f(P[2][0],P[2][1]); gl.glVertex2f(P[6][0],P[6][1]); gl.glVertex2f(P[3][0],P[3][1]); gl.glVertex2f(P[7][0],P[7][1]); gl.glEnd(); 5

1.2 Transformaes
As transformaes necessrias para visualizao de uma cena podem ser comparadas ao processo de fotografar uma cena real [OpenGL Guide pg. 65]: 1. Monte o trip e aponte a camera para a cena desejada (viewing transformation) 2. Prepare a cena a ser fotografada na posio desejada (modeling transformation). 3. Escolhas a lente certa para a cmera e ajuste o zoom. (projection transformation). 4. Defina os limites da cena que estaro na foto final (viewport transformation). De forma geral podemos dividir as operaes necessrias em trs grupos: - Transformaes (representadas por multiplicao de matrizes) incluindo operaes de projeo, visualizao e modelagem. Estas operaes incluem rotaes, escalas, translaes, reflexes, projees ortogrficas e perspectivas. - Operaes de Clipping so responsveis pela eliminao de objetos que esto fora da janela de visualizao. - Transformaes que estabeleam a correspondncia entre as coordenadas e a dimenso da tela (Viewport transformation). De forma esquemtica podemos estabelecer:

Para especificar uma transformao o OpenGL constri uma matriz 4x4 que representa a transformao desejada. Esta matriz ento multiplicada pelas coordenadas de cada vrtice na cena. As transformaes de Modelagem e Visualizao so combinadas em uma nica matriz denominada MODELVIEW matrix. A transformao de projeo armazenada na PROJECTION matrix.

1.3 - Comandos de Auxlio


Antes de iniciar a descrio do mecanismo das transformaes acima, apresentaremos um conjunto de comandos de carter geral. Os comandos a seguir sero teis durante todas as etapas do processo de modelagem, visualizao e Projeo. glMatrixMode(Glenum tipo); Este comando especifica a matriz a ser alterada. Existem trs argumentos conforme o tipo da matriz: 1) GL_MODELVIEW 2) GL_PROJECTION 3) GL_TEXTURE As transformaes subsequentes afetam a matriz especificada. Observe que somente uma matriz pode ser alterada por vez. 6

glLoadIdentity(void); Este comando carrega a matriz identidade na matriz corrente especificada anteriormente pelo glMatrixMode. O objetivo limpar qualquer alterao anterior realizada sobre a matriz.

glLoadMatrix(const TYPE *M); Quando voc deseja especificar uma matriz M particular para ser a matriz corrente, utilize o glLoadMatrix(M).

glMultMatrix(const TYPE *M); Este comando multiplica a matriz definida por

pela matriz corrente.

1.4- Exemplo: cubo unitrio


Antes de detalhar as transformaes principais, vamos apresentar um programa exemplo que visualiza o mesmo cubo do exemplo anterior, porem utilizando as transformaes do OpenGL.

main.cpp
import java.awt.*; import java.awt.event.*; import net.java.games.jogl.*; public class main { static cubo Q; static GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); public static void main(String[] args) { Frame frame = new Frame("Cubo"); canvas.addGLEventListener( new JoglRender() ); frame.add(canvas); frame.setSize(600, 600); frame.setLocation(50,50); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); } static class JoglRender implements GLEventListener { public void init(GLDrawable drawable) { GL gl = drawable.getGL(); 7

Q = new cubo(); gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); gl.glOrtho(-2.0,2.0,-2.0,2.0,-2.0,2.0); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); gl.glRotatef(30,0,0,1); gl.glRotatef(45,0,1,0); gl.glRotatef(45,0,0,1); } public void display(GLDrawable drawable) { GL gl = drawable.getGL(); GLU glu = drawable.getGLU(); gl.glClearColor(0.0f,0.0f,0.0f,1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glColor3f(1.0f,0.0f,0.0f); Q.render_cubo(drawable); gl.glFlush(); } public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) { } public void reshape(GLDrawable drawable, int x, int y, int width, int height) { } } }

cubo.java
import net.java.games.jogl.*; public class cubo { float[][] P; cubo() { P = new float[8][3]; unitario(); } public void P[0][0] = P[0][1] = P[0][2] = P[1][0] = P[1][1] = P[1][2] = P[2][0] = P[2][1] = P[2][2] = P[3][0] = P[3][1] = P[3][2] = } unitario() { 0; P[4][0] 0; P[4][1] 0; P[4][2] 1; P[5][0] 0; P[5][1] 0; P[5][2] 1; P[6][0] 1; P[6][1] 0; P[6][2] 0; P[7][0] 1; P[7][1] 0; P[7][2] = = = = = = = = = = = = 0; 0; 1; 1; 0; 1; 1; 1; 1; 0; 1; 1; 8

public void render_cubo(GLDrawable drawable) { GL gl = drawable.getGL(); gl.glBegin(GL.GL_LINE_LOOP); gl.glVertex3f(P[0][0],P[0][1],P[0][2]); gl.glVertex3f(P[1][0],P[1][1],P[1][2]); gl.glVertex3f(P[2][0],P[2][1],P[2][2]); gl.glVertex3f(P[3][0],P[3][1],P[3][2]); gl.glEnd(); gl.glBegin(GL.GL_LINE_LOOP); gl.glVertex3f(P[4][0],P[4][1],P[4][2]); gl.glVertex3f(P[5][0],P[5][1],P[4][2]); gl.glVertex3f(P[6][0],P[6][1],P[4][2]); gl.glVertex3f(P[7][0],P[7][1],P[4][2]); gl.glEnd(); gl.glBegin(GL.GL_LINES); gl.glVertex3f(P[0][0],P[0][1],P[0][2]); gl.glVertex3f(P[4][0],P[4][1],P[4][2]); gl.glVertex3f(P[1][0],P[1][1],P[1][2]); gl.glVertex3f(P[5][0],P[5][1],P[5][2]); gl.glVertex3f(P[2][0],P[2][1],P[2][2]); gl.glVertex3f(P[6][0],P[6][1],P[6][2]); gl.glVertex3f(P[3][0],P[3][1],P[3][2]); gl.glVertex3f(P[7][0],P[7][1],P[7][2]); gl.glEnd(); } }

1.5 - Transformaes de Modelagem e Visualizao


Existem trs tipos de comandos para transformaes de modelagem: glTranslate(), glRotate() e glScale(). Vamos descrever abaixo cada uma dessas funes.

1.5.1- Translao
void glTranslatef(float x, float y, float z); Este comando multiplica a matriz corrente por uma matriz que translada o objeto conforme o vetor .

1.5.2- Rotao
void glRotatef(float theta, float x, float y, float z); Multiplica a matriz corrente por uma matriz que rotaciona o objeto no sentido anti-horrio de theta graus, na direo do eixo dado pelo vetor .

1.5.3- Escala
9

void glScalef(float x, float y, float z); Este comando realiza transformaes de escala e reflexo. Cada ponto x, y e z do objeto multiplicado pelo correspondente argumento x,y e z.

1.5.4-Exemplo
Como exemplo vamos apresentar um programa que executa as trs transformaes citadas acima. Partindo de um tringulo, desenhamos este tringulo quatro vezes sendo que: - O tringulo vermelho desenhado sem nenhuma transformao. - O tringulo verde sofreu uma translao. - O tringulo azul sofreu uma rotao. - O tringulo amarelo sofreu uma transformao de escala. triangulo.java import net.java.games.jogl.*; public class triangulo { float[][] P; triangulo() { P = new float[3][3]; P[1][0] = 0.5f; P[2][0] = 0.25f; P[2][1] = 0.43f; } public void render_triangulo(GLDrawable drawable) { GL gl = drawable.getGL(); gl.glBegin(GL.GL_TRIANGLES); gl.glVertex3f(P[0][0],P[0][1],P[0][2]); gl.glVertex3f(P[1][0],P[1][1],P[1][2]); gl.glVertex3f(P[2][0],P[2][1],P[2][2]); gl.glEnd(); } }

main.java import java.awt.*; import java.awt.event.*; import net.java.games.jogl.*; public class main { static triangulo Q; static GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); public static void main(String[] args) { Frame frame = new Frame("Cubo V02"); canvas.addGLEventListener( new JoglRender() ); frame.add(canvas); frame.setSize(600, 600); frame.setLocation(50,50); frame.addWindowListener(new WindowAdapter() { 10

public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); } static class JoglRender implements GLEventListener { public void init(GLDrawable drawable) { GL gl = drawable.getGL(); GLU glu = drawable.getGLU(); Q = new triangulo(); } public void display(GLDrawable drawable) { GL gl = drawable.getGL(); GLU glu = drawable.getGLU(); gl.glClearColor(0.0f,0.0f,0.0f,1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glColor3f(1.0f,0.0f,0.0f); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); Q.render_triangulo(drawable); gl.glColor3f(0.0f,1.0f,0.0f); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); gl.glTranslatef( 0.5f, 0.5f,0.0f); Q.render_triangulo(drawable); gl.glLoadIdentity(); gl.glColor3f(0.0f,0.0f,1.0f); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); gl.glRotatef(45,0.0f,0.0f,1.0f); Q.render_triangulo(drawable); gl.glLoadIdentity(); gl.glColor3f(1.0f,1.0f,0.0f); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); gl.glScalef(0.5f, 0.5f,0.5f); Q.render_triangulo(drawable); gl.glLoadIdentity(); gl.glFlush(); } public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) { } public void reshape(GLDrawable drawable, int x, int y, int width, int height) { } 11

} }

1.6- Projeo Ortogrfica


Em uma projeo ortogrfica, ns estabelecemos um volume de visualizao (que corresponde a um paraleleppedo retngulo). O objeto s ser visualizado se ele estiver contido neste volume.

O comando utilizado : glOrtho(double left, double right, double bottom, double top, double near, double far);

1.7- Projeo Perspectiva

12

Em uma projeo perspectiva, ns estabelecemos um cone de visualizao. O comando utilizado : void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble near, GLdouble far);

1.8- ngulos de Euler


Um sistema de referncia que ir nos auxiliar na montagem do ambiente 3D so ao ngulos de Euler. Os ngulos de Euler so definidos como trs sucessivos ngulos de rotao atravs do qual definiremos um novo sistema de coordenadas partindo das coordenadas cartesianas. No Opengl o sistema de coordenadas est posicionado conforme o desenho abaixo, onde o eixo x est na posio horizontal, o eixo y na posio vertical e o eixo z est apontando para fora da tela do computador.

A seqncia inicia rotacionando o sistema de coordenadas xyz por um ngulo torno do eixo z.

no sentido anti-horrio em

Em seguida o sistema de coordenadas resultante rotacionado em torno do eixo y de

graus. 13

Por fim o sistema de coordenadas sofre uma nova rotao de

em torno do eixo z.

Estes trs ngulos definem os ngulos de Euler.

1.8 - Criando um Ambiente de Visualizao 3D


Vamos montar um ambiente para visualizao tri-dimensional, atravs do qual poderemos visualizar nossos objetos 3D.

1.8.1- Mdulo Bsico de Visualizao


Como primeiro passo vamos desenhar os trs eixos de referencia, mantendo a seguinte escala de cores: - Eixo x: vermelho - Eixo y: verde - Eixo z: azul Uma posio inicial para a visualizao pode ser obtida utilizando-se os ngulos theta = 135, phi = 45, gamma=90. main.java import java.awt.*; import java.awt.event.*; import net.java.games.jogl.*; public class main { static dominio D = new dominio(); static GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); public static void main(String[] args) { Frame frame = new Frame("Dominio 3D"); canvas.addGLEventListener( new JoglRender() ); 14

frame.add(canvas); frame.setSize(600, 600); frame.setLocation(50,50); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); } static class JoglRender implements GLEventListener { public void init(GLDrawable drawable) { GL gl = drawable.getGL(); D.init(gl); } public void display(GLDrawable drawable) { GL gl = drawable.getGL(); GLU glu = drawable.getGLU(); gl.glClearColor(0.0f,0.0f,0.0f,1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glColor3f(1.0f,0.0f,0.0f); D.plota_eixo(drawable); gl.glFlush(); } public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) { } public void reshape(GLDrawable drawable, int x, int y, int width, int height) { } } } Dominio.java import net.java.games.jogl.*; public class dominio { float xmin,xmax,ymin,ymax,zmin,zmax; float gama,phi,theta; dominio() xmin = xmax = gama = phi = theta= } { ymin = zmin = -1; ymax = zmax = 1; 90; 45; 135;

15

dominio(float xm,float ym,float zm,float xM,float yM,float zM) { xmin = xm; ymin = ym; zmin = zm; xmax = xM; ymax = yM; zmax = zM; gama = 90; phi = 45; theta= 135; } public void plota_eixo(GLDrawable drawable) { GL gl = drawable.getGL(); gl.glColor3f (1.0f, 0.0f, 0.0f); gl.glBegin (GL.GL_LINES); gl.glVertex3f (xmax,0,0); gl.glVertex3f (0,0,0); gl.glEnd(); gl.glColor3f (0.0f, 1.0f, 0.0f); gl.glBegin (GL.GL_LINES); gl.glVertex3f (0,0,0); gl.glVertex3f (0,ymax,0); gl.glEnd(); gl.glColor3f (0.0f, 0.0f, 1.0f); gl.glBegin (GL.GL_LINES); gl.glVertex3f (0,0,0); gl.glVertex3f (0,0,zmax); gl.glEnd();

public void init(GL gl) { gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); gl.glOrtho(xmin,xmax, ymin,ymax, zmin,zmax); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); gl.glRotatef(gama ,0,0,1); gl.glRotatef(phi ,0,1,0); gl.glRotatef(theta,0,0,1); } public void set_angle(float g,float p,float t) { gama = g; phi = p; theta = t; } }

1.8.2- Alterando os ngulos de Euler


Vamos agora acrescentar a possibilidade de alterar os ngulos com auxlio do mouse. Com o boto Esquerdo do mouse pressionado, quando o mouse anda na direo horizontal, alteramos theta, quando o muse anda na direo vertical alteramos phi. 16

main.java import java.awt.*; import java.awt.event.*; import net.java.games.jogl.*; public class main { static dominio D = new dominio(); static int xm,xb,ym,yb; static float gama,phi,theta; static GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); public static void main(String[] args) { Frame frame = new Frame("Dominio 3D"); canvas.addGLEventListener( new JoglRender() ); canvas.addMouseListener( new JoglMouse() ); canvas.addMouseMotionListener( new JoglMouseMotion() ); frame.add(canvas); frame.setSize(600, 600); frame.setLocation(50,50); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); } static class JoglRender implements GLEventListener { public void init(GLDrawable drawable) { GL gl = drawable.getGL(); gama = 90; phi = 45; theta = 135; D .init(gl); } public void display(GLDrawable drawable) { GL gl = drawable.getGL(); GLU glu = drawable.getGLU(); D.init(gl); gl.glClearColor(0.0f,0.0f,0.0f,1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glColor3f(1.0f,0.0f,0.0f); D.plota_eixo(drawable); gl.glFlush(); } public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) { } public void reshape(GLDrawable drawable, int x, int y, 17

int width, int height) { } }

static class JoglMouse implements MouseListener { public void mouseEntered(MouseEvent e) { // System.out.println("Mouse Entra"); } public void mouseExited (MouseEvent e) { // System.out.println("Mouse Sai"); } public void mousePressed(MouseEvent e) { if (e.getButton()==1) { System.out.println("Entra"); xb = e.getX(); yb = e.getY(); } } public void mouseReleased(MouseEvent e) { if (e.getButton()==1) { theta = theta + xm - xb; phi = phi - ym + yb ; D.set_angle(gama,phi,theta); canvas.display(); } } public void mouseClicked(MouseEvent e) { System.out.println("Mouse botao"); } } static class JoglMouseMotion implements MouseMotionListener {

public void mouseDragged(MouseEvent e) { if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) { xm = e.getX(); ym = e.getY(); theta = theta + xm - xb; phi = phi - ym + yb ; D.set_angle(gama,phi,theta); theta = theta - xm + xb; phi = phi + ym - yb; canvas.display(); } } public void mouseMoved(MouseEvent e) { }

} }

18

1.9 Visualizao de grfico de funes


A seguir apresentamos um programa exemplo para visualizao de grficos de funes main.java .

import java.awt.*; import java.awt.event.*; import net.java.games.jogl.*; public class main { static dominio D = new dominio(); static funcao f = new funcao(); static int xm,xb,ym,yb; static float gama,phi,theta; static float scale; static GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new LCapabilities()); public static void main(String[] args) { Frame frame = new Frame("Funcao 3D"); canvas.addGLEventListener( new JoglRender() ); canvas.addMouseListener( new JoglMouse() ); canvas.addMouseMotionListener( new JoglMouseMotion() ); canvas.addMouseWheelListener( new JoglMouseWheel() ); frame.add(canvas); frame.setSize(600, 600); frame.setLocation(50,50); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); } static class JoglRender implements GLEventListener { public void init(GLDrawable drawable) { GL gl = drawable.getGL(); gama = 90; phi = 45; theta = 135; D .init(gl); } public void display(GLDrawable drawable) { GL gl = drawable.getGL(); GLU glu = drawable.getGLU(); D.init(gl); gl.glClearColor(0.0f,0.0f,0.0f,1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
19

gl.glColor3f(1.0f,0.0f,0.0f); D.plota_eixo(drawable); f.plota_funcao(drawable); gl.glFlush(); } public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) { } public void reshape(GLDrawable drawable, int x, int y, int width, int height) { } } static class JoglMouse implements MouseListener { public void mouseEntered(MouseEvent e) { // System.out.println("Mouse Entra"); } public void mouseExited (MouseEvent e) { // System.out.println("Mouse Sai"); } public void mousePressed(MouseEvent e) { if (e.getButton()==1) { System.out.println("Entra"); xb = e.getX(); yb = e.getY(); } } public void mouseReleased(MouseEvent e) { if (e.getButton()==1) { theta = theta + xm - xb; phi = phi - ym + yb ; D.set_angle(gama,phi,theta); canvas.display(); } } public void mouseClicked(MouseEvent e) { System.out.println("Mouse botao"); } } static class JoglMouseMotion implements MouseMotionListener { public void mouseDragged(MouseEvent e) { if ((e.getModifiers() &
20

InputEvent.BUTTON1_MASK) != 0) { xm = e.getX(); ym = e.getY(); theta = theta + xm - xb; phi = phi - ym + yb ; D.set_angle(gama,phi,theta); theta = theta - xm + xb; phi = phi + ym - yb; canvas.display(); } } public void mouseMoved(MouseEvent e) { } } static class JoglMouseWheel implements MouseWheelListener {

public void mouseWheelMoved(MouseWheelEvent e) { scale += e.getWheelRotation()/10.0; D.set_scale(scale); canvas.display(); } } }

funcao.java import net.java.games.jogl.*; public class funcao { float xmin,xmax,ymin,ymax; int points; funcao() { xmin = ymin = -1; xmax = ymax = 1; points = 10; } public float f(float x,float y) { return(x*x+y*y); } public void plota_funcao(GLDrawable drawable) { GL gl = drawable.getGL(); float x,y; float dx = (xmax-xmin)/points; float dy = (ymax-ymin)/points; gl.glColor3f (1.0f, 1.0f, 1.0f); x = xmin; 21

for(int i=0;i<points;i++) { y = ymin; for(int j=0;j<points;j++){ gl.glBegin(GL.GL_LINE_LOOP); gl.glVertex3f(x ,y ,f(x ,y) ); gl.glVertex3f(x+dx,y ,f(x+dx,y) ); gl.glVertex3f(x+dx,y+dy,f(x+dx,y+dy)); gl.glVertex3f(x ,y+dy,f(x ,y+dy)); gl.glEnd(); y += dy; } x += dx; } } }

import net.java.games.jogl.*; public class dominio { float xmin,xmax,ymin,ymax,zmin,zmax; float gama,phi,theta; float scale; dominio() xmin = xmax = gama = phi = theta= scale= } { ymin = zmin = -2; ymax = zmax = 2; 90; 45; 135; 1;

dominio(float xm,float ym,float zm,float xM,float yM,float zM) { xmin = xm; ymin = ym; zmin = zm; xmax = xM; ymax = yM; zmax = zM; gama = 90; phi = 45; theta= 135; scale= 1; } public void plota_eixo(GLDrawable drawable) { GL gl = drawable.getGL(); gl.glColor3f (1.0f, 0.0f, 0.0f); gl.glBegin (GL.GL_LINES); gl.glVertex3f (xmax,0,0); gl.glVertex3f (0,0,0); gl.glEnd(); gl.glColor3f (0.0f, 1.0f, 0.0f); gl.glBegin (GL.GL_LINES); 22

gl.glVertex3f (0,0,0); gl.glVertex3f (0,ymax,0); gl.glEnd(); gl.glColor3f (0.0f, 0.0f, 1.0f); gl.glBegin (GL.GL_LINES); gl.glVertex3f (0,0,0); gl.glVertex3f (0,0,zmax); gl.glEnd(); } public void init(GL gl) { gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); gl.glOrtho(xmin,xmax, ymin,ymax, zmin,zmax); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); gl.glScalef(scale,scale,scale); gl.glRotatef(gama ,0,0,1); gl.glRotatef(phi ,0,1,0); gl.glRotatef(theta,0,0,1); } public void set_angle(float g,float p,float t) { gama = g; phi = p; theta = t; } public void set_scale(float s) { scale = s; } }

23

2- ILUMINAO
Para definir o seu modelo de iluminao so necessrias trs etapas bsicas: 1) Definir as fontes de luz (posio, cor, direo, etc.); 2) Definir a iluminao. 3) Definir o tipo de material do objeto. O modelo de iluminao do OPENGL considera que a iluminao pode ser dividida em trs componentes independentes: ambiente, difusa e especular. - Luz Emitida: a componente que se origina de um objeto e inalterada pelas fontes de luz. - Luz Ambiente: a luz proveniente de uma fonte dispersa tal que sua direo no pode ser determinada. - Luz Difusa: uma luz proveniente de uma nica direo que quando incide sobre o objeto no mantm uma direo preferencial, e se divide em componentes em todas as direes. - Luz Especular: a luz proveniente de uma direo particular e tende a refletir em uma direo preferencial. A cor de uma fonte de luz caracterizada pela intensidade de cada uma de suas componentes: vermelho, verde e azul. O material da superfcie caracterizado pela quantidade de luz refletida ou absorvida. Um material verde, refle a luz verde e absorve as outras componentes, por exemplo. O material tem as mesmas caractersticas de uma fonte de luz, sendo necessrio definir qual o seu comportamento relativo a luz ambiente, difusa e especular. Vamos iniciar com um simples exemplo, ilustrando as dificuldades de se estabelecer uma boa iluminao. Nosso primeiro exemplo um cubo, com uma face amarela e outra verde, onde se estabeleceu uma iluminao bsica, porm no satisfatria ainda. A classe Iluminacao contem alguns parmetros bsicos. main.java public class main { static dominio D = new dominio(); static Iluminacao I = new Iluminacao(); static cubo C = new cubo(); ... static class JoglRender implements GLEventListener { public void init(GLDrawable drawable) { GL gl = drawable.getGL(); gama = 90; phi = 45; theta = 135; D.init(drawable); I.light_on(drawable); } public void display(GLDrawable drawable) { GL gl = drawable.getGL(); D.init(drawable); gl.glClearColor(0.0f,0.0f,0.0f,1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); D.plota_eixo(drawable); I.render_light(drawable); 24

I.light_on(drawable); C.render_cubo(drawable); I.light_off(drawable); gl.glFlush(); } ... } dominio.java public class dominio { ... public void init(GLDrawable drawable) { ... gl.glRotatef(phi ,0,1,0); gl.glRotatef(theta,0,0,1); gl.glEnable(GL.GL_DEPTH_TEST); }

cubo.java public class cubo { ... public void render_cubo(GLDrawable drawable) { GL gl = drawable.getGL(); gl.glColor3f(1,1,0); gl.glBegin(GL.GL_QUADS); gl.glNormal3f(0,0,1); gl.glVertex3f(P[0][0],P[0][1],P[0][2]); gl.glVertex3f(P[1][0],P[1][1],P[1][2]); gl.glVertex3f(P[2][0],P[2][1],P[2][2]); gl.glVertex3f(P[3][0],P[3][1],P[3][2]); gl.glEnd(); gl.glColor3f(0,1,0); gl.glBegin(GL.GL_QUADS); gl.glNormal3f(0,0,1); gl.glVertex3f(P[4][0],P[4][1],P[4][2]); gl.glVertex3f(P[5][0],P[5][1],P[4][2]); gl.glVertex3f(P[6][0],P[6][1],P[4][2]); gl.glVertex3f(P[7][0],P[7][1],P[4][2]); gl.glEnd(); gl.glColor3f(1,0,1); gl.glBegin(GL.GL_LINES); gl.glVertex3f(P[0][0],P[0][1],P[0][2]); gl.glVertex3f(P[4][0],P[4][1],P[4][2]); gl.glVertex3f(P[1][0],P[1][1],P[1][2]); gl.glVertex3f(P[5][0],P[5][1],P[5][2]); gl.glVertex3f(P[2][0],P[2][1],P[2][2]); gl.glVertex3f(P[6][0],P[6][1],P[6][2]); gl.glVertex3f(P[3][0],P[3][1],P[3][2]); 25

gl.glVertex3f(P[7][0],P[7][1],P[7][2]); gl.glEnd(); } } ...

Iluminacao.java import net.java.games.jogl.*; public class Iluminacao { float[] mat_specular; float[] mat_shininess; float[] light_position; Iluminacao() { mat_specular = new float[4]; mat_specular[0] = 1.0f; mat_specular[1] = 1.0f; mat_specular[2] = 1.0f; mat_specular[3] = 1.0f; mat_shininess = new float[1]; mat_shininess[0] = 50.0f; light_position = new float[4]; light_position[0] = 2.0f; light_position[1] = 2.0f; light_position[2] = 2.0f; light_position[3] = 1.0f;

public void light_on(GLDrawable drawable) { GL gl = drawable.getGL(); gl.glShadeModel (GL.GL_SMOOTH); gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, mat_specular); gl.glMaterialfv(GL.GL_FRONT, GL.GL_SHININESS, mat_shininess); gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, light_position); gl.glEnable(GL.GL_LIGHTING); gl.glEnable(GL.GL_LIGHT0); gl.glEnable(GL.GL_COLOR_MATERIAL); gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL.GL_DIFFUSE); gl.glEnable(GL.GL_NORMALIZE);

public void render_light(GLDrawable drawable) { GL gl = drawable.getGL(); gl.glColor3f(1,0,0); gl.glPointSize(8); gl.glBegin(GL.GL_POINTS); gl.glVertex3f(light_position[0], light_position[1], light_position[2]); 26

gl.glEnd(); } public void light_off(GLDrawable drawable) { GL gl = drawable.getGL(); gl.glDisable(GL.GL_LIGHTING); gl.glDisable(GL.GL_LIGHT0); gl.glDisable(GL.GL_DEPTH_TEST); } }

2.1 Criando Fontes de Luz


. As fontes de luz tm certas propriedades que devem ser definidas (Cor, direo, posio, etc.). O comando para especificar essas propriedades : void glLightfv(GLenum luz, GLenum iluminao, GLenum param); O parmetro luz indica apenas qual fonte de luz estamos trabalhando. Existem no mximo oito fontes que so: GL_LIGHT0, GL_LIGHT1, ... , GL_LIGHT7. Por default a luz GL_LIGHT0 inicia com a cor branca e as sete luzes restantes ficam apagadas (luz preta). Os parmetros da iluminao so: Parmetro GL_AMBIENT GL_DIFFUSE GL_SPECULAR GL_POSITION GL_SPOT_DIRECTION GL_SPOT_EXPONENT GL_SPOT_CUTOFF GL_CONSTANT_ATTENUATION GL_LINEAR_ATTENUATION GL_QUADRATIC_ATTENUATION Valor default (0.0, 0.0, 0.0, 1.0) (1.0, 1.0, 1.0, 1.0) (1.0, 1.0, 1.0, 1.0) (0.0, 0.0, 1.0, 0.0) (0.0, 0.0, -1.0) 0.0 180.0 1.0 0.0 0.0 Significado Intensidade da luz ambiente Intensidade da luz difusa Intensidade da luz especular posio da luz direo da luz Parmetro que controla a distribuio da luz. ngulo de abertura da luz

2.1.1 Cor
A caracterstica da luz definida pelo parmetro iluminao. O modelo de iluminao do OPENGL considera que a iluminao pode ser dividida em quatro componentes independentes: emitida, ambiente, difusa e especular. - Luz Emitida: a componente que se origina de um objeto e inalterada pelas fontes de luz. - Luz Ambiente: a luz proveniente de uma fonte dispersa tal que sua direo no pode ser determinada. - Luz Difusa: a luz proveniente de uma nica direo que ao incidir sobre a superfcie do material, se reflete em todas as direes. Define a luz que naturalmente definiramos como a cor da luz. - Luz Especular: a luz proveniente de uma direo particular e tende a refletir em uma direo preferencial. Se voc quer criar efeitos realsticos, mantenha a luz especular com os mesmos parmetros da luz difusa. Por exemplo, para alterar a luz ambiente utiliza-se o seguinte cdigo: GLfloat luz_ambiente[4] = { 0.0, 0.0, 0.0, 1.0 }; 27

glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambiente);

2.1.2 Posio
A posio da luz pode ser de dois tipos bsicos: Direcional: quando a fonte de luz considerada no infinito. Neste caso os raios de luz incidem paralelos ao objeto. Para obter, por exemplo, uma fonte de luz branca voc deve utilizar o seguinte cdigo:

GLfloat luz_posicao[4] = { 1.0, 1.0, 1.0, 0.0 }; glLightfv(GL_LIGHT0, GL_POSITION, luz_posicao); Posicional : Se o ltimo valor do vetor luz_posicao[] for diferente de zero, a luz posicional e sua localizao definida pelo vetor luz_posicao[4]={x , y, z, 1.0}.

2.2 Selecionando o Modelo de Iluminao


2.2.1- Luz Ambiente Global
Cada fonte de luz pode contribuir com uma parcela da luz ambiente. Alm disso possvel adicionar uma outra parcela de luz ambiente que no dependa das fontes de iluminao. Para isso utiliza-se o comando: GLfloat luz_ambiente_modelo[4] = { 0.2, 0.2, 0.2, 1.0 }; glLightModelfv(GL_LIGHT_MODEL_AMBIENT, luz_ambiente_modelo); Observe que neste caso, mesmo que todas as fontes de luz estejam desligadas ainda assim ser possvel ver os objetos na cena.

2.2.2 Posio do observador local ou no infinito


A localizao do observador pode ou no influenciar na iluminao. O default o observador no infinito. Para mudar a configurao, considerando-se a iluminao conforme o observador utilize: glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);

2.2.3 Iluminao nos dois lados das faces


O clculo da iluminao feito para todos os polgonos. possvel considerar diferentes iluminaes nos dois lados de um polgono. Para isso utilize: glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);

2.2.4 Habilitando a iluminao


No OpenGL voc precisa explicitamente habilitar a iluminao. Para isso utilize o comando: glEnable(GL_LIGHTING); Para desabilitar basta utilizar o comando: glDisable(GL_LIGHTING); 28

2.3 Selecionando as Propriedades do Material


Para definir as propriedades do material do objeto em cena utilizamos os seguinte comando: void glMaterialfv(GLenum face, GLenum iluminacao, TYPE param); O parmetro face pode ser: GL_FRONT, GL_BACK ou GL_FRONT_AND_BACK. Os parmetros da iluminao so: Parmetro GL_AMBIENT GL_DIFFUSE GL_SPECULAR GL_SHININESS GL_EMISSION Valor default (0.2, 0.2, 0.2, 1.0) (0.8, 0.8, 0.8, 1.0) (0.0, 0.0, 0.0, 1.0) 0.0 (0.0, 0.0, 0.0, 1.0) Significado Cor da luz ambiente do material Cor da luz difusa do material Especular cor do material ndice especular Cor de emisso do material

2.4 Exemplo 1
Como exemplo, inserimos o modulo de iluminacao no programa funcao3D. funcao.java import net.java.games.jogl.*; public class funcao { float xmin,xmax,ymin,ymax; int points; funcao() { xmin = ymin = -2; xmax = ymax = 2; points = 40; } // public float f(float x,float y) { return(x*x-y*y); return((float)Math.cos(Math.sqrt(x*x+y*y))); } public void plota_funcao(GLDrawable drawable) { GL gl = drawable.getGL(); float x,y; float dx = (xmax-xmin)/points; float dy = (ymax-ymin)/points; float[] v; gl.glColor3f (1.0f, 1.0f, 1.0f); 29

x = xmin; for(int i=0;i<points;i++) { y = ymin; for(int j=0;j<points;j++){ gl.glBegin(GL.GL_QUADS); v = normal(x,y); gl.glNormal3f(v[0],v[1],v[2]); gl.glVertex3f(x ,y ,f(x ,y) ); v = normal(x+dx,y); gl.glNormal3f(v[0],v[1],v[2]); gl.glVertex3f(x+dx,y ,f(x+dx,y) ); v = normal(x+dx,y+dy); gl.glNormal3f(v[0],v[1],v[2]); gl.glVertex3f(x+dx,y+dy,f(x+dx,y+dy)); v = normal(x,y+dy); gl.glNormal3f(v[0],v[1],v[2]); gl.glVertex3f(x ,y+dy,f(x ,y+dy)); gl.glEnd(); y += dy; } x += dx; } } public float dfx(float x,float y) { // return(2*x); return((float)(-Math.sin(Math.sqrt(x*x+y*y))*x/Math.sqrt(x*x+y*y))); } public float dfy(float x,float y) { // return(-2*y); return((float)(-Math.sin(Math.sqrt(x*x+y*y))*y/Math.sqrt(x*x+y*y)) ); } public float[] normal(float x,float y) { float[] v = new float[3]; v[0] = -dfx(x,y); v[1] = -dfy(x,y); v[2] = 1; return(v); } }

main.java import net.java.games.jogl.*; public class main { static static static static static static dominio D = new dominio(); funcao f = new funcao(); Iluminacao I = new Iluminacao(); int xm,xb,ym,yb,mov=0; float gama,phi,theta; float scale; 30

static GLCanvas canvas GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); public static void main(String[] args) {

Frame frame = new Frame("Funcao 3D"); canvas.addGLEventListener( new JoglRender() ); canvas.addMouseListener( new JoglMouse() ); canvas.addMouseMotionListener( new JoglMouseMotion() ); canvas.addMouseWheelListener( new JoglMouseWheel() ); frame.add(canvas); frame.setSize(600, 600); frame.setLocation(50,50); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); } static class JoglRender implements GLEventListener { public void init(GLDrawable drawable) { gama = 90; phi = 45; theta = 135; D .init(drawable); } public void display(GLDrawable drawable) { GL gl = drawable.getGL(); D.init(drawable); gl.glClearColor(0.0f,0.0f,0.0f,1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); gl.glColor3f(1.0f,0.0f,0.0f); D.plota_eixo(drawable); I.render_light(drawable); I.light_on(drawable); f.plota_funcao(drawable); I.light_off(drawable); gl.glFlush(); ...

} } Iluminacao.java

import net.java.games.jogl.*; public class Iluminacao { float[] float[] float[] float[] mat_specular; mat_shininess; light_position; light_diffuse; 31

Iluminacao() {

mat_specular = new float[4]; mat_specular[0] = 1.0f; mat_specular[1] = 1.0f; mat_specular[2] = 0.0f; mat_specular[3] = 1.0f; mat_shininess = new float[1]; mat_shininess[0] = 50.0f; light_position = new float[4]; light_position[0] = 2.0f; light_position[1] = 2.0f; light_position[2] = 2.0f; light_position[3] = 1.0f; light_diffuse = new float[4]; light_diffuse[0] = 1.0f; light_diffuse[1] = 0.0f; light_diffuse[2] = 0.0f; light_diffuse[3] = 1.0f;

public float[] get_light_position() { return(light_position); } public void rotaciona_light() { double x,y; double t = 0.01; Math.sin(t); Math.cos(t); x= y= light_position[0] light_position[0] * * Math.cos(t) Math.sin(t) + light_position[1] light_position[1] * *

light_position[0] = (float)x; light_position[1] = (float)y; } public void light_on(GLDrawable drawable) { GL gl = drawable.getGL(); gl.glShadeModel (GL.GL_SMOOTH); gl.glMaterialfv(GL.GL_FRONT, GL.GL_SPECULAR, mat_specular); gl.glMaterialfv(GL.GL_FRONT, GL.GL_SHININESS, mat_shininess); gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, light_position); gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE , light_diffuse); gl.glEnable(GL.GL_LIGHTING); gl.glEnable(GL.GL_LIGHT0); gl.glEnable(GL.GL_COLOR_MATERIAL); gl.glColorMaterial(GL.GL_FRONT_AND_BACK, GL.GL_DIFFUSE); gl.glEnable(GL.GL_NORMALIZE); } public void render_light(GLDrawable drawable) { GL gl = drawable.getGL(); 32

gl.glColor3f(1,1,1); gl.glPointSize(8); gl.glBegin(GL.GL_POINTS); ); gl.glVertex3f(light_position[0],light_position[1],light_position[2] gl.glEnd(); } public void light_off(GLDrawable drawable) { GL gl = drawable.getGL(); gl.glDisable(GL.GL_LIGHTING); gl.glDisable(GL.GL_LIGHT0); gl.glDisable(GL.GL_DEPTH_TEST);

// }

dominio.java import net.java.games.jogl.*; public class dominio { float float float float xmin,xmax,ymin,ymax,zmin,zmax; gama,phi,theta; scale; aa,bb; { ymin = zmin = -5; ymax = zmax = 5; 90; 45; 135; 1;

dominio() xmin = xmax = gama = phi = theta= scale= } {

dominio(float xm,float ym,float zm,float xM,float yM,float zM) xmin = ymin = zmin = xmax = ymax = zmax = gama = phi = theta= } public void plota_eixo(GLDrawable drawable) { GL gl = drawable.getGL(); gl.glColor3f (1.0f, 0.0f, 0.0f); gl.glBegin (GL.GL_LINES); gl.glVertex3f (xmax,0,0); gl.glVertex3f (0,0,0); 33 xm; ym; zm; xM; yM; zM; 90; 45; 135;

gl.glEnd(); gl.glColor3f (0.0f, 1.0f, 0.0f); gl.glBegin (GL.GL_LINES); gl.glVertex3f (0,0,0); gl.glVertex3f (0,ymax,0); gl.glEnd(); gl.glColor3f (0.0f, 0.0f, 1.0f); gl.glBegin (GL.GL_LINES); gl.glVertex3f (0,0,0); gl.glVertex3f (0,0,zmax); gl.glEnd();

public void init(GLDrawable drawable) { GL gl = drawable.getGL(); GLU glu = drawable.getGLU(); gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); gl.glOrtho(xmin,xmax, ymin,ymax, zmin,zmax); glu.gluPerspective(40.0,1.0,0.1,40); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); gl.glTranslatef(0,0,-10); gl.glScalef(scale,scale,scale); gl.glRotatef(gama ,0,0,1); gl.glRotatef(phi ,0,1,0); gl.glRotatef(theta,0,0,1); gl.glEnable(GL.GL_DEPTH_TEST); } public void set_angle(float g,float p,float t) { gama = g; phi = p; theta = t; } public void set_scale(float s) { scale = s; } }

// // //

2.5 Comando glLookAt


O comando glLookAt permite que voc defina a visualizao por trs parmetros: 1) A posio do observador (ox,oy,oz). 2) ,A direo em que o observador est olhando (dx,dy,dz). 3) A posio da camera (px,py,pz).

34

Assim a sintaxe do comando glLookAt(ox,oy,oz, dx,dy,dz, px,py,pz). Podemos criar interessantes efeitos, movimentando o observador sobre uma curva paramtrica, por exemplo, ou movimentando a fonte de iluminao ao mesmo tempo, etc. No exemplo abaixo, o observador se desloca sobre uma helice olhando sempre para a origem do sistema. dominio.java public void init(GLDrawable drawable) { GL gl = drawable.getGL(); GLU glu = drawable.getGLU(); gl.glMatrixMode(GL.GL_PROJECTION); gl.glLoadIdentity(); glu.gluPerspective(40.0,1.0,0.1,40); gl.glMatrixMode(GL.GL_MODELVIEW); gl.glLoadIdentity(); gl.glScalef(scale,scale,scale); glu.gluLookAt(2.1*Math.cos(t), 2.1*Math.sin(t), t+0.01, 0,0,0 ,0,0,1); t -= 0.01; gl.glEnable(GL.GL_DEPTH_TEST); } curva.java import net.java.games.jogl.*; public class curva { float tmin,tmax; int points; curva() { tmin = 0; tmax = 10; points = 80; } public float[] c(float t) { float[] p = new float[3]; p[0] = 2*(float)Math.cos(t); p[1] = 2*(float)Math.sin(t); p[2] = (float)t; return(p); } public void plota_curva(GLDrawable drawable) { GL gl = drawable.getGL(); float t; float dt = (tmax-tmin)/points; float[] v; gl.glColor3f (1.0f, 1.0f, 1.0f); gl.glBegin(GL.GL_LINE_STRIP); t = tmin; for(int i=0;i<points;i++) { 35

} }

} gl.glEnd();

v = c(t); gl.glVertex3f(v[0],v[1],v[2]); t += dt;

2.6 Visualizando as normais


Podemos acrescentar um novo metodo para visualizarmos as normais sobre a superfcie.

public void plota_normal(GLDrawable drawable) { GL gl = drawable.getGL(); float x,y; float dx = (xmax-xmin)/points; float dy = (ymax-ymin)/points; float[] v; float n = 10; gl.glColor3f (1.0f, 1.0f, 1.0f); x = xmin; for(int i=0;i<points;i++) { y = ymin; for(int j=0;j<points;j++){ gl.glBegin(GL.GL_LINES); v = normal(x,y); gl.glNormal3f(v[0],v[1],v[2]); gl.glVertex3f(x ,y ,f(x ,y) ); gl.glVertex3f(x+v[0]/n,y+v[1]/n,f(x ,y)+v[2]/n); v = normal(x+dx,y); gl.glNormal3f(v[0],v[1],v[2]); gl.glVertex3f(x+dx,y ,f(x+dx,y) ); gl.glVertex3f(x+dx+v[0]/n,y+v[1]/n,f(x+dx,y)+v[2]/n); v = normal(x+dx,y+dy); gl.glNormal3f(v[0],v[1],v[2]); gl.glVertex3f(x+dx,y+dy,f(x+dx,y+dy)); gl.glVertex3f(x+dx+v[0]/n,y+dy+v[1]/n,f(x+dx,y+dy)+v[2]/n); v = normal(x,y+dy); gl.glNormal3f(v[0],v[1],v[2]); gl.glVertex3f(x ,y+dy,f(x ,y+dy)); gl.glVertex3f(x+v[0]/n,y+dy+v[1]/n,f(x,y+dy)+v[2]/n); gl.glEnd(); 36

} }

y += dy; } x += dx;

3- SUPERFCIES PARAMETRIZADAS
Para compreender a idia de uma superfcie parametrizada, considere D uma regio do plano, cujas variveis so denotadas por . A cada par de D vamos associar um ponto no espao tridimensional, o qual pode ser escrito em termos de suas funes coordenadas por:

Uma superfcie parametrizada uma aplicao superfcie S correspondente a funo parmetros (u, v). a imagem

onde D algum domnio em

. A

. A superfcie parametrizada depende de dois

3.1 Visualizao de superfcies na forma paramtrica


. Para visualizar superfcies dadas na forma paramtrica, utilizaremos o programa abaixo. O programa composto de dois mdulos: sup_main.cpp e sup_param.cpp. O mdulo sup_main.cpp responsvel pelas tarefas de iluminao e definio do ambiente OpenGL. O segundo mdulo sup_param.cpp define a parametrizao e atravs da funo draw_superficie(), visualiza a superfcie desejada. 37

import net.java.games.jogl.*; public class parametrico { float vmin,vmax,umin,umax; int points; parametrico() { vmin = umin = 0; vmax = (float)Math.PI; umax = 2*(float)Math.PI; points = 40; } public float[] superficie(float u,float v) { float[] r = new float[3]; r[0] = (float)(Math.cos(u) * Math.sin(v)); r[1] = (float)(Math.sin(u) * Math.sin(v)); r[2] = (float)(Math.cos(v)); r[0] = (float)(-Math.sin(u)*(2+Math.cos(v))); r[1] = (float)(Math.cos(u)*(2+Math.cos(v))); r[2] = (float)(Math.sin(v)); return(r); plota_superficie(GLDrawable drawable) { = drawable.getGL(); u,v; du = (umax-umin)/points; dv = (vmax-vmin)/points;

public void GL gl float float float

float[] r,n; gl.glColor3f (1.0f, 1.0f, 1.0f); u = umin; for(int i=0;i<points;i++) { v = vmin; for(int j=0;j<points;j++){ gl.glBegin(GL.GL_QUADS); n = normal(u,v); r = superficie(u,v); gl.glNormal3f(n[0],n[1],n[2]); gl.glVertex3f(r[0],r[1],r[2]); n = normal(u+du,v); r = superficie(u+du,v); gl.glNormal3f(n[0],n[1],n[2]); gl.glVertex3f(r[0],r[1],r[2]); n = normal(u+du,v+dv); r = superficie(u+du,v+dv); gl.glNormal3f(n[0],n[1],n[2]); gl.glVertex3f(r[0],r[1],r[2]); n = normal(u,v+dv); r = superficie(u,v+dv); gl.glNormal3f(n[0],n[1],n[2]); gl.glVertex3f(r[0],r[1],r[2]); 38

} u += du;

gl.glEnd(); v += dv;

public float[] normal(float u,float v) { float[] v1 = new float[3]; float[] v2 = new float[3]; float[] n = new float[3]; float norma; float[] p1 = new float[3]; float[] p2 = new float[3]; float[] p3 = new float[3]; float du = (umax-umin)/points; float dv = (vmax-vmin)/points; p1 = superficie(u,v); p2 = superficie(u,v+dv); p3 = superficie(u+du,v); v1[0] = p2[0]-p1[0] ; v1[1] = p2[1]-p1[1]; v1[2] = p2[2]-p1[2]; v2[0] = p3[0]-p1[0]; v2[1] = p3[1]-p1[1]; v2[2] = p3[2]-p1[2]; n[0] = v1[1] * v2[2] - v1[2] * v2[1]; n[1] = -v1[0] * v2[2] + v1[2] * v2[0]; n[2] = v1[0] * v2[1] - v1[1] * v2[0]; norma = (float)Math.sqrt(n[0] * n[0] + n[1] *n[1] + n[2] * n[2]); n[0] = -n[0] / norma; n[1] = -n[1] / norma; n[2] = -n[2] / norma; return(n); } }

3.2 Exerccios
1) Utilizando o programa anterior, visualize as seguintes superfcies e identifique-as: a) b) c) d)

39

e)

f)

g)

2) Visualize os vetores normais sobre a superfcie. Observe o exemplo da letra f).

40

4- SUPERFCIES IMPLCITAS
main.java import net.java.games.jogl.*; public class main { static dominio D = new dominio(); static superficie f = new superficie(); static Iluminacao I = new Iluminacao(); static int xm,xb,ym,yb,mov=0; static float gama,phi,theta; static float scale; static GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); public static void main(String[] args) { Frame frame = new Frame("Superficie Implicita");

canvas.addGLEventListener( new JoglRender() ); canvas.addMouseListener( new JoglMouse() ); canvas.addMouseMotionListener( new JoglMouseMotion() ); canvas.addMouseWheelListener( new JoglMouseWheel() ); frame.add(canvas); frame.setSize(600, 600); frame.setLocation(50,50); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); } static class JoglRender implements GLEventListener { public void init(GLDrawable drawable) { gama = 90; phi = 45; theta = 135; D.init(drawable); f.set_draw(drawable); } public void display(GLDrawable drawable) { GL gl = drawable.getGL(); D.init(drawable); gl.glClearColor(0.0f,0.0f,0.0f,1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT); D.plota_eixo(drawable); I.render_light(drawable); I.light_on(drawable); f.plota_funcao(); I.light_off(drawable); 41

gl.glFlush(); } public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) { } public void reshape(GLDrawable drawable, int x, int y, int width, int height) { }

static class JoglMouse implements MouseListener { public void mouseEntered(MouseEvent e) { // System.out.println("Mouse Entra"); } public void mouseExited (MouseEvent e) { // System.out.println("Mouse Sai"); } public void mousePressed(MouseEvent e) { if (e.getButton()==1) { xb = e.getX(); yb = e.getY(); } if (e.getButton()==3) { mov = (mov+1) % 2; if (mov == 0) System.out.println("Scala "); else System.out.println("Resolucao "); } } public void mouseReleased(MouseEvent e) { if (e.getButton()==1) { theta = theta + xm - xb; phi = phi - ym + yb ; D.set_angle(gama,phi,theta); canvas.display(); }

public void mouseClicked(MouseEvent e) { System.out.println("Mouse botao"); } } static class JoglMouseMotion implements MouseMotionListener

42

public void mouseDragged(MouseEvent e) { if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) { xm = e.getX(); ym = e.getY(); theta = theta + xm - xb; phi = phi - ym + yb ; D.set_angle(gama,phi,theta); theta = theta - xm + xb; phi = phi + ym - yb; canvas.display();

} }

public void mouseMoved(MouseEvent e) { } } static class JoglMouseWheel implements MouseWheelListener {

public void mouseWheelMoved(MouseWheelEvent e) { if (mov == 0){ scale += e.getWheelRotation()/10.0; D.set_scale(scale); canvas.display(); } else { int p = f.get_pontos(); p += e.getWheelRotation(); if (p <= 0) p = 1; f.set_pontos(p); canvas.display(); } } } superficie.java import net.java.games.jogl.*; public class superficie { float xmin,xmax,ymin,ymax,zmin,zmax; int pontos; GLDrawable drawable; superficie() { xmin = ymin xmax = ymax pontos = 5; } = zmin = -2; = zmax = 2; }

public int get_pontos() { 43

return pontos; } public void set_pontos(int p) { pontos = p; } public void set_draw(GLDrawable draw) { drawable = draw; } // public float f(float x,float y,float z) { return(x*x-y*y-z); return(x*x+(float)Math.cos(x)*y*y-z*y-1); } public void normal(float[] v, float x,float y,float z) { v[0] = 2*x-(float)Math.sin(x)*y*y; v[1] = 2*y*(float)Math.cos(x)-z; v[2] = -y; v[0] = 2*x; v[1] = -2*y; v[2] = -1.0f; }

// // //

void intersect(float[] v,float[] x,float[] y,float[] z,float[] w,int i,int j) { float t; t = w[i]/(w[i]-w[j]); v[0] = x[i] + t * (x[j] - x[i]); v[1] = y[i] + t * (y[j] - y[i]); v[2] = z[i] + t * (z[j] - z[i]); } void tri(float[] x,float[] y,float[] z,float[] w,int i,int j,int k,int l) { GL gl = drawable.getGL(); float[] v1 = new float[3]; float[] v2 = new float[3]; float[] v3 = new float[3]; float[] n = new float[3]; intersect(v1,x,y,z,w,i,j); intersect(v2,x,y,z,w,i,k); intersect(v3,x,y,z,w,i,l); gl.glBegin(GL.GL_TRIANGLES); normal(n,v1[0],v1[1],v1[2]); gl.glNormal3f(n[0],n[1],n[2]); gl.glVertex3f(v1[0],v1[1],v1[2]); normal(n,v2[0],v2[1],v2[2]); gl.glNormal3f(n[0],n[1],n[2]); gl.glVertex3f(v2[0],v2[1],v2[2]); normal(n,v3[0],v3[1],v3[2]); gl.glNormal3f(n[0],n[1],n[2]); gl.glVertex3f(v3[0],v3[1],v3[2]); gl.glEnd(); 44

} void quad(float[] x,float[] y,float[] z,float[] w,int i,int j,int k,int l) { GL gl = drawable.getGL(); float[] v1 = new float[3]; float[] v2 = new float[3]; float[] v3 = new float[3]; float[] v4 = new float[3]; float[] n = new float[3]; intersect(v1,x,y,z,w,i,k); intersect(v2,x,y,z,w,i,l); intersect(v3,x,y,z,w,j,l); intersect(v4,x,y,z,w,j,k); gl.glBegin(GL.GL_TRIANGLES); normal(n,v1[0],v1[1],v1[2]); gl.glNormal3f(n[0],n[1],n[2]); gl.glVertex3f(v1[0],v1[1],v1[2]); normal(n,v2[0],v2[1],v2[2]); gl.glNormal3f(n[0],n[1],n[2]); gl.glVertex3f(v2[0],v2[1],v2[2]); normal(n,v3[0],v3[1],v3[2]); gl.glNormal3f(n[0],n[1],n[2]); gl.glVertex3f(v3[0],v3[1],v3[2]); gl.glEnd(); gl.glBegin(GL.GL_TRIANGLES); normal(n,v1[0],v1[1],v1[2]); gl.glNormal3f(n[0],n[1],n[2]); gl.glVertex3f(v1[0],v1[1],v1[2]); normal(n,v3[0],v3[1],v3[2]); gl.glNormal3f(n[0],n[1],n[2]); gl.glVertex3f(v3[0],v3[1],v3[2]); normal(n,v4[0],v4[1],v4[2]); gl.glNormal3f(n[0],n[1],n[2]); gl.glVertex3f(v4[0],v4[1],v4[2]); gl.glEnd();

void tetraedro(float[] x,float[] y,float[] z,float[] w,int i,int j,int k,int l) { GL gl = drawable.getGL(); // light_on(drawable); gl.glColorMaterial(GL.GL_FRONT, GL.GL_DIFFUSE); gl.glColor3f(1,1,0); gl.glColorMaterial(GL.GL_BACK , GL.GL_DIFFUSE); gl.glColor3f(1,0,0.2f); if (w[i] < 0) { if (w[j] < 0) { if (w[k] < 0) { if (w[l] >= 0) tri(x,y,z,w,l,k,j,i); } else { if (w[l] < 0) tri(x,y,z,w,k,i,j,l); else 45

quad(x,y,z,w,k,l,i,j); } } else { if (w[k] < 0) { if (w[l] < 0) tri(x,y,z,w,j,l,k,i); else quad(x,y,z,w,j,l,k,i); } else { if (w[l] < 0) quad(x,y,z,w,j,k,i,l); else tri(x,y,z,w,i,l,k,j);

} } else { if

} else {

(w[j] < 0) { if (w[k] < 0) { if (w[l] < 0) tri(x,y,z,w,i,j,k,l); else quad(x,y,z,w,i,l,j,k); if (w[l] < 0) quad(x,y,z,w,i,k,l,j); else tri(x,y,z,w,j,l,i,k);

} } else {

if (w[k] < 0) { if (w[l] < 0) quad(x,y,z,w,i,j,k,l); else tri(x,y,z,w,k,l,j,i); } else { } } // if (w[l] < 0) tri(x,y,z,w,l,i,j,k);

} desabilita_lighting(); gl.glColorMaterial(GL.GL_FRONT, GL.GL_DIFFUSE); gl.glColor3f(0.0f,0.0f,1.0f); gl.glBegin(GL.GL_LINE_LOOP); gl.glVertex3f(x[i],y[i],z[i]); gl.glVertex3f(x[j],y[j],z[j]); gl.glVertex3f(x[k],y[k],z[k]); gl.glEnd(); gl.glBegin(GL.GL_LINE_LOOP); gl.glVertex3f(x[i],y[i],z[i]); gl.glVertex3f(x[j],y[j],z[j]); gl.glVertex3f(x[l],y[l],z[l]); gl.glEnd(); 46

gl.glBegin(GL.GL_LINE_LOOP); gl.glVertex3f(x[i],y[i],z[i]); gl.glVertex3f(x[k],y[k],z[k]); gl.glVertex3f(x[l],y[l],z[l]); gl.glEnd(); gl.glBegin(GL.GL_LINE_LOOP); gl.glVertex3f(x[j],y[j],z[j]); gl.glVertex3f(x[k],y[k],z[k]); gl.glVertex3f(x[l],y[l],z[l]); gl.glEnd(); } public void plota_funcao() { GL gl = drawable.getGL(); int i,j,k,l; float x,y,z; float dx,dy,dz; float[] xv,yv,zv,wv; xv = new float[8]; yv = new float[8]; zv = new float[8]; wv = new float[8]; gl.glColor3f(1.0f,1.0f,0.0f); dx = (xmax - xmin)/pontos; dy = (ymax - ymin)/pontos; dz = (zmax - zmin)/pontos; for(i=0;i<pontos;i++) { x = xmin + i * dx; for (l = 0;l < 8;l++) xv[l] = ((l % 2) == 0) ? x : x+dx; for(j=0;j<pontos;j++) { y = ymin + j * dy; for (l = 0;l < 8;l++) yv[l] = ((l % 4) < 2) ? y : y+dy; for(k=0;k<pontos;k++) { z = zmin + k * dz; for (l = 0;l < 8;l++) { zv[l] = (l < 4) ? z : z+dz; wv[l] = f(xv[l],yv[l],zv[l]); } tetraedro(xv,yv,zv,wv,0,1,3,7); tetraedro(xv,yv,zv,wv,0,5,1,7); tetraedro(xv,yv,zv,wv,0,3,2,7); tetraedro(xv,yv,zv,wv,0,2,6,7); tetraedro(xv,yv,zv,wv,0,4,5,7); tetraedro(xv,yv,zv,wv,0,6,4,7); } } } } }

47

5- TEXTURA
Parametrico.java import net.java.games.jogl.*; public class parametrico { float vmin,vmax,umin,umax; int points; parametrico() { vmin = umin = 0; vmax = (float)Math.PI; umax = 2*(float)Math.PI; vmin = umin = -5; umax = vmax = 5; points = 20; } public float[] superficie(float u,float v) { float[] r = new float[3]; r[0] = (float)(Math.cos(u) * Math.sin(v)); r[1] = (float)(Math.sin(u) * Math.sin(v)); r[2] = (float)(Math.cos(v)); r[0] = (float)(-Math.sin(u)*(2+Math.cos(v))); r[1] = (float)(Math.cos(u)*(2+Math.cos(v))); r[2] = (float)(Math.sin(v)); r[0] = u; r[1] = v; r[2] = (float)(Math.cos(Math.sqrt(u*u+v*v))); r[2] = (float)(Math.cos(u)*v); r[2] = (float)((Math.sqrt(u*u+v*v))); r[0] = u*(float)Math.cos(v); r[1] = u*(float)Math.sin(v); r[2] = u; } return(r);

// // //

// // // // //

public void plota_superficie(GLDrawable drawable) { GL gl = drawable.getGL(); float u,v; float du = (umax-umin)/points; float dv = (vmax-vmin)/points; float[] r,n; gl.glColor3f (1.0f, 1.0f, 1.0f); u = umin; for(int i=0;i<points;i++) { v = vmin; for(int j=0;j<points;j++){ gl.glBegin(GL.GL_QUADS); n = normal(u,v); r = superficie(u,v); gl.glNormal3f(n[0],n[1],n[2]); 48

gl.glTexCoord2f(u/10.0f+0.5f, v/10.0f+0.5f); gl.glTexCoord2f(0,0); gl.glTexCoord2f(u/umax, v/vmax); gl.glTexCoord2f(u, v); gl.glVertex3f(r[0],r[1],r[2]); n = normal(u+du,v); r = superficie(u+du,v); gl.glNormal3f(n[0],n[1],n[2]);

gl.glTexCoord2f((u+du)/10.0f+0.5f, v/10.0f+0.5f); gl.glTexCoord2f(0, 1); gl.glTexCoord2f((u+du)/umax, v/vmax); gl.glTexCoord2f(u+du, v); gl.glVertex3f(r[0],r[1],r[2]); n = normal(u+du,v+dv); r = superficie(u+du,v+dv); gl.glNormal3f(n[0],n[1],n[2]); gl.glTexCoord2f((u+du)/10.0f+0.5f, (v+dv)/10.0f+0.5f); gl.glTexCoord2f(1, 1); gl.glTexCoord2f((u+du)/umax, (v+dv)/vmax); gl.glTexCoord2f(u+du, v+dv); gl.glVertex3f(r[0],r[1],r[2]); n = normal(u,v+dv); r = superficie(u,v+dv); gl.glNormal3f(n[0],n[1],n[2]); gl.glTexCoord2f(u/10.0f+0.5f, (v+dv)/10.0f+0.5f); gl.glTexCoord2f(1, 0); gl.glTexCoord2f(u/umax, (v+dv)/vmax); gl.glTexCoord2f(u, v+dv); gl.glVertex3f(r[0],r[1],r[2]); gl.glEnd(); v += dv; } u += du; } } public float[] normal(float u,float v) { float[] v1 = new float[3]; float[] v2 = new float[3]; float[] n = new float[3]; float norma; float[] p1 = new float[3]; float[] p2 = new float[3]; float[] p3 = new float[3]; float du = (umax-umin)/points; float dv = (vmax-vmin)/points; 49

p1 = superficie(u,v); p2 = superficie(u,v+dv); p3 = superficie(u+du,v); v1[0] = p2[0]-p1[0] ; v1[1] = p2[1]-p1[1]; v1[2] = p2[2]-p1[2]; v2[0] = p3[0]-p1[0]; v2[1] = p3[1]-p1[1]; v2[2] = p3[2]-p1[2]; n[0] = v1[1] * v2[2] - v1[2] * v2[1]; n[1] = -v1[0] * v2[2] + v1[2] * v2[0]; n[2] = v1[0] * v2[1] - v1[1] * v2[0]; n[2] * n[2]); norma = (float)Math.sqrt(n[0] * n[0] + n[1] *n[1] + n[0] = -n[0] / norma; n[1] = -n[1] / norma; n[2] = -n[2] / norma; return(n); } } Imagemrgb.java import net.java.games.jogl.*; import java.io.*; public class Imagemrgb { int int byte[][][] String dimx,dimy,range; rx,ry; imagergb; file;

Imagemrgb(String s) { file = s; try { Reader q = new FileReader(s); int ch; String p; ch = q.read(); p = String.valueOf((char)ch); while(!Character.isWhitespace((char) ch )) { ch = q.read(); if (Character.isWhitespace((char) ch)) break; p += String.valueOf((char)ch); } dimx = Integer.parseInt(p); 50

while(Character.isWhitespace((char) ch)) ch = q.read(); p = String.valueOf((char)ch); while(!Character.isWhitespace((char) ch)) { ch = q.read(); if (Character.isWhitespace((char) ch)) break; p += String.valueOf((char)ch); dimy = Integer.parseInt(p); while(Character.isWhitespace((char) ch)) ch = q.read(); p = String.valueOf((char)ch); while(!Character.isWhitespace((char) ch)) { ch = q.read(); if (Character.isWhitespace((char) ch)) break; p += String.valueOf((char)ch); } range = Integer.parseInt(p); imagergb = new byte[dimx][dimy][3]; System.out.println(" " + dimx + " " + dimy + " " +

range); for (int i = 0; i<dimx; i++) { for(int j = 0; j<dimy; j++) { for(int k = 0; k < 3; k++) { while(Character.isWhitespace((char) ch = q.read(); p = String.valueOf((char)ch); while (!Character.isWhitespace((char) ch = q.read(); if break; p += String.valueOf((char)ch);

ch))

ch)) { (Character.isWhitespace((char) ch))

} imagergb[i][j][k] = (byte)Integer.parseInt(p); // // // + p ); }

if (imagergb[i][j][k] < 0) imagergb[i][j][k] += 256; System.out.println(imagergb[i][j][k] + " " }

} } catch (Exception e) { e.printStackTrace(); } } public byte get_image(int i,int j,int k) { if ((i < dimx) && (j < dimy)) { return(imagergb[i][j][k]); 51

} else { System.out.println(i+ " " + j + " " + dimx + " " + dimy + " " + imagergb[i][j][k]); return(0); } } public int get_dimx() { return dimx; } public int get_dimy() { return dimy; } public void draw_image(GLDrawable draw) { GL gl = draw.getGL(); for (int i=0;i<dimx;i++) for (int j=0;j<dimy;j++) { gl.glColor3f(imagergb[i][j][0]/(float)range,imagergb[i][j][1]/(floa t)range,imagergb[i][j][2]/(float)range); gl.glBegin(GL.GL_POINTS); gl.glVertex2d(j,i); gl.glEnd(); } } } main.java import java.awt.*; import java.awt.event.*; import net.java.games.jogl.*; public class main { static dominio D = new dominio(); static parametrico f = new parametrico(); static Iluminacao I = new Iluminacao(); static Textura T = new Textura("bricks2.pgm",1); // static Textura T = new Textura("sea.pgm"); static int xm,xb,ym,yb,mov=0; static float gama,phi,theta; static float scale; static GLCanvas canvas = GLDrawableFactory.getFactory().createGLCanvas(new GLCapabilities()); public static void main(String[] args) { Frame frame = new Frame("Textura"); canvas.addGLEventListener( new JoglRender() ); canvas.addMouseListener( new JoglMouse() ); canvas.addMouseMotionListener( new JoglMouseMotion() ); canvas.addMouseWheelListener( new JoglMouseWheel() ); frame.add(canvas); 52

frame.setSize(600, 600); frame.setLocation(50,50); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true);

static class JoglRender implements GLEventListener { public void init(GLDrawable drawable) { gama = 90; phi = 45; theta = 135; D.init(drawable); T.set_Drawable(drawable); T.init();

public void display(GLDrawable drawable) { GL gl = drawable.getGL(); D.init(drawable); gl.glClearColor(0.0f,0.0f,0.0f,1.0f); gl.glClear(GL.GL_COLOR_BUFFER_BIT | I.rotaciona_light(); D.plota_eixo(drawable); I.render_light(drawable); I.light_on(drawable); T.texture_on(); f.plota_superficie(drawable); T.texture_off(); I.light_off(drawable); gl.glFlush(); } public void displayChanged(GLDrawable drawable, boolean modeChanged, boolean deviceChanged) { } public void reshape(GLDrawable drawable, int x, int y, int width, int height) { } } static class JoglMouse implements MouseListener { public void mouseEntered(MouseEvent e) { // System.out.println("Mouse Entra"); } public void mouseExited (MouseEvent e) { // System.out.println("Mouse Sai"); } public void mousePressed(MouseEvent e) { 53

GL.GL_DEPTH_BUFFER_BIT);

if (e.getButton()==1) { System.out.println("Entra"); xb = e.getX(); yb = e.getY(); } if (e.getButton()==2) { System.out.println("troca"); mov = (mov+1) %3; System.out.println("Persp = " + mov); } } public void mouseReleased(MouseEvent e) { if (e.getButton()==1) { theta = theta + xm - xb; phi = phi - ym + yb ; D.set_angle(gama,phi,theta); canvas.display(); }

public void mouseClicked(MouseEvent e) { System.out.println("Mouse botao"); } } static class JoglMouseMotion implements MouseMotionListener

!= 0) {

public void mouseDragged(MouseEvent e) { if ((e.getModifiers() & InputEvent.BUTTON1_MASK) xm = e.getX(); ym = e.getY(); theta = theta + xm phi = phi - ym + D.set_angle(gama,phi,theta); theta = theta - xm phi = phi + ym canvas.display(); } } public void mouseMoved(MouseEvent e) { }

xb; yb ; + xb; - yb;

static class JoglMouseWheel implements

MouseWheelListener {

public void mouseWheelMoved(MouseWheelEvent e) { scale = D.get_scale(); scale += e.getWheelRotation()/10.0; D.set_scale(scale); 54

canvas.display(); } } }

Textura.java import net.java.games.jogl.*; public class Textura { byte[] Image; int dimx,dimy,depth; int[] texName = new int[1]; int rx,ry; GLDrawable draw; Imagem I; Imagemrgb R; Textura(String s) { int ind; I = new Imagem(s); dimx = I.get_dimx(); dimy = I.get_dimy(); depth = 3; Image = new byte[dimx*dimy*3]; ind = 0; System.out.println("W/B"); for(int i=0;i<dimx;i++) { for(int j=0;j<dimy;j++) { Image[ind] = I.get_image(i,j); Image[ind+1] = Image[ind+2] = Image[ind]; ind = ind + 3; } } } Textura(String s,int type) { int ind; R = new Imagemrgb(s); dimx = 512; dimy = 512; depth = 3; rx = R.get_dimx(); ry = R.get_dimx(); Image = new byte[dimx*dimy*3]; ind = 0; System.out.println("Color"); for(int i=0;i<dimx;i++) { for(int j=0;j<dimy;j++) { for(int k=0;k<3;k++) { Image[ind] = R.get_image(i,j,k); ind = ind + 1; } } } } public void set_Drawable(GLDrawable drawable) { draw = drawable; 55

} public void texture_on() { GL gl = draw.getGL(); gl.glEnable(GL.GL_TEXTURE_2D); gl.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_DECAL); // GL_GL_BLEND , GL_REPLACE, GL_MODULATE gl.glBindTexture(GL.GL_TEXTURE_2D, texName[0]); } public void texture_off() { GL gl = draw.getGL(); gl.glDisable(GL.GL_TEXTURE_2D); } public void init() { GL gl = draw.getGL(); gl.glClearColor (0, 0, 0, 0); gl.glShadeModel(GL.GL_SMOOTH); gl.glEnable(GL.GL_DEPTH_TEST); gl.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1); gl.glGenTextures(1, texName); gl.glBindTexture(GL.GL_TEXTURE_2D, texName[0]); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT); //GL_CLAMP gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER,GL.GL_LINEAR); //GL.GL_NEAREST gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER,GL.GL_LINEAR); gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGB, dimx,dimy, 0, GL.GL_RGB, GL.GL_UNSIGNED_BYTE,Image); } }

56

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