import javax.swing.*; import java.awt.*; import java.util.*; import java.util.List; public class Delaunay extends JFrame { public static Triangle[] triangulateDelaunay(long[] x, long[] y) { int n = x.length; long[] z = new long[n]; for (int i = 0; i < n; i++) z[i] = x[i] * x[i] + y[i] * y[i]; List res = new ArrayList<>(); for (int i = 0; i < n - 2; i++) { for (int j = i + 1; j < n; j++) { m1: for (int k = i + 1; k < n; k++) { if (j == k) continue; long nx = (y[j] - y[i]) * (z[k] - z[i]) - (y[k] - y[i]) * (z[j] - z[i]); long ny = (x[k] - x[i]) * (z[j] - z[i]) - (x[j] - x[i]) * (z[k] - z[i]); long nz = (x[j] - x[i]) * (y[k] - y[i]) - (x[k] - x[i]) * (y[j] - y[i]); if (nz >= 0) continue; for (int m = 0; m < n; m++) { long dot = (x[m] - x[i]) * nx + (y[m] - y[i]) * ny + (z[m] - z[i]) * nz; if (dot > 0) continue m1; } // to deal with 4 points on a circle int[] s1 = { i, j, k, i }; for (Triangle t : res) { int[] s2 = { t.a, t.b, t.c, t.a }; for (int u = 0; u < 3; u++) for (int v = 0; v < 3; v++) if (isCrossIntersect(x[s1[u]], y[s1[u]], x[s1[u + 1]], y[s1[u + 1]], x[s2[v]], y[s2[v]], x[s2[v + 1]], y[s2[v + 1]])) continue m1; } res.add(new Triangle(i, j, k)); } } } return res.toArray(new Triangle[0]); } static class Triangle { int a, b, c; public Triangle(int a, int b, int c) { this.a = a; this.b = b; this.c = c; } } static boolean isCrossIntersect(long x1, long y1, long x2, long y2, long x3, long y3, long x4, long y4) { long z1 = (x3 - x1) * (y2 - y1) - (y3 - y1) * (x2 - x1); long z2 = (x4 - x1) * (y2 - y1) - (y4 - y1) * (x2 - x1); if (z1 < 0 && z2 < 0 || z1 > 0 && z2 > 0 || z1 == 0 || z2 == 0) return false; long z3 = (x1 - x3) * (y4 - y3) - (y1 - y3) * (x4 - x3); long z4 = (x2 - x3) * (y4 - y3) - (y2 - y3) * (x4 - x3); if (z3 < 0 && z4 < 0 || z3 > 0 && z4 > 0 || z3 == 0 || z4 == 0) return false; return true; } public Delaunay() { // 4 points on a circle // final long[] x = { 0, 0, 100, 100 }; // final long[] y = { 0, 100, 100, 0 }; int n = 100; final long[] x = new long[n]; final long[] y = new long[n]; Random rnd = new Random(); for (int i = 0; i < n; i++) { x[i] = rnd.nextInt(500) + 1; y[i] = rnd.nextInt(500) + 1; } final Triangle[] ts = triangulateDelaunay(x, y); JPanel panel = new JPanel() { protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = ((Graphics2D) g); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setStroke(new BasicStroke(3)); g.setColor(Color.BLUE); for (Triangle t : ts) { g.drawLine((int) x[t.a], (int) y[t.a], (int) x[t.b], (int) y[t.b]); g.drawLine((int) x[t.a], (int) y[t.a], (int) x[t.c], (int) y[t.c]); g.drawLine((int) x[t.c], (int) y[t.c], (int) x[t.b], (int) y[t.b]); } g.setColor(Color.RED); for (int i = 0; i < x.length; i++) { g.drawOval((int) x[i] - 1, (int) y[i] - 1, 3, 3); } } }; setContentPane(panel); } public static void main(String[] args) { JFrame frame = new Delaunay(); frame.setSize(new Dimension(800, 600)); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.setVisible(true); } }