Search code examples
javagraphicscoordinatesgraphics2d

How can I find all of the coordinates along an Arc2D in Java?


I have drawn an Arc2D in Java and I want to be able to find all of the points that the Arc2D contains. Is there any way that I can do that?


Solution

  • You want to make use of a PathIterator

    Basically this will allow you to iterator between the points that make up the path. You can control the "accuracy" (or distance between the points) using the flatness parameter

    For example...

    enter image description hereenter image description here

    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.geom.Arc2D;
    import java.awt.geom.Ellipse2D;
    import java.awt.geom.PathIterator;
    import java.awt.geom.Point2D;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JSlider;
    import javax.swing.event.ChangeEvent;
    import javax.swing.event.ChangeListener;
    
    public final class Main {
        public static void main(String[] args) {
            new Main();
        }
    
        public Main() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    JFrame frame = new JFrame();
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            private Arc2D shape;
            private double flatness = 0.4;
    
            public TestPane() {
                shape = new Arc2D.Double(50, 50, 100, 100, 0, 180, Arc2D.OPEN);
    
                setLayout(new BorderLayout());
                JSlider slider = new JSlider(0, 100);
                slider.addChangeListener(new ChangeListener() {
                    @Override
                    public void stateChanged(ChangeEvent e) {
                        double progress = slider.getValue() / 100d;
                        flatness = 0.001 + (0.4d * progress);
                        repaint();
                    }
                });
                slider.setValue(0);
    
                add(slider, BorderLayout.SOUTH);
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(200, 200);
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
                g2d.draw(shape);
                g2d.setColor(Color.RED);
                PathIterator pi = shape.getPathIterator(null, flatness);
                // Use this if you want to draw lines between the points
                Point2D lastPoint;
                while (!pi.isDone()) {
                    double[] coords = new double[6];
                    switch (pi.currentSegment(coords)) {
                        case PathIterator.SEG_MOVETO:
                            // Starting point of next line
                            lastPoint = new Point2D.Double(coords[0], coords[1]);
                            // You don't need this if you're drawing lines
                            g2d.fill(new Ellipse2D.Double(coords[0] - 2, coords[1] - 2, 4, 4));
                            break;
                        case PathIterator.SEG_LINETO:
                            g2d.fill(new Ellipse2D.Double(coords[0] - 2, coords[1] - 2, 4, 4));
                            // If you were drawing lines, then you'd draw a line
                            // between the last point and this point
                            lastPoint = new Point2D.Double(coords[0], coords[1]);
                            break;
                    }
                    pi.next();
                }
                g2d.dispose();
            }
    
        }
    }