Espiral quadrada

5 respostas
K

Boa noite.

Estou há mais de 2 dias tentando fazer uma bendita espiral quadrada pelo Java, mas sem sucesso.

O livro que estou estudando é o Java - Como Programar, Deitel.

O exercício é o seguinte:

Desenhe uma espiral com a forma quadrada, centralizada no painel, utilizando o método drawLine(). Uma técnica é utilizar um loop que aumenta o comprimento da linha depois de desenhar cada duas linhas. A direção na qual desenhar a próxima linha deve seguir um padrão distinto - por exemplo, para baixo, para a esquerda, para cima, para a direita.

Preciso da ajuda de vocês!

Desde já agradeço.

5 Respostas

InicianteJavaHenriqu

O que vc sabe sobre Java 2D :?:

O que vc já fez até agora :?:

Post ai que fica mais fácil :smiley:

:thumbup:

K

Olá =D

Sei até a parte de Arrays, aprendi a usar drawRect, drawLine, fillOval, fillRect.

Fiz uns loops pra fazer uns exercícios com drawLine, mas não sei muito sobre java2D…

Bom, apaguei meu código que tinha feito pra tentar a espiral, aí comecei a escrevê-lo pra poder postar aqui até onde eu tinha feito.

Novidade: consegui fazer o exercício haIUHAiuaHUI

Só que talvez teria algum jeito de deixar o código mais enxuto.

Têm alguma ideia?

Aí vai meu código:

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class EspiralQuad extends JPanel
{	
	public void paintComponent( Graphics g)
	{
		super.paintComponent( g );
		int passos = 10;
		
		// coordenadas do centro da espiral
		int coordX = getWidth() / 2;
		int coordY = getHeight() / 2;
		
		// coordenadas da outra ponta da linha
		// a coordenada X fica estática na primeira linha, mas a Y muda pra maior
		int coord2X = getWidth() / 2;
		// resolvi fazer por passos pra poder redimensionar a tela e a espiral redimensionar também
		int coord2Y = getHeight() / 2 + ( getHeight() / passos );
		
		g.setColor( Color.blue ); // muda a cor das linhas para azul
		
		// início do loop for que desenha as linhas e muda os valores das coordenadas
		for ( int contador = 1; contador  <= 10; contador++ )
		{			
			// desenha a primeira linha com os valores iniciais
			g.drawLine( coordX, coordY, coord2X, coord2Y );
			
                        // decide se o contador é par ou ímpar
			if ( contador % 2 == 1)
			{
				// muda a coordX e coordY para desenhar a outra linha
				// caso o contador for ímpar
				coordX -= contador * ( getWidth() / passos );
				coordY += contador * ( getHeight() / passos );
			}
			else
			{
				// muda a coordX e coordY caso contador seja par
				coordX += contador * ( getWidth() / passos );
				coordY -= contador * ( getHeight() / passos );
			}
			
			// desenha a outra linha a partir do ultimo ponto
			g.drawLine( coord2X, coord2Y, coordX, coordY);
			
			// muda os valores para desenhar de onde parou
			if ( contador % 2 == 1)
			{
				// muda a coord2X e coord2Y caso seja ímpar
				coord2X -= contador * ( getWidth() / passos );
				// aqui o calculo inclui 1 ao contador para a altura ser o dobro
				// da ultima linha vertical
				coord2Y -= ( 1 + contador ) * ( getHeight() / passos );
			}
			else
			{
				// muda a coord2X e coord 2Y para desenhar a outra linha
				// mesmo caso da anterior em relação ao 1 + contador
				coord2Y += ( 1 + contador ) * ( getHeight() / passos );
				coord2X += contador * ( getWidth() / passos );
			}
		}
	}
}

Desde já agradeço.

InicianteJavaHenriqu

Olá Kakofonia :smiley:

A espiral quadrada é desta maneira mesmo que você desenhou (conforme o livro pedia) :?: :!:

Caso sim, só faltava a espiral aumentar junto com a tela, para isto mudei de JPanel para JFrame, só para ficar mais fácil, porque senão você teria que guardar o tamanho do JFrame em variáveis e passá-las a cada movimento ao JPanel.

Outras pequenas mudanças expliquei no código, logo a baixo:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;

@SuppressWarnings("serial")
public class EspiralQuad extends JFrame {

    private final int passos = 10;

    public EspiralQuad() {
        setSize(200, 200);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        //*****cria um cópia do contexto gráfio atual, para não atrapalhar a chamada do método por outras classes*****  
        Graphics2D g2d = (Graphics2D) g.create();

        // coordenadas do centro da espiral  
        int coordX = getWidth() / 2;
        int coordY = getHeight() / 2;

        // coordenadas da outra ponta da linha  
        // a coordenada X fica estática na primeira linha, mas a Y muda pra maior  
        int coord2X = getWidth() / 2;
        // resolvi fazer por passos pra poder redimensionar a tela e a espiral redimensionar também  
        int coord2Y = getHeight() / 2 + (getHeight() / passos);

        g2d.setColor(Color.blue); // muda a cor das linhas para azul  

        // início do loop for que desenha as linhas e muda os valores das coordenadas  
        for (int contador = 1; contador &lt;= passos; contador++) {
            // desenha a primeira linha com os valores iniciais  
            g2d.drawLine(coordX, coordY, coord2X, coord2Y);

            // decide se o contador é par ou ímpar  
            if (contador % 2 == 1) {
                // muda a coordX e coordY para desenhar a outra linha  
                // caso o contador for ímpar  
                coordX -= contador * (getWidth() / passos);
                coordY += contador * (getHeight() / passos);
            } else {
                // muda a coordX e coordY caso contador seja par  
                coordX += contador * (getWidth() / passos);
                coordY -= contador * (getHeight() / passos);
            }

            // desenha a outra linha a partir do ultimo ponto  
            g2d.drawLine(coord2X, coord2Y, coordX, coordY);

            // muda os valores para desenhar de onde parou  
            if (contador % 2 == 1) {
                // muda a coord2X e coord2Y caso seja ímpar  
                coord2X -= contador * (getWidth() / passos);
                // aqui o calculo inclui 1 ao contador para a altura ser o dobro  
                // da ultima linha vertical  
                coord2Y -= (1 + contador) * (getHeight() / passos);
            } else {
                // muda a coord2X e coord 2Y para desenhar a outra linha  
                // mesmo caso da anterior em relação ao 1 + contador  
                coord2Y += (1 + contador) * (getHeight() / passos);
                coord2X += contador * (getWidth() / passos);
            }
        }
        //*****encerra os gráficos neste contexto e libera os recursos do sistema que está usando*****
        g2d.dispose();
        g.dispose();
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new EspiralQuad().setVisible(true);
            }
        });
    }
}

O restante do código não mexi, porque você já fez certo. Também não deixei o código mais enxuto, porque teria que mudar a lógica que você utilizou, mas não se preocupe com isto, você fez tudo certinho e otimizações no código você mesmo consegue fazer :smiley:

Qualquer dúvida, é só postar

K

Olá InicianteJavaHenrique!

A espiral é dessa maneira que eu desenhei sim =D

Do jeito que tá no livro ela saiu o/

A espiral já está aumentando junto com a tela, porque o livro ensina nos tópicos de “Estudo de caso de GUI” que o desenho em si deve ser feito em uma classe (objeto), e o aplicativo em si (onde você vai colocar o objeto) em outra classe.

Por exemplo: o desenho criei na classe EspiralQuad e o aplicativo na classe EspiralQuadTeste.

Utilize meu código anterior com esse aqui abaixo, que é o EspiralQuadTeste:

import javax.swing.JFrame;

public class EspiralQuadTeste 
{
	public static void main(String[] args) 
	{
		EspiralQuad painel = new EspiralQuad();
		JFrame aplicativo = new JFrame();
		
		aplicativo.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		aplicativo.add( painel );
		aplicativo.setSize( 200, 200 );
		aplicativo.setVisible( true );
	}
}

Ele redimensiona com a tela normalmente =D

Pra brincar um pouco eu coloquei um objeto da classe Random no EspiralQuad e outro da classe Color pra ficar mudando de cor a cada linha que o loop desenha! Ficou legal :smiley:

Valew pela resposta rápida :smiley:

InicianteJavaHenriqu

Deu certo legal :smiley:

Sim funcionou inserir o JPanel em seu JFrame, porque o gerenciador de layout deste é BorderLayout.

:thumbup:

Criado 18 de abril de 2012
Ultima resposta 19 de abr. de 2012
Respostas 5
Participantes 2