1

Swing/JPanel でいくつかの (変更可能な) 変数を取り、次のようなグラフを描画するコードを作成しようとしています。

画像

どこから始めればよいかわかりません。アイデアは、六角形にキーポイントがあり、変数ごとに1つあり、各ポイントの間に線が引かれ、カスタムシェイプ内のスペースが陰影付けされるというものです。何かアイデアはありますか?

コードプロトタイプ

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

public class DrawPolygon extends JPanel {

int xOffset = 0;
int yOffset = 0;
int sizeModifer = 50;
int numOfPoints = 8;
int linePosition = 80;
double sizeMultiplier = 1;

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);

    Polygon[] polygons = new Polygon[5];
    for (int i = 0; i < polygons.length; i++){
        polygons[i] = new Polygon();
        for (int q = 0; q < numOfPoints; q++) {
            polygons[i].addPoint(
                xOffset + (int) (linePosition + (sizeModifer*sizeMultiplier)
                * Math.cos(q * 2 * Math.PI / numOfPoints)),
                yOffset + (int) ((linePosition - 10) + (sizeModifer*sizeMultiplier)
                * Math.sin(q * 2 * Math.PI / numOfPoints)));
        }//built points
        sizeMultiplier = sizeMultiplier - 0.2;
    }//build polygon arrays

    Polygon innerPolygon = new Polygon();
    for (int i = 0; i < numOfPoints; i++) {
        int randomRange = 5 + (int) (Math.random() * ((sizeModifer - 5) + 1));
        innerPolygon.addPoint(
            xOffset + (int) (linePosition + randomRange
            * Math.cos(i * 2 * Math.PI / numOfPoints)),
            yOffset + (int) ((linePosition - 10) + randomRange
            * Math.sin(i * 2 * Math.PI / numOfPoints)));
    }
    Graphics2D g2d = (Graphics2D) g;
    g2d.setRenderingHint(
        RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.setStroke(new BasicStroke(1));

    for (int i = 0; i < polygons.length; i++){
        g2d.setColor(Color.green);
        g2d.fill(polygons[i]);
        g2d.setColor(Color.black);
        g2d.draw(polygons[i]);
    }//draw polygons from arrays

    double distanceModifier = 1;
    for (int i = 0; i < numOfPoints; i++) {
        g2d.drawString("test"+(i+1),
            xOffset + (int) (linePosition + (sizeModifer*distanceModifier)
            * Math.cos(i * 2 * Math.PI / numOfPoints)),
            yOffset + (int) ((linePosition - 10) + (sizeModifer*distanceModifier)
            * Math.sin(i * 2 * Math.PI / numOfPoints)));
        distanceModifier = distanceModifier +.01;
    }

    g2d.setColor(new Color(255,213,200,90));
    g2d.fill(innerPolygon);
    g2d.setColor(Color.red);
    g2d.draw(innerPolygon);
}

@Override
public Dimension getPreferredSize() {
    // TODO calculate size based on geometry
    return new Dimension(160, 160);
}

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setTitle("Show Different Polygons");
            frame.add(new DrawPolygon());
            frame.pack();
            frame.setLocationByPlatform(true);
            frame.setVisible(true);
        }
    });
}

}

4

3 に答える 3

3

もちろん。これを行うための Java ライブラリが既に存在するはずです。たとえば、Sonarは次のような図を表示します。通常、可能であれば独自のコンポーネントを作成するよりも、他の人のコンポーネントを使用することをお勧めします。通常は JFreeChart を使用しますが、そのようなコンポーネントはないようです。

自分で書きたい場合は、Web 上の各ポイントがどこにあるかを簡単に計算するだけで済みます。中心から、0 度で線を引くことから始めます。次に、後続の各ラジアル ラインが2*pi/nラジアン単位で回転します。簡単な三角法を適用して、各六角形の角度と半径からデカルト (x, y) 座標を計算できます。最後に、塗りつぶされた領域をオーバーレイします。したがって、アルゴリズムはこのようなものかもしれません。次の疑似コードでは、パラメーターvaluesは、ポリゴン上の各ポイントをダイアグラムの中心からのオフセットとして表す小さな正の整数のリストです。したがって、六角形の場合、このリストには 6 つの値があります。

function drawGraph(values):

    steps = maximum value from values
    lines = number of values

    webWidth = min(width, height)
    centerX = width / 2
    centerY = height / 2

    // Draw lines

    for radialLineNumber in 0..lines:
        angle = radialLineNumber * 2 * pi / lines;
        draw line from (centerX, centerY) to (centerX + cos(angle)*webWidth, centerY + sin(angle) * webWidth))
        edgePolygon = blank polygon
        for edgeNumber in 1..steps:
            x = centerX + cos(angle) * webWidth * edgeNumber / steps
            y = centerY + sin(angle) * webWidth * edgeNumber / steps
            add (x, y) to edgePolygon
        stroke polygon edgePolygon

    // Draw polygon

    areaPolygon = blank polygon
    radialLineNumber = 0
    for value in values:
        angle = radialLineNumber * 2 * pi / lines;
        x = centerX + cos(angle) * value * webWidth / steps
        y = centerY + sin(angle) * value * webWidth / steps
        add (x, y) to areaPolygon
    fill polygon areaPolygon

この疑似コードを実際の に変換するのはあなたに任せますJComponent。私が使用したすべての機能は、またはのいずれMathGraphics2Dです。エリア ポリゴンを描画する前に、その不透明度を設定することができます。

于 2013-02-23T21:04:53.720 に答える
2

あなたの例に関するいくつかのメモ:

  • の機能を使用して、Graphics2Dをレンダリングします。Polygonこれは、を実装しShapeます。

  • ここでgetPreferredSize()説明するように、オーバーライドします。

  • Swing GUIオブジェクトは、イベントディスパッチスレッドでのみ構築および操作する必要があります。

画像

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

public class DrawPolygon extends JPanel {

    int xOffset = 0;
    int yOffset = 0;
    int sizeModifer = 50;
    int numOfPoints = 8;
    int linePosition = 80;

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Polygon outerPolygon = new Polygon();
        for (int i = 0; i < numOfPoints; i++) {
            outerPolygon.addPoint(
                xOffset + (int) (linePosition + sizeModifer
                * Math.cos(i * 2 * Math.PI / numOfPoints)),
                yOffset + (int) ((linePosition - 10) + sizeModifer
                * Math.sin(i * 2 * Math.PI / numOfPoints)));
        }
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(
            RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setColor(Color.cyan);
        g2d.fill(outerPolygon);
        g2d.setStroke(new BasicStroke(2));
        g2d.setColor(Color.red);
        g2d.draw(outerPolygon);
    }

    @Override
    public Dimension getPreferredSize() {
        // TODO calculate size based on geometry
        return new Dimension(160, 160);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setTitle("Show Different Polygons");
                frame.add(new DrawPolygon());
                frame.pack();
                frame.setLocationByPlatform(true);
                frame.setVisible(true);
            }
        });
    }
}

補遺:コメントに基づいて、このリビジョンは元のを復元しinnerPolygonます。

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

public class DrawPolygon extends JPanel {

    int xOffset = 0;
    int yOffset = 0;
    int sizeModifer = 50;
    int numOfPoints = 8;
    int linePosition = 80;

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Polygon outerPolygon = new Polygon();
        for (int i = 0; i < numOfPoints; i++) {
            outerPolygon.addPoint(
                xOffset + (int) (linePosition + sizeModifer
                * Math.cos(i * 2 * Math.PI / numOfPoints)),
                yOffset + (int) ((linePosition - 10) + sizeModifer
                * Math.sin(i * 2 * Math.PI / numOfPoints)));
        }
        Polygon innerPolygon = new Polygon();
        for (int i = 0; i < numOfPoints; i++) {
            int randomRange = 5 + (int) (Math.random() * ((sizeModifer - 5) + 1));
            innerPolygon.addPoint(
                xOffset + (int) (linePosition + randomRange
                * Math.cos(i * 2 * Math.PI / numOfPoints)),
                yOffset + (int) ((linePosition - 10) + randomRange
                * Math.sin(i * 2 * Math.PI / numOfPoints)));
        }
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(
            RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setStroke(new BasicStroke(2));
        g2d.setColor(Color.cyan);
        g2d.fill(outerPolygon);
        g2d.setColor(Color.red);
        g2d.draw(outerPolygon);
        g2d.setColor(Color.blue);
        g2d.fill(innerPolygon);
        g2d.setColor(Color.red);
        g2d.draw(innerPolygon);
    }

    @Override
    public Dimension getPreferredSize() {
        // TODO calculate size based on geometry
        return new Dimension(160, 160);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setTitle("Show Different Polygons");
                frame.add(new DrawPolygon());
                frame.pack();
                frame.setLocationByPlatform(true);
                frame.setVisible(true);
            }
        });
    }
}
于 2013-02-24T14:55:34.483 に答える