Detecting self crossing in closed Bezier curves
algorithm, bezier, geometry, java, java-2d
Solution
I have actually found a working solution which is using built in Java2D functions and is EXTREMELY fast...
Simply create a Path2D out of your curves, then create an area out of your Path2D and invoke the method Area.isSingular();
It works... See this small example.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Area;
import java.awt.geom.CubicCurve2D;
import java.awt.geom.Path2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Test {
@SuppressWarnings("serial")
public static void main(String[] args) {
JFrame f = new JFrame("Test");
JPanel c = new JPanel() {
Area a;
Path2D p;
{
p = new Path2D.Double();
p.append(new CubicCurve2D.Double(0, 0, 100, 0, 150, 50, 200, 100), true);
p.append(new CubicCurve2D.Double(200, 100, 200, 150, 150,0, 50, 100), true);
p.append(new CubicCurve2D.Double(100, 100, 100, 50, 50, 50, 0, 0), true);
a = new Area(p);
setPreferredSize(new Dimension(300, 300));
}
@Override
protected void paintComponent(Graphics g) {
g.setColor(Color.black);
((Graphics2D)g).fill(p);
System.out.println(a.isSingular());
}
};
f.setContentPane(c);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setVisible(true);
}
}
Problem
I've created a "blob" shape by patching cubic Bezier curves together (screenshot below). I'd like to be able to detect the situation where a curve has crossed over either itself or another curve and was wondering if there's a recommended approach or known algorithm for doing this? One idea I had was to use a `FlatteningPathIterator` to decompose the shape into straight line segments and then detect whether a given segment crosses with another one, but I'd be interested in whether there's a better approach (as this will have quadratic performance). If I do pursue this method are there library functions in Java to detect whether two line segments are overlapping? Thanks. No Cross-Over No Crossover http://www.freeimagehosting.net/uploads/7ad585414d.png Cross-Over Crossover http://www.freeimagehosting.net/uploads/823748f8bb.png