package Delaunay;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Iterator;
import java.util.Set;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.SwingUtilities;
public class DelaunayAp extends javax.swing.JApplet implements Runnable {
public void init () {
try {SwingUtilities.invokeAndWait(this);}
catch (Exception e) {System.err.println("Initialization failure");}
}
public void run () {
Container pane = getContentPane();
pane.setLayout(new BorderLayout());
JRadioButton voronoiButton = new JRadioButton("Voronoi Diagram");
voronoiButton.setActionCommand("voronoi");
JRadioButton delaunayButton = new JRadioButton("Delaunay Triangulation");
delaunayButton.setActionCommand("delaunay");
JButton clearButton = new JButton("Clear");
clearButton.setActionCommand("clear");
ButtonGroup group = new ButtonGroup();
group.add(voronoiButton);
group.add(delaunayButton);
JPanel buttonPanel = new JPanel();
buttonPanel.add(voronoiButton);
buttonPanel.add(delaunayButton);
buttonPanel.add(clearButton);
pane.add(buttonPanel, "North");
JLabel circleLabel = new JLabel("Show Empty Circles");
circleLabel.setName("circles");
JLabel delaunayLabel = new JLabel("Show Delaunay Edges");
delaunayLabel.setName("delaunay");
JLabel voronoiLabel = new JLabel("Show Voronoi Edges");
voronoiLabel.setName("voronoi");
JPanel switchPanel = new JPanel();
switchPanel.add(circleLabel);
switchPanel.add(new Label(" "));
switchPanel.add(delaunayLabel);
switchPanel.add(new Label(" "));
switchPanel.add(voronoiLabel);
pane.add(switchPanel, "South");
DelaunayPanel graphicsPanel = new DelaunayPanel();
graphicsPanel.setBackground(Color.gray);
pane.add(graphicsPanel, "Center");
voronoiButton.addActionListener(graphicsPanel);
delaunayButton.addActionListener(graphicsPanel);
clearButton.addActionListener(graphicsPanel);
graphicsPanel.addMouseListener(graphicsPanel);
circleLabel.addMouseListener(graphicsPanel);
delaunayLabel.addMouseListener(graphicsPanel);
voronoiLabel.addMouseListener(graphicsPanel);
voronoiButton.doClick();
}
public static void main (String[] args) {
DelaunayAp applet = new DelaunayAp(); applet.init(); JFrame dWindow = new JFrame(); dWindow.setSize(700, 500); dWindow.setTitle("Voronoi/Delaunay Window");
dWindow.getContentPane().setLayout(new BorderLayout());
dWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
dWindow.getContentPane().add(applet, "Center");
dWindow.setVisible(true); }
}
class DelaunayPanel extends JPanel implements ActionListener, MouseListener {
private DelaunayTriangulation dt; private Simplex initialTriangle; private int initialSize = 10000; private boolean isVoronoi; private boolean showCircles = false; private boolean showDelaunay = false; private boolean showVoronoi= false;
public boolean debug = false;
public Color voronoiColor = Color.magenta;
public Color delaunayColor = Color.green;
public int pointRadius = 3;
private Graphics g;
public DelaunayPanel () {
initialTriangle = new Simplex(new Pnt[] {
new Pnt(-initialSize, -initialSize),
new Pnt( initialSize, -initialSize),
new Pnt( 0, initialSize)});
dt = new DelaunayTriangulation(initialTriangle);
}
public void actionPerformed (ActionEvent e) {
String command = e.getActionCommand();
if (debug) System.out.println(command);
if (command.equals("voronoi")) isVoronoi = true;
else if (command.equals("delaunay")) isVoronoi = false;
else if (command.equals("clear"))
dt = new DelaunayTriangulation(initialTriangle);
repaint();
}
public void mousePressed (MouseEvent e) {
if (e.getComponent() != this) return;
Pnt point = new Pnt(e.getX(), e.getY());
if (debug) System.out.println("Click " + point);
dt.delaunayPlace(point);
repaint();
}
public void mouseEntered (MouseEvent e) {
if (e.getComponent() == this) return;
String name = e.getComponent().getName();
if (debug) System.out.println("Entering " + name);
showCircles = (name == "circles");
showDelaunay = (name == "delaunay");
showVoronoi = (name == "voronoi");
repaint();
}
public void mouseExited (MouseEvent e) {
if (e.getComponent() == this) return;
if (debug) System.out.println("Exiting");
showCircles = false;
showDelaunay = false;
showVoronoi = false;
repaint();
}
public void mouseClicked (MouseEvent e) {}
public void mouseReleased (MouseEvent e) {}
public void draw (Pnt point) {
int r = pointRadius;
int x = (int) point.coord(0);
int y = (int) point.coord(1);
g.fillOval(x-r, y-r, r+r, r+r);
}
public void draw (Pnt endA, Pnt endB) {
g.drawLine((int)endA.coord(0), (int)endA.coord(1),
(int)endB.coord(0), (int)endB.coord(1));
}
public void draw (Pnt center, double radius, Color fillColor) {
int x = (int) center.coord(0);
int y = (int) center.coord(1);
int r = (int) radius;
if (fillColor != null) {
Color temp = g.getColor();
g.setColor(fillColor);
g.fillOval(x-r, y-r, r+r, r+r);
g.setColor(temp);
}
g.drawOval(x-r, y-r, r+r, r+r);
}
public void paintComponent (Graphics g) {
super.paintComponent(g);
this.g = g;
Color temp = g.getColor();
if (!isVoronoi) g.setColor(delaunayColor);
else if (dt.contains(initialTriangle)) g.setColor(this.getBackground());
else g.setColor(voronoiColor);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.setColor(temp);
if (isVoronoi) {
drawAllVoronoi();
drawAllSites();
}
else drawAllDelaunay();
temp = g.getColor();
if (isVoronoi) g.setColor(delaunayColor);
else g.setColor(voronoiColor);
if (showCircles) drawAllCircles();
if (showDelaunay) drawAllDelaunay();
if (showVoronoi) drawAllVoronoi();
g.setColor(temp);
}
public void drawAllDelaunay () {
for (Iterator it = dt.iterator(); it.hasNext();) {
Simplex triangle = (Simplex) it.next();
for (Iterator otherIt = triangle.facets().iterator(); otherIt.hasNext();) {
Set facet = (Set) otherIt.next();
Pnt[] endpoint = (Pnt[]) facet.toArray(new Pnt[2]);
draw(endpoint[0], endpoint[1]);
}
}
}
public void drawAllVoronoi () {
for (Iterator it = dt.iterator(); it.hasNext();) {
Simplex triangle = (Simplex) it.next();
for (Iterator otherIt = dt.neighbors(triangle).iterator(); otherIt.hasNext();) {
Simplex other = (Simplex) otherIt.next();
Pnt p = Pnt.circumcenter((Pnt[]) triangle.toArray(new Pnt[0]));
Pnt q = Pnt.circumcenter((Pnt[]) other.toArray(new Pnt[0]));
draw(p,q);
}
}
}
public void drawAllSites () {
for (Iterator it = dt.iterator(); it.hasNext();) {
for (Iterator otherIt = ((Simplex) it.next()).iterator(); otherIt.hasNext();)
draw((Pnt) otherIt.next());
}
}
public void drawAllCircles () {
loop: for (Iterator it = dt.iterator(); it.hasNext();) {
Simplex triangle = (Simplex) it.next();
for (Iterator otherIt = initialTriangle.iterator(); otherIt.hasNext();) {
Pnt p = (Pnt) otherIt.next();
if (triangle.contains(p)) continue loop;
}
Pnt c = Pnt.circumcenter((Pnt[]) triangle.toArray(new Pnt[0]));
double radius = c.subtract((Pnt) triangle.iterator().next()).magnitude();
draw(c, radius, null);
}
}
}