如何在 Java 中找到沿 Arc2D 的所有坐标?
How can I find all of the coordinates along an Arc2D in Java?
我在 Java 中绘制了一个 Arc2D,我希望能够找到 Arc2D 包含的所有点。有什么办法可以做到吗?
您想使用 PathIterator
基本上这将允许您在构成路径的点之间进行迭代。您可以使用 flatness
参数
控制“精度”(或点之间的距离)
例如...
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();
}
}
}
我在 Java 中绘制了一个 Arc2D,我希望能够找到 Arc2D 包含的所有点。有什么办法可以做到吗?
您想使用 PathIterator
基本上这将允许您在构成路径的点之间进行迭代。您可以使用 flatness
参数
例如...
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();
}
}
}