1

興味深い問題があります。Java グラフィックスを使用して、事前に定義されたギャップ定数で間隔をあけた平行線で円を描きたいと思います。円には既知の x と y の位置と半径があります。線は円の中心から開始し、円の外側に移動する必要があります。例えば、

ここに画像の説明を入力

次のように、最初に線を引いて正方形全体を埋めるのが最も簡単だと思います。

ここに画像の説明を入力

そしておそらく4つのポリゴンを描き、それらを白く塗りつぶします。4 つのポリゴンは次のようにラベル付けされます。

ここに画像の説明を入力

ご覧のとおり、この場合の多角形は、左上の点 (x,y)、円の半径によって定義される幅と高さのエッジ、および (x+radius, y+radius) からの円弧によって定義されます。 .

必要なフィードバック:

  1. Javaでそのようなポリゴンを描くことさえ可能ですか?
  2. このロジックは理にかなっていますか?これはあなたにとってより簡単に思えますか?
  3. 別の方法は、円を構成するピクセルを何らかの方法で決定し、それらを使用して線を描画することです。しかし、これは私には面倒に思えます。同意しますか?
  4. これを行う別の方法を考えられますか?

重要:このソリューションには垂直線がありますが、線は角度シータで定義する必要があることに注意してください。つまり、角度を付けることができます (ただし、すべて互いに平行です)。

誰かが実際にこれを描画するコードを提供できれば、私は永遠に感謝します!! :)

public void draw(Graphics g, int x, int y, int radius, int lineGap, int lineThickness, int theta) {
   //g = the graphics object
   //x,y = the top left coordinate of the square
   //radius = the radius of the circle, the width of the rectangle, the height of the rectangle
   //lineGap = the gap in between each of the lines
   //lineThickness = the thickness of the lines in pixels
   //theta = the angle that the lines should be at, relative to the y axis
}
4

3 に答える 3

5

古いピタゴラスの Thereomを使用すると、この単純な代数が続きます... x と r に関する y

rは円の半径です。
xは、円を反復処理する変数です。増分では、半径と間隔を知ることで簡単に解決できます。

各線の高さ (およびその x 位置) を知っていれば、垂直線を円の中心に平行に配置するのは難しくありません (配置座標が通常のように左上隅を指定している場合は、それy = circle_center - (line_length / 2)

また、左上隅から垂直線の座標を指定する場合は、x 座標を計算するときにそれらの太さを考慮する必要があることに注意してください。
これは非常に簡単で、円で示される x 値を使用します。
true_x = suggested_x - (line_width / 2)

斜めの線を扱うには、他のより賢明な回答を参照してください

この手順は、各行の正確なドメイン/範囲を見つけることよりもクリップを使用することの感度のデモンストレーションとして残っています(そして、私の人生の多くを無駄にしたためです)。

ここに画像の説明を入力 ここに画像の説明を入力 ここに画像の説明を入力 ここに画像の説明を入力 ここで私にとっての楽しみは終わりました。 ここに画像の説明を入力

うーん!最後の m を「tan(theta)」に置き換えます

于 2013-01-14T00:52:57.220 に答える
3

グラフィッククリッピングを簡単に変更...

ここに画像の説明を入力

public class SimplePaint02 {

    public static void main(String[] args) {
        new SimplePaint02();
    }

    public SimplePaint02() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(100, 100);
        }

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

            int radius = Math.min(getWidth(), getHeight());
            int x = (getWidth() - radius) / 2;
            int y = (getHeight()- radius) / 2;

            BufferedImage buffer = new BufferedImage(radius, radius, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = buffer.createGraphics();

            Ellipse2D circle = new Ellipse2D.Float(0, 0, radius, radius);
            Shape clip = g2d.getClip();
            g2d.setClip(circle);
            int gap = getWidth() / 10;
            g2d.setColor(Color.RED);
            for (int index = 0; index < 10; index++) {

                g2d.drawLine(index * gap, 0, index * gap, radius);

            }
            g2d.setClip(clip);
            g2d.setColor(Color.BLUE);
            g2d.draw(circle);
            g2d.dispose();
            g.drawImage(buffer, x, y, this);
        }

    }

}

アップデート

画面にレンダリングされているグラフィックス コンテキストのクリッピングを絶対に変更しないでください。これにより、画面のレンダリングが大幅に台無しになる可能性があります ;)

更新 #2

AffinTransformation回転をサポートするための の使用を示す例...

ここに画像の説明を入力

public class CirlceDraw {

    public static void main(String[] args) {
        new CirlceDraw();
    }

    public CirlceDraw() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public class TestPane extends JPanel {

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(100, 100);
        }

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

            int radius = Math.min(getWidth(), getHeight());
            int x = (getWidth() - radius) / 2;
            int y = (getHeight() - radius) / 2;

            BufferedImage buffer = new BufferedImage(radius, radius, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g2d = buffer.createGraphics();

            Ellipse2D circle = new Ellipse2D.Float(0, 0, radius, radius);
            Shape clip = g2d.getClip();
            g2d.setClip(circle);
            AffineTransform at = g2d.getTransform();
            g2d.setTransform(AffineTransform.getRotateInstance(Math.toRadians(33), radius / 2, radius / 2));
            int gap = getWidth() / 10;
            g2d.setColor(Color.RED);
            for (int index = 0; index < 10; index++) {

                g2d.drawLine(index * gap, 0, index * gap, radius);

            }
            g2d.setTransform(at);
            g2d.setClip(clip);
            g2d.setColor(Color.BLUE);
            g2d.draw(circle);
            g2d.dispose();
            g.drawImage(buffer, x, y, this);
        }

    }

}
于 2013-01-14T01:01:07.487 に答える
1

私は三角法を使用します。

直線のxは、原点 (円の中心) からの角度の余弦によって与えられます。それで、arccos(x)どちらが角度であるかを教えてくれます。

角度を取得したら、sinussin関数を使用して最大の高さを取得できます。

もちろん、すべての Java 三角関数はラジアン (360 度 = 2*PI ラジアン) で機能します。

于 2013-01-14T00:48:46.100 に答える