Desenhar retas a partir do centro do circulo

Bom dia amigos!

Bem, tenho uma dúvida: Como eu faço para que sejam desenhadas um certo número de retas partindo do centro do círculo?

Abaixo um código que eu gostaria de fazer isso. Este código desenha 8 círculos concentricos. Agora eu preciso desenhar a partir do centro, retas como se fosse uma tela de radar.

Seria como seu estivesse fatiando os círculos a partir do centro.


import javax.swing.JPanel;
import java.awt.*;
import java.math.*;

public class CirclesJPanel extends JPanel {
 
 public void paintComponent( Graphics g ) {
    
    Graphics2D g2d = (Graphics2D)g;
	g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
    super.paintComponent( g );
	
	for ( int topLeft = 0; topLeft < 80; topLeft += 10 ) {
	
	
		int radius = 160 - ( topLeft * 2 );
        
		g2d.drawArc( topLeft + 10, topLeft + 25, radius, radius, 0, 360 );
	} 
 }

 } 

Sabe um pouco de trigonometria? Se souber, ajuda.

Quantos segmentos de reta você quer desenhar? Em que ângulos?

[quote=entanglement]Sabe um pouco de trigonometria? Se souber, ajuda.

Quantos segmentos de reta você quer desenhar? Em que ângulos?
[/quote]

O numero de retas inicialmente, pode ser 8, depois vai ser variavel, como se fossem divididas em pizza, com porcoes de tamanho iguais. Tais retas devem comecar no centro do circulo e chegar ate no final do grafico. Se puderem me ajudar, ficaria muito grato. Conheco e tenho mais experiencia com outras parte do java, agora que estou precisando trabalhar com graficos.

Abaixo a forma pretendida:

Depois que eu conseguir criar esta forma, preciso pintar alguns pedacinhos individualmente, assim como no imagem. Mas por hora, preciso apenas de uma maneira com o codigo acima de criar aquela grade. Grato.

É melhor aprender a pintar já os pedaços, isso pode ser feito com fillArc mesmo. No seu caso em particular, é bem mais fácil você já pintar os pedaços que desenhar os segmentos de reta, já que você está com dificuldades com trigonometria.
http://java.sun.com/javase/6/docs/api/java/awt/Graphics.html#fillArc(int,%20int,%20int,%20int,%20int,%20int)

http://www.jchq.net/applets/arc_demo.htm

[quote=entanglement]É melhor aprender a pintar já os pedaços, isso pode ser feito com fillArc mesmo. No seu caso em particular, é bem mais fácil você já pintar os pedaços que desenhar os segmentos de reta, já que você está com dificuldades com trigonometria.
http://java.sun.com/javase/6/docs/api/java/awt/Graphics.html#fillArc(int,%20int,%20int,%20int,%20int,%20int)

http://www.jchq.net/applets/arc_demo.htm[/quote]

Amigo, esse é um grafico de níveis. Existe alguma funcao que me posicione no centro deste circulo? Ele irá funcionar assim: Cada fatia corresponde a um setor, e cada pedaco desta fatia representa um nivel, ou seja, neste caso como tenho 8 circulos, quando for fatiado em partes iguais, cada fatia devera possui 8 níveis.

valeu.

Infelizmente o meu proxy não está me deixando visualizar sua imagem. Você quer algo parecido com isto?

[quote=entanglement]Infelizmente o meu proxy não está me deixando visualizar sua imagem. Você quer algo parecido com isto?

Amigo, postei em outro image hosting, v c agora agora da pra vc ver a imagem, é um trabalho pra facul, eh um grafico diferente dos demais.

Nao sei se estou burlando alguma regra do forum, mas to postando aqui tbem o link direto da imagem:
[URL]http://www.glowfoto.com/static_image/29-094525L/4516/png/06/2010/img4/glowfoto[/URL]

Da um olhada ai, valeu!

Ah, beleza, isso não é tão difícil de desenhar. Vou ver se monto um exemplo depois do almoço.

João, por que você duplicou o tópico e criou outro usuário?

Seu tópico original era aqui:
http://www.guj.com.br/posts/list/210927.java#1072525

Você poderia ter continuado a complementar as informações por lá, pois eu ainda receberia um e-mail.

Você chegou a ler os artigos que indiquei?
No terceiro link, havia a explicação de como achar um ponto que está na superficie de uma circunferência.

[quote=entanglement]Ah, beleza, isso não é tão difícil de desenhar. Vou ver se monto um exemplo depois do almoço.
[/quote]

Valeu amigo, estou aguardando sua ajuda. Acho que o mais complicado mesmo seria tipo: Se uma fatia tem 5 niveis, pintar 5 pedacinhos. se outra fatia tem nivel 2, pintar 2 pedacinhos.

Fiquei meio que sem tempo pra terminar este grafico, pois estou com atividades em PVM, Corba e simulacao. Caso conseguir me ajudar com um exemplo ficaria muito grato!

[quote=ViniGodoy]João, por que você duplicou o tópico e criou outro usuário?

Seu tópico original era aqui:
http://www.guj.com.br/posts/list/210927.java#1072525

Você poderia ter continuado a complementar as informações por lá, pois eu ainda receberia um e-mail.

Você chegou a ler os artigos que indiquei?
No terceiro link, havia a explicação de como achar um ponto que está na superficie de uma circunferência.[/quote]

Bom dia, nao estava conseguindo receber o email de alteracao de senha da outra conta, caso voce puder apagar o outro topico e manter este eu agradeceria muito. Acho que estava no tema errado aquele outro tambem ne? To apertadaço com o tempo aqui, trab de sistemas distribuidos, simulacao de redes e tava precisando de ajuda!! :smiley:

Aliás, voce está de parabéns com os seus artigos.

Ok, já que a trigonometria está difícil, vou te passar a fórmula.

x2 = cos(angle) * size + x1 y2 = sin(angle) * size + y1

Onde x1 e y1 são as coordenadas do ponto no centro da circunferência, e x2 e y2 são as coordenadas do ponto resultante, size é o tamanho do segmento de reta e angle é o ângulo que deve ser traçado em relação ao eixo x. Lembrando que o ângulo é em radianos e vai de 0 até 2*PI.

Agora é só fazer um for.

Se você usar vetores, fica mais fácil ainda. Se v1 for o vetor que marca o centro do circulo, v2 é definido por:

package guj;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Arc2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JPanel;

public class GraficoNivel extends JPanel {

    public static class Valor {
        private double valor;
        private String legenda;
        public Valor (double valor, String legenda) {
            this.valor = valor; this.legenda = legenda;
        }
        public double getValor() {
            return valor;
        }
        public void setValor(double valor) {
            this.valor = valor;
        }
        public String getLegenda() {
            return legenda;
        }
        public void setLegenda(String legenda) {
            this.legenda = legenda;
        }
    };
    
    public GraficoNivel() {
        super();
    }
    private List<Valor> valores = new ArrayList<Valor>();
    public void add (Valor valor) {
        valores.add (valor);
        System.out.println (valores);
    }
    public void clear() {
        valores.clear();
    }
    public void setDivisoes (int nDivisoes) {
        this.nDivisoes = nDivisoes;
    }
    
    private void normalize (Graphics2D g2d, Dimension dim) {
        g2d.translate(dim.width / 2, dim.height / 2);
        g2d.scale((dim.width - 2) / 2, -(dim.height - 2) / 2);
    }
    
    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        // Devemos a princípio determinar as dimensões, de forma que possamos normalizar
        // para um sistema de coordenadas com -1 <= x <= +1 e -1 <= y <= +1, e com o 
        // eixo dos x apontando para cima, não para baixo.
        normalize (g2d, getSize());
        g2d.setStroke(new BasicStroke(0.01f));
        // Vamos desenhar as fatias, de acordo om seus respectivos raios
        for (int i = 1; i <= valores.size(); ++i) {
            double radius = valores.get(i-1).getValor();
            double angle = 360 / valores.size();
            g2d.setPaint (new Color ((int) (255 * i / valores.size()), (int) (255 * i / valores.size()), (int) (255 * i / valores.size())));
            System.out.println (radius);
            Arc2D.Double d = new Arc2D.Double (-radius, -radius, 2 * radius, 2 * radius, 270- (int) (angle * (i-1)), (int) angle, Arc2D.PIE);
            g2d.fill (d);
        }
        g2d.setPaint(Color.BLACK);
        // Vamos desenhar agora os raios (um para cada Valor)
        System.out.println (valores.size());
        for (int i = 0; i < valores.size(); ++i) {
            double theta = 2 * Math.PI * i / valores.size();
            g2d.draw (new Line2D.Double(0, 0, Math.sin(theta), Math.cos(theta)));
        }
        // Agora, vamos desenhar a quantidade de subdivisões
        for (int i = 1; i <= nDivisoes; ++i) {
            double radius = i * 1.0 / nDivisoes;
            Ellipse2D.Double d = new Ellipse2D.Double(-radius, -radius, 2*radius, 2*radius); 
            g2d.draw(d);
        }
        g2d.dispose();
    }
    
    private int nDivisoes = 3;
}

Exemplo de uso.

package guj;

import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class ExemploGraficoNivel extends JFrame {

    private static final long serialVersionUID = 1L;
    private JPanel jContentPane = null;
    private GraficoNivel grfNivel = null;

    private GraficoNivel getGrfNivel() {
        if (grfNivel == null) {
            grfNivel = new GraficoNivel();
            grfNivel.setDivisoes(5);
            grfNivel.add (new GraficoNivel.Valor(0.5, "meio"));
            grfNivel.add (new GraficoNivel.Valor(0.7, "meio"));
            grfNivel.add (new GraficoNivel.Valor(0.9, "meio"));
            grfNivel.add (new GraficoNivel.Valor(1.2, "meio"));
            grfNivel.add (new GraficoNivel.Valor(0.6, "meio"));
        }
        return grfNivel;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                ExemploGraficoNivel thisClass = new ExemploGraficoNivel();
                thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                thisClass.setVisible(true);
            }
        });
    }
    public ExemploGraficoNivel() {
        super();
        initialize();
    }

    private void initialize() {
        this.setSize(300, 300);
        this.setContentPane(getJContentPane());
        this.setTitle("Teste Gráfico Nível");
    }
    private JPanel getJContentPane() {
        if (jContentPane == null) {
            jContentPane = new JPanel();
            jContentPane.setLayout(new BorderLayout());
            jContentPane.add(getGrfNivel(), BorderLayout.CENTER);
        }
        return jContentPane;
    }
}


[quote=entanglement][code]
package guj;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Arc2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JPanel;

public class GraficoNivel extends JPanel {

public static class Valor {
    private double valor;
    private String legenda;
    public Valor (double valor, String legenda) {
        this.valor = valor; this.legenda = legenda;
    }
    public double getValor() {
        return valor;
    }
    public void setValor(double valor) {
        this.valor = valor;
    }
    public String getLegenda() {
        return legenda;
    }
    public void setLegenda(String legenda) {
        this.legenda = legenda;
    }
};

public GraficoNivel() {
    super();
}
private List<Valor> valores = new ArrayList<Valor>();
public void add (Valor valor) {
    valores.add (valor);
    System.out.println (valores);
}
public void clear() {
    valores.clear();
}
public void setDivisoes (int nDivisoes) {
    this.nDivisoes = nDivisoes;
}

private void normalize (Graphics2D g2d, Dimension dim) {
    g2d.translate(dim.width / 2, dim.height / 2);
    g2d.scale((dim.width - 2) / 2, -(dim.height - 2) / 2);
}

@Override
protected void paintComponent(Graphics g) {
    Graphics2D g2d = (Graphics2D) g.create();
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    // Devemos a princípio determinar as dimensões, de forma que possamos normalizar
    // para um sistema de coordenadas com -1 <= x <= +1 e -1 <= y <= +1, e com o 
    // eixo dos x apontando para cima, não para baixo.
    normalize (g2d, getSize());
    g2d.setStroke(new BasicStroke(0.01f));
    // Vamos desenhar as fatias, de acordo om seus respectivos raios
    for (int i = 1; i <= valores.size(); ++i) {
        double radius = valores.get(i-1).getValor();
        double angle = 360 / valores.size();
        g2d.setPaint (new Color ((int) (255 * i / valores.size()), (int) (255 * i / valores.size()), (int) (255 * i / valores.size())));
        System.out.println (radius);
        Arc2D.Double d = new Arc2D.Double (-radius, -radius, 2 * radius, 2 * radius, 270- (int) (angle * (i-1)), (int) angle, Arc2D.PIE);
        g2d.fill (d);
    }
    g2d.setPaint(Color.BLACK);
    // Vamos desenhar agora os raios (um para cada Valor)
    System.out.println (valores.size());
    for (int i = 0; i < valores.size(); ++i) {
        double theta = 2 * Math.PI * i / valores.size();
        g2d.draw (new Line2D.Double(0, 0, Math.sin(theta), Math.cos(theta)));
    }
    // Agora, vamos desenhar a quantidade de subdivisões
    for (int i = 1; i <= nDivisoes; ++i) {
        double radius = i * 1.0 / nDivisoes;
        Ellipse2D.Double d = new Ellipse2D.Double(-radius, -radius, 2*radius, 2*radius); 
        g2d.draw(d);
    }
    g2d.dispose();
}

private int nDivisoes = 3;

}
[/code]

Exemplo de uso.

[code]
package guj;

import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class ExemploGraficoNivel extends JFrame {

private static final long serialVersionUID = 1L;
private JPanel jContentPane = null;
private GraficoNivel grfNivel = null;

private GraficoNivel getGrfNivel() {
    if (grfNivel == null) {
        grfNivel = new GraficoNivel();
        grfNivel.setDivisoes(5);
        grfNivel.add (new GraficoNivel.Valor(0.5, "meio"));
        grfNivel.add (new GraficoNivel.Valor(0.7, "meio"));
        grfNivel.add (new GraficoNivel.Valor(0.9, "meio"));
        grfNivel.add (new GraficoNivel.Valor(1.2, "meio"));
        grfNivel.add (new GraficoNivel.Valor(0.6, "meio"));
    }
    return grfNivel;
}

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            ExemploGraficoNivel thisClass = new ExemploGraficoNivel();
            thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            thisClass.setVisible(true);
        }
    });
}
public ExemploGraficoNivel() {
    super();
    initialize();
}

private void initialize() {
    this.setSize(300, 300);
    this.setContentPane(getJContentPane());
    this.setTitle("Teste Gráfico Nível");
}
private JPanel getJContentPane() {
    if (jContentPane == null) {
        jContentPane = new JPanel();
        jContentPane.setLayout(new BorderLayout());
        jContentPane.add(getGrfNivel(), BorderLayout.CENTER);
    }
    return jContentPane;
}

}
[/code][/quote]

Muito obrigado a todos, principalmente ao amigo entanglement!!

Tentei colocar legenda em cada fatia mas ta saindo esquisito e as vezes nem sai. Alguma ideia de como posso colocar do lado de fora de cada fatia? Ou qual seriam as medidas que eu deveria considerar?

Abraco.

Acho que você não vai mais poder evitar fazer algumas contas, não? Você talvez tenha de achar um ponto no meio de cada fatia, e a partir desse ponto, posicionar sua legenda.

Voce poderia me dar um exemplo em uma fatia deste codigo por favor ? Depois contribuo com algum bom artigo aqui no GUJ. Estou com um projeto de software para a faculdade que algumas tarefas foram divididas entre os grupos. So que me foram delegadas outras tarefas que ainda nao foram concluidas. Obrigado.

Vou dar uma sugestão.

É que se você pensar bem, o posicionamento das legendas não é tão simples quanto parece; poderíamos ter de reduzir o desenho, e ficar puxando retas a partir do centro de cada fatia, o que é um pouquinho chato de fazer.

Eu já vi muitos gráficos em que a legenda era por cores, não diretamente sobre o desenho.

Então você poderia escolher umas cores bem diferentes (em vez dos diversos tons de cinza que usei) e então pôr a legenda do lado do desenho, talvez usando uma série de JLabels em que as cores do background fossem as cores do desenho.

[quote=entanglement]Vou dar uma sugestão.

É que se você pensar bem, o posicionamento das legendas não é tão simples quanto parece; poderíamos ter de reduzir o desenho, e ficar puxando retas a partir do centro de cada fatia, o que é um pouquinho chato de fazer.

Eu já vi muitos gráficos em que a legenda era por cores, não diretamente sobre o desenho.

Então você poderia escolher umas cores bem diferentes (em vez dos diversos tons de cinza que usei) e então pôr a legenda do lado do desenho, talvez usando uma série de JLabels em que as cores do background fossem as cores do desenho.

[/quote]
Entao rapaz, eu comecei a fazer isso, coloquei um ArrayList para pegar as cores de todas as fatias coloridas. Mas nao estou conseguindo desenhar do lado do grafico. Pode me dar uma forca? E vc acha que o BorderLayout seria o melhor para este caso?

Obrigado pela rapida resposta.

Eu acho que não seria necessário desenhar do lado do gráfico (até porque você precisaria de mexer um pouco na parte de conversão de coordenadas. Você deve ter visto que, conforme o gráfico é redimensionado, o círculo fica na verdade como uma elipse e ocupa todo o gráfico).

Eu acho que você pode enquadrar esse gráfico em um JFrame ou JDialog (por exemplo), e pôr as legendas em JLabels ao lado do gráfico. É mais fácil.