0

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?

49KWIC
  • 68
  • 1
  • 5
  • 1
    You need to use a `PathIterator`, for [example](https://stackoverflow.com/questions/32392095/how-to-rotate-a-rectangle-after-reaching-specified-position/32397121#32397121). Remember, a Circle is just made of a lot of straight lines, depending on the "flatness" (or the number of points used to make the shape) – MadProgrammer May 01 '22 at 22:18

1 Answers1

2

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

    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366