Italo Info


Plot 3D (Framework Java)

Atenção:

Esta versão do framework está DESATUALIZADA. Existe uma versão mais recente do plot3d que recebeu o nome de iplot por suportar também a plotagem de dados e funções, tanto em 3D quanto em 2D. A nova versão (chamada de iplot) trouxe muitas melhorias em comparação com esta versão do framework. Visite a página do projeto iplot:

Link do iplot: clique aqui.

Olá! Desta vez escrevo para apresentar uma biblioteca gráfica que construi para que programadores possam plotar funções em 3D no plano cartesiano com a escrita de pouco código. Dei a biblioteca gráfica o nome de "Plot 3D" por ser possível com ela a plotagem de funções em 3D.

Exemplos

Plotagem de uma função
y=(x-3)²-(z-2)²
Plotagem de uma função
y=sen( sqrt( x² + z² ) )
Plotagem de uma função
y=( z + (x²)² ) * ( x + z³ )
Plotagem de uma função
y=x² * sen( 3 / (x*PI) )

O plot3d também permite o desenho de formas geométricas em 3D. Abaixo, um exemplo de aplicação da gaussiana para geração de uma forma geométrica e o desenho de um cubo em 3D. Preste atenção a cor das faces das formas geométricas. As cores são calculadas conforme a incidência de luz que varia de acordo com o ângulo entre um vetor que representa o raio de luz emitido por uma fonte de luz que atinge a face e um vetor normal que é perpendicular a o plano ao qual pertence a face da figura geométrica.

Função gaussiana aplicada
Gaussiana 3D
Desenho de cubo em 3D
Cubo 3D

Instalação

Para integrar o Plot 3D em sua aplicação Java, basta inserir no CLASSPATH o jar da biblioteca gráfica disponível abaixo:

Download: plot3d.jar

Exemplos e aplicações

Atenção:
Se você baixou antes o plot3d.jar, por favor baixe novamente para que funcionem corretamente os exemplos dessa página com a versão mais recente do plot3d, e seja possível rodar a versão mais recente do programa de demonstração.

Vamos a um pequeno exemplo de demonstração de uso, o exemplo 1. Veja o código abaixo:

import javax.swing.JComponent; import javax.swing.JFrame; import plot3d.planocartesiano.PlanoCartesianoPlot3D; import plot3d.planocartesiano.PlanoCartesianoPlot3DDriver; public class Ex1 { public static void main( String[] args ) { PlanoCartesianoPlot3D plot3D = new PlanoCartesianoPlot3D(); PlanoCartesianoPlot3DDriver drv = (plano) -> { plano.setAltura2D( 1.7 ); plano.setIntervalos( -Math.PI, Math.PI, -Math.PI, Math.PI ); plano.setFunc3D( (x,z) -> { return Math.pow( x, 3 ) + 3*Math.pow( z, 2 ); } ); }; JComponent c = plot3D.getDesenhoComponent(); JFrame janela = new JFrame(); janela.setTitle( "Desenho da função y=x³+3z² em 3D" ); janela.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); janela.setContentPane( c ); janela.setSize( 640, 480 ); janela.setLocationRelativeTo( janela ); janela.setVisible( true ); plot3D.constroi( drv, true ); } }

Veja abaixo a imágem capturada da plotagem da função:

Plotagem de uma função (Ex1)
Plotagem da função y=x³+3z²

Para o exemplo acima funcionar foi preciso instanciar a classe PlanoCartesianoPlot3D e implementar a interface PlanoCartesianoPlot3DDriver que permite a configuração do plano cartesiano e a função a ser plotada.

Voltando ao exemplo, perceba que há um método da classe PlanoCartesianoPlot3D com nome controi que recebe alguns parâmetros. No exemplo 1, foram passados dois parâmetros, a implementação da interface PlanoCartesianoPlot3DDriver onde é definida a configuração do plano cartesiano e um segundo parâmetro booleano que, se tiver valor true, será possível rotacionar e escalar o plano cartesiano para visualizá-lo em vários ângulos. Se o segundo parâmetro tiver valor false, o plano cartesiano com a função são apenas desenhados na tela. Se você for um programador Java, experimente alterar as expressões da função setada no método setFunc3D!

Vale ressaltar que, é importante prestar atenção ao domínio da função a ser plotada. Por exemplo, o domínio da função 1/sen(x+z) não abrange pontos em que x+z é igual a algum múltiplo de PI incluindo o zero e os multiplos negativos, dado que, por exemplo, se x+z é zero, sen(0) é zero e uma divisão por zero acontece. Também é importante frizar que os intervalos são configurados em x e z e o resultado da função que envolve os parâmatros de x e z é calculado para o eixo y. Por exemplo y=sen(x+z), e não z=sen(x+y). Os intervalos dos eixos x e z podem ser configurados com a chamada do método setIntervalos da classe PlanoCartesianoObjeto3D.

Também é necessário informar que há uma limitação em relação as dimensões (largura e altura) do plano cartesiano. Isto é, para o desenho do plano cartesiano funcionar corretamente no exemplo 1, foi necessário chamar o método constroi após a chamada do método setVisible da classe JFrame. Para isso não ser necessário, teria de o tamanho das dimensões da tela onde o plano cartesiano será pintado ser definido manualmente e, assim, funcionar com a chamada do método constroi antes do método setVisible. Por exemplo, veja o exemplo abaixo:

import java.awt.Dimension; import javax.swing.JComponent; import javax.swing.JFrame; import plot3d.g2d.DesenhoPNL; import plot3d.g2d.PainelTela; import plot3d.planocartesiano.PlanoCartesianoPlot3D; import plot3d.planocartesiano.PlanoCartesianoPlot3DDriver; import plot3d.planocartesiano.g3d.PlanoCartesianoObjeto3D; public class Ex2 extends JFrame implements PlanoCartesianoPlot3DDriver, PainelTela { private PlanoCartesianoPlot3D plot3D = new PlanoCartesianoPlot3D(); private int painelLargura = 640; private int painelAltura = 480; public Ex2() { JComponent desenhoComp = plot3D.getDesenhoComponent(); desenhoComp.setPreferredSize( new Dimension( painelLargura, painelAltura ) ); super.setTitle( "Desenho da função x³+3z² em 3D" ); super.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); super.setContentPane( desenhoComp ); super.pack(); super.setLocationRelativeTo( this ); plot3D.setPainelTela( this ); plot3D.constroi( this, true ); } @Override public void configura(PlanoCartesianoObjeto3D pc) { pc.setAltura2D( 1.7 ); pc.setIntervalos( -Math.PI, Math.PI, -Math.PI, Math.PI ); pc.setFunc3D( (x,z) -> { return Math.pow( x, 3 ) + 3*Math.pow( z, 2 ); } ); } @Override public int getTelaX(DesenhoPNL pnl) { return 0; } @Override public int getTelaY(DesenhoPNL pnl) { return 0; } @Override public int getTelaLargura(DesenhoPNL pnl) { return painelLargura; } @Override public int getTelaAltura(DesenhoPNL pnl) { return painelAltura; } public static void main( String[] args ) { Ex2 ex = new Ex2(); ex.setVisible( true ); } }

O exemplo acima faz o mesmo que o exemplo 1. No entanto, é estruturado de modo bem diferente. Perceba que o método constroi é chamado no construtor da classe e o método setVisible é chamado depois de instanciada a classe. Para funcionar assim, foi necessário implementar a interface PainelTela que tem dois métodos para que se possa definir manualmente a largura e altura do painel onde o plano cartesiano será pintado. Perceba que, no exemplo acima, os valores de largura e altura são, respectivamente, 640 e 480.

Agora vamos ao exemplo 3 que permite o desenho do gráfico em um objeto de imagem (classe BufferedImage) que permite até que se possa exportar a imagem do gráfico para algum formado de imagem como, por exemplo, gif ou jpg. No exemplo 3, perceba que a imagem é exportada como jpg.

import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JOptionPane; import plot3d.planocartesiano.PlanoCartesianoPlot3D; import plot3d.planocartesiano.PlanoCartesianoPlot3DDriver; public class Ex3 { public static void main(String[] args) { PlanoCartesianoPlot3DDriver drv = (pc) -> { pc.setAltura2D( 1.7 ); pc.setXIntervalo( -Math.PI, Math.PI ); pc.setZIntervalo( -Math.PI, Math.PI ); pc.setFunc3D( (x,z) -> { double d = Math.sqrt( x*x + z*z ); return Math.sin( d ); } ); }; PlanoCartesianoPlot3D aplic = new PlanoCartesianoPlot3D(); BufferedImage imagem = new BufferedImage( 640, 480, BufferedImage.TYPE_INT_RGB ); aplic.constroi( imagem.getGraphics(), drv, true, imagem.getWidth(), imagem.getHeight() ); String arquivo = JOptionPane.showInputDialog( "Informe o nome do arquivo a ser salvo: " ); if ( arquivo != null ) { File f = new File( arquivo+".jpg" ); try { ImageIO.write( imagem, "jpg", f ); JOptionPane.showMessageDialog( null, "Arquivo salvo para: "+f.getPath() ); } catch (IOException ex) { JOptionPane.showMessageDialog( null, "Não foi possível salvar a imagem para: "+arquivo ); } } } }

Os três exemplos mostrados aqui ilustram algumas das funcionalidades e aplicações da biblioteca gráfica Plot 3D. Para uma demonstração mais complexa, veja o exemplo abaixo que permite vários planos cartesianos em um único painel e mostra a função gaussiana que pode ser aplicada como função de visinhança em um algorítmo de redes neurais artificiais, o SOM ou Mapas auto-organizaveis. No exemplo de demonstração abaixo é possível configurar os intervalos x e z, o numero de divisões da malha da grade onde a função é aplicada e os parâmetros da função gaussiana (raio e altura). Para executar o exemplo de demonstração basta dar dois cliques no arquivo da biblioteca gráfica de nome plot3d.jar. Claro, vale lembrar que, para o exemplo funcionar, é necessário que o aplicativo seja executado em um computador com a maquina virtual Java instalada.

Link: plot3d.jar

Em breve pretendo escrever uma documentação mais detalhada sobre o Plot 3D, principalmente se houverem pessoas interessadas em utilizar a biblioteca gráfica!


Escrito por: Ítalo Herbert

Deixe seu comentário

Código de verificação:


Comentários postados:

Nenhum comentario visível postado até o momento, deixe o seu!