使用Java图形在其中绘制线条

时间:2013-01-14 00:40:58

标签: java geometry awt java-2d

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

enter image description here

我想成像,最简单的方法是首先绘制线条以填满整个方块,如下所示:

enter image description here

然后可能绘制4个多边形并用白色填充它们。 4个多边形标记如下:

enter image description here

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

需要反馈:

  1. 甚至可以用Java绘制这样的多边形吗?
  2. 这个逻辑有意义吗?这对你来说似乎更容易吗?
  3. 另一种方法是以某种方式确定构成圆的像素并使用它们绘制线条。但这对我来说似乎很混乱。你同意吗?
  4. 您能想到另一种方法吗?
  5. 重要事项:请注意,虽然此解决方案具有垂直线,但应使用某个角度θ来定义线条。也就是说,它们可以成角度(但彼此平行)。

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

    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
    }
    

3 个答案:

答案 0 :(得分:5)

使用ol'Pythagorean Thereom,这个简单的代数跟随...... y in terms of x and r

r 是圆的半径 x 是您将在圆圈中迭代的变量,您可以通过知道半径和间距轻松计算出来。

知道每条线的高度(以及它们的x位置),并不是以垂直于cirlce中心的垂直线为中心的挑战(如果你的位置坐标像往常一样指定左上角,你将会想把它放在y = circle_center - (line_length / 2)

另请注意,如果您通过左上角指定垂直线的坐标,则需要考虑计算x坐标时它们的厚度。
这非常简单,使用圆圈建议的x值 true_x = suggested_x - (line_width / 2)

请参阅其他更明智的答案来处理斜线

此过程仍然是对使用剪辑而不是找到每行的确切域/范围的敏感性的证明(并且因为我浪费了太多的生命)。

enter image description here enter image description here enter image description here enter image description here 这就是为我带来乐趣的地方。 enter image description here

OOMPH!用'tan(theta)'

替换最后一个m

答案 1 :(得分:3)

简单更改图形剪辑......

enter image description here

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来支持轮换......

enter image description here

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);
        }

    }

}

答案 2 :(得分:1)

我会使用三角法。

你的线的x是由原点(圆心)的角度余弦给出的。所以,arccos(x)会给你哪个角度。

获得角度后,可以使用正弦sin函数获得其最大高度。

当然,所有java trig函数都使用弧度(360度= 2 * PI弧度)。