1

我有一个有趣的问题。使用Java图形,我想画一个圆圈,圆圈中有平行线,它们之间有一些预先定义的间隙常数。圆具有已知的 x 和 y 位置以及半径。这些线应该从圆的中心开始,并且应该向外移动。例如,

在此处输入图像描述

我想最简单的方法是先画线来填满整个正方形,如下所示:

在此处输入图像描述

然后也许画4个多边形并用白色填充它们。4个多边形标记如下:

在此处输入图像描述

如您所见,在这种情况下,多边形由左顶点 (x,y) 定义,宽度和高度边缘由圆的半径定义,然后是 (x+radius, y+radius) 的弧.

需要反馈:

  1. 甚至可以在 Java 中绘制这样的多边形吗?
  2. 这个逻辑有意义吗?这对你来说似乎更容易?
  3. 另一种方法是以某种方式确定构成圆的像素并使用这些像素绘制线条。但这对我来说似乎很乱。你同意?
  4. 你能想到另一种方法吗?

重要提示:请注意,虽然此解决方案具有垂直线,但应根据某个角度 theta 定义这些线。也就是说,它们可以倾斜(但都相互平行)。

如果有人可以提供实际绘制的代码,我将永远感激不尽!!:)

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

使用 ol' Pythagorean Thereom,这个简单的代数如下...... y 根据 x 和 r

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

显示使用 anAffinTransformation来支持旋转的示例...

在此处输入图像描述

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 trig 函数都使用弧度(360 度 = 2*PI 弧度)。

于 2013-01-14T00:48:46.100 回答