signalprocesser.voronoi.VoronoiTest Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mia-algorithms Show documentation
Show all versions of mia-algorithms Show documentation
ModularImageAnalysis (MIA) is an ImageJ plugin which provides a modular framework for assembling image and object analysis workflows. Detected objects can be transformed, filtered, measured and related. Analysis workflows are batch-enabled by default, allowing easy processing of high-content datasets.
/*
* "Concave" hulls by Glenn Hudson and Matt Duckham
*
* Source code downloaded from https://archive.md/l3Un5#selection-571.0-587.218 on 3rd November 2021.
*
* - This software is Copyright (C) 2008 Glenn Hudson released under Gnu Public License (GPL). Under
* GPL you are free to use, modify, and redistribute the software. Please acknowledge Glenn Hudson
* and Matt Duckham as the source of this software if you do use or adapt the code in further research
* or other work. For full details of GPL see http://www.gnu.org/licenses/gpl-3.0.txt.
* - This software comes with no warranty of any kind, expressed or implied.
*
* A paper with full details of the characteristic hulls algorithm is published in Pattern Recognition.
* Duckham, M., Kulik, L., Worboys, M.F., Galton, A. (2008) Efficient generation of simple polygons for
* characterizing the shape of a set of points in the plane. Pattern Recognition v41, 3224-3236
*
* The software was developed by Glenn Hudson while working with me as an RA. The characteristic shapes
* algorithm is collaborative work between Matt Duckham, Lars Kulik, Antony Galton, and Mike Worboys.
*
*/
package signalprocesser.voronoi;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Area;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.StringTokenizer;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.UIManager;
import signalprocesser.shared.JCollapsiblePanel;
import signalprocesser.shared.StatusDialog;
import signalprocesser.voronoi.representation.AbstractRepresentation;
import signalprocesser.voronoi.representation.RepresentationFactory;
import signalprocesser.voronoi.representation.RepresentationInterface;
import signalprocesser.voronoi.representation.boundaryproblem.BoundaryProblemRepresentation;
import signalprocesser.voronoi.representation.triangulation.TriangulationRepresentation;
import signalprocesser.voronoi.shapegeneration.ShapeGeneration;
import signalprocesser.voronoi.shapegeneration.ShapeGenerationException;
import signalprocesser.voronoi.statusstructure.VLinkedNode;
import signalprocesser.voronoi.statusstructure.binarysearchtreeimpl.debug.DebugTree;
import signalprocesser.voronoi.tools.CountryData;
import signalprocesser.voronoi.tools.CountryListModel;
import signalprocesser.voronoi.tools.TestSuite;
public class VoronoiTest extends javax.swing.JFrame {
javax.swing.ButtonGroup groupMatt = new javax.swing.ButtonGroup();
// Frame height/width
public static final int FRAME_WIDTH = 800;
public static final int FRAME_HEIGHT = 400;
// Margin around the generated shapes
public static final int SHAPEMARGIN_TOPBOTTOM = 60;
public static final int SHAPEMARGIN_LEFTRIGHT = 120;
public static final int POINT_SIZE = 10;
public static final String SAVE_FILE = "voronoipoints.txt";
public static DebugTree treedialog = null;
private boolean SHOW_POINTS = false;
private boolean SHOW_POINT_COORDINATES = false;
private boolean SHOW_MOUSE_LOCATION = false;
private boolean SHOW_INTERACTIVE_SWEEPLINE = false;
private boolean SHOW_CIRCLEEVENTS = false;
private boolean SHOW_EXPECTED_BORDER = false;
private boolean SHOW_INTERSECTION_WITH_EXPECTED = false;
private boolean SHOW_ALPHA_SHAPE = false;
private int backupboundaryenhancedvalue = -1;
private double expectedarea = -1;
private String lastdirectoryopened = null;
private CountryListModel countrylistmodel;
private Shape alphashape;
private SignalPanel panel;
private ArrayList points = new ArrayList();
private ArrayList borderpoints = null;
private TestRepresentationWrapper representationwrapper = new TestRepresentationWrapper();
private AbstractRepresentation representation;
public static void main(String args[]) {
// Set look and feel
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
displayError(null, e);
}
// Load the application
VoronoiTest frame = new VoronoiTest();
frame.setVisible(true);
}
/** Creates new form MainFrame */
public VoronoiTest() {
// Inital components
initComponents();
initMattComponents();
// Sync the state with what is being visually shown
sliderAreaCutOffToUseStateChanged(null);
chkShowPointsActionPerformed(null);
chkShowPointCoordinatesActionPerformed(null);
chkShowCircleEventsActionPerformed(null);
chkShowTreeStructureActionPerformed(null);
chkShowMouseLocationActionPerformed(null);
chkShowSweeplineActionPerformed(null);
chkShowEdgeLengthsActionPerformed(null);
chkShowInternalTrianglesActionPerformed(null);
chkShowMinimumSpanningTreeActionPerformed(null);
chkShowDebugInfoActionPerformed(null);
chkMaxEdgesToRemoveActionPerformed(null);
chkShowExpectedBorderActionPerformed(null);
chkShowIntersectionActionPerformed(null);
// Set the default generation to use
optLetterGenerationActionPerformed(null);
//optCountryGenerationActionPerformed(null);
// Set the representation
//optNone.setSelected(true);
//optNoneActionPerformed(null);
optEdgeRemoval.setSelected(true);
optEdgeRemovalActionPerformed(null);
//optClustering.setSelected(true);
//optClusteringActionPerformed(null);
// Load any saved points
//try {
// loadPoints();
//} catch ( IOException e ) {
// displayError(e);
// }
// Set countries to country list
try {
cboCountries.setModel( countrylistmodel = new CountryListModel(cboCountries,CountryData.getCountryList()) );
} catch ( IOException e ) {
displayError(e);
}
// Add panel
panel = new SignalPanel();
getContentPane().add(panel, java.awt.BorderLayout.CENTER);
// Center the entire frame
Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
super.setBounds(
(screensize.width-FRAME_WIDTH)/2,
(screensize.height-FRAME_HEIGHT)/2,
FRAME_WIDTH, FRAME_HEIGHT);
}
public class SignalPanel extends JPanel implements MouseListener, MouseMotionListener {
private int mouse_x = -1;
private int mouse_y = -1;
private int attentiontopoint = -1;
private VPoint attentiontovpoint = null;
private VPoint attentiontovpoint_onclick = null;
public SignalPanel() {
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
public void mousePressed(MouseEvent e) {
// If mouse button 1
if ( e.getButton()==MouseEvent.BUTTON1 ) {
if ( attentiontovpoint!=null ) {
attentiontovpoint_onclick = attentiontovpoint;
} else {
// Get dimensions
double width = this.getWidth();
double height = this.getHeight();
// Add to vector
if ( representation==null ) {
points.add( new VPoint(e.getX(), e.getY()) );
} else {
points.add( representation.createPoint(e.getX(), e.getY()) );
}
// Save the points
//try {
// savePoints();
//} catch ( IOException e2 ) {
// displayError(e2);
// }
// Determine mouse over
int mouseoverindex = getPointOverIndex(e.getX(), e.getY());
if ( mouseoverindex!=attentiontopoint ) {
attentiontopoint = mouseoverindex;
}
}
} else if ( attentiontovpoint!=null ) { // If other mouse button
points.remove(attentiontovpoint);
attentiontopoint = -1;
attentiontovpoint = null;
attentiontovpoint_onclick = null;
// Save the points
//try {
// savePoints();
//} catch ( IOException e2 ) {
// displayError(e2);
// }
// Determine mouse over
int mouseoverindex = getPointOverIndex(e.getX(), e.getY());
if ( mouseoverindex!=attentiontopoint ) {
attentiontopoint = mouseoverindex;
}
}
// Repaint
this.getParent().repaint();
// Update controls (post repaint)
updateControls();
}
public void paintComponent(Graphics _g) {
Graphics2D g = (Graphics2D) _g;
// Get dimensions
double width = this.getWidth();
double height = this.getHeight();
// Set background color
g.setColor(Color.white);
g.fillRect(0,0,(int)width,(int)height);
// Draw mouse coord
g.setColor(Color.black);
if ( SHOW_MOUSE_LOCATION || SHOW_INTERACTIVE_SWEEPLINE ) {
g.drawString("(" + mouse_x + ", " + mouse_y + ")", 5 , (int)height-20);
}
// Run algorithm
// ( being very careful to catch errors and show them to the user )
try {
g.setColor( Color.red );
representationwrapper.innerrepresentation = representation;
if ( SHOW_INTERACTIVE_SWEEPLINE==false ) {
if ( points!=null ) {
VoronoiAlgorithm.generateVoronoi(representationwrapper, points);
}
} else {
if ( attentiontovpoint!=null ) {
if ( points!=null ) {
VoronoiAlgorithm.generateVoronoi(representationwrapper, points, g, attentiontovpoint, mouse_y);
}
} else {
if ( points!=null ) {
VoronoiAlgorithm.generateVoronoi(representationwrapper, points, g, attentiontovpoint_onclick, mouse_y);
}
}
}
} catch ( Error e ) {
points.clear();
displayError(e); throw e;
} catch ( RuntimeException e ) {
points.clear();
displayError(e); throw e;
}
// Show Intersection with expected border
if ( SHOW_INTERSECTION_WITH_EXPECTED && borderpoints!=null && representation instanceof TriangulationRepresentation) {
// Get the representation
TriangulationRepresentation triangularrep = (TriangulationRepresentation) representation;
// Check we're in edge removal mode
if ( triangularrep.getMode()==TriangulationRepresentation.MODE_REDUCE_OUTER_BOUNDARIES ) {
// Create the initial area required
Area area = ShapeGeneration.createArea( borderpoints );
// Calculate the exclusive or with second area
ArrayList outterpoints = triangularrep.getPointsFormingOutterBoundary();
area.exclusiveOr( ShapeGeneration.createArea( outterpoints ) );
// Draw the resulting shape
g.setPaint(Color.yellow);
g.fill( ShapeGeneration.createShape(area) );
// Set captions appropriately
try {
Shape shape = ShapeGeneration.createShape(area);
double l2norm = VoronoiShared.calculateAreaOfShape(shape);
double error = l2norm / expectedarea * 100;
txtL2Norm.setText( String.format("%.1f",l2norm) + " pixels^2");
txtErrorFromExpectedArea.setText( String.format("%.2f",error) + "%");
} catch ( Exception e ) {
e.printStackTrace();
txtL2Norm.setText( "Error" );
txtErrorFromExpectedArea.setText( "Error" );
}
try {
txtActualArea.setText( String.format("%.1f",VoronoiShared.calculateAreaOfShape(outterpoints)) + " pixels^2");
} catch ( Exception e ) {
e.printStackTrace();
txtActualArea.setText( "Error" );
}
try {
txtActualPerimeter.setText( String.format("%.1f",VoronoiShared.calculatePerimeterOfShape(outterpoints)) + " pixels");
} catch ( Exception e ) {
e.printStackTrace();
txtActualPerimeter.setText( "Error" );
}
}
}
// Draw the expected border (if we even have one)
if ( SHOW_EXPECTED_BORDER && borderpoints!=null ) {
VPoint prev = null;
Stroke originalstroke = g.getStroke();
g.setStroke(new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
g.setColor(Color.red);
for ( VPoint point : borderpoints ) {
if ( prev==null ) {
prev = point;
continue;
}
// Paint line
g.drawLine(prev.x, prev.y, point.x, point.y);
// Set the new previous point
prev = point;
}
g.setStroke(originalstroke);
}
// Drawing points
if ( points!=null && SHOW_POINTS ) {
g.setColor(Color.blue);
for ( VPoint point : points ) {
g.fillOval((int)(point.x-POINT_SIZE/2), (int)(point.y-POINT_SIZE/2), POINT_SIZE, POINT_SIZE);
if ( SHOW_POINT_COORDINATES ) {
g.drawString("(" + point.x + "," + point.y + ")", (int)(point.x+POINT_SIZE/2+1), (int)(point.y));
}
}
}
// Show circle events
if ( SHOW_CIRCLEEVENTS ) {
g.setColor(Color.red);
for ( VPoint point : representationwrapper.circleevents ) {
g.fillOval((int)(point.x-POINT_SIZE/2), (int)(point.y-POINT_SIZE/2), POINT_SIZE, POINT_SIZE);
if ( SHOW_POINT_COORDINATES ) {
g.drawString("(" + point.x + "," + point.y + ")", (int)(point.x+POINT_SIZE/2+1), (int)(point.y));
}
}
}
// Show alpha shapes
if(SHOW_ALPHA_SHAPE){
// Draw the resulting shape
g.setPaint(Color.green);
g.draw(alphashape);
g.setPaint(new Color(0,255,0,25));
g.fill(alphashape);
}
// Paint the representation
if ( representation!=null ) {
g.setColor(Color.magenta);
// Be very careful to catch errors and show them to the user
try {
representation.paint(g);
} catch ( Error e ) {
displayError(e); throw e;
} catch ( RuntimeException e ) {
displayError(e); throw e;
}
}
}
public void mouseMoved(MouseEvent e) {
if ( mouse_x==e.getX() && mouse_y==e.getY() ) return;
int mouseoverindex = getPointOverIndex(mouse_x = e.getX(), mouse_y = e.getY());
if ( mouseoverindex!=attentiontopoint ) {
attentiontopoint = mouseoverindex;
}
if ( SHOW_MOUSE_LOCATION || SHOW_INTERACTIVE_SWEEPLINE ) {
this.repaint();
}
}
private int getPointOverIndex(int mouse_x, int mouse_y) {
for ( int x=0 ; x=point.x-POINT_SIZE/2 && mouse_x<=point.x+POINT_SIZE/2
&& mouse_y>=point.y-POINT_SIZE/2 && mouse_y<=point.y+POINT_SIZE/2 ) {
attentiontovpoint = point;
return x;
}
}
attentiontovpoint = null;
return -1;
}
// Ignored
public void mouseDragged(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
}
private void savePoints() throws IOException {
savePoints(SAVE_FILE);
}
private void savePoints(String filename) throws IOException {
FileWriter writer = new FileWriter(filename);
for ( VPoint point : points ) {
writer.write(point.x + "," + point.y + "\n");
}
writer.close();
}
private void exportPoints(String filename) throws IOException {
FileWriter writer = new FileWriter(filename);
for ( VPoint point : points ) {
writer.write(point.x + " " + point.y + "\n");
}
writer.close();
}
private void loadPoints() throws IOException {
loadPoints(SAVE_FILE);
}
private void loadPoints(String filename) throws IOException {
// Clear the points array
points.clear();
borderpoints = null;
// Load the points
try {
BufferedReader reader = new BufferedReader(new FileReader(filename));
String line;
while ( (line=reader.readLine())!=null ) {
if ( line.trim().length()<=0 ) continue;
// Split components of line
String[] values;
if ( line.indexOf(',')>0 ) {
values = line.split(",", 2);
} else if ( line.indexOf(' ')>0 ) {
values = line.split(" ", 2);
} else {
throw new IOException("Expected value line to be comma or space seperated - except found neither");
}
// Get values
int x = Integer.parseInt(values[0]);
int y = Integer.parseInt(values[1]);
// Add to points array
if ( representation==null ) {
points.add( new VPoint(x, y) );
} else {
points.add( representation.createPoint(x, y) );
}
}
reader.close();
} catch ( FileNotFoundException e ) {
// ignore this exception
}
}
private void initMattComponents(){
JCollapsiblePanel mattPanel = new JCollapsiblePanel();
mattPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Matt's custom controls"));
JButton hi = new JButton("Read in alpha shape");
mattPanel.add(hi);
//panelTop.add(mattPanel);
hi.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
hiActionPerformed(evt);
}
});
}
private void hiActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_optMaxEdgeOfSmallestTEdgeActionPerformed
javax.swing.JFileChooser jfc = new javax.swing.JFileChooser();
//jfc.setCurrentDirectory(new File("d:/Research/Live/Nonconvex"));
jfc.showOpenDialog(this);
String filename = jfc.getSelectedFile().getAbsolutePath();
// Read in alphashape
int [] points = this.getAlphaShapeFromFile(filename + "-alf");
//for(int i=0; i=0){
//System.out.println(lineno);
// first two numbers to read in
if(lastnumber<0){
points[lineno]=data[i][0];
points[lineno+1]=data[i][1];
lastnumber=data[i][1];
data[i][0]=-1;
data[i][1]=-1;
lineno+=2;
change=true;
}
else{
if(data[i][0]==lastnumber){
points[lineno]=data[i][1];
lineno+=1;
lastnumber = data[i][1];
data[i][0]=-1;
data[i][1]=-1;
change=true;
}
else if (data[i][1]==lastnumber){
points[lineno]=data[i][0];
lineno+=1;
lastnumber = data[i][0];
data[i][0]=-1;
data[i][1]=-1;
change=true;
}
}
}
}
}
System.out.println("Lineno=" + lineno + ", points=" + points.length);
for(int i=0; i=points.length-1)more=false;
lastnumber=-1;
lineno=lineno-1;
change=true;
// Place negative number at end of segment
points[lineno-1]=-points[lineno-1];
}
return points;
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
// //GEN-BEGIN:initComponents
private void initComponents() {
groupRepresentations = new javax.swing.ButtonGroup();
groupEdgeRemoval = new javax.swing.ButtonGroup();
optBoundary = new javax.swing.JRadioButton();
optBoundaryUsingAngle20 = new javax.swing.JRadioButton();
optBoundaryUsingAngle30 = new javax.swing.JRadioButton();
optBoundaryEnhanced = new javax.swing.JRadioButton();
panelBoundaryEnhanced = new javax.swing.JPanel();
sliderAreaCutOffToUse = new javax.swing.JSlider();
groupGenerationType = new javax.swing.ButtonGroup();
scrollRight = new javax.swing.JScrollPane();
panelRight = new javax.swing.JPanel();
panelTop = new javax.swing.JPanel();
panelActions = new JPanel();
panelActionsInner = new javax.swing.JPanel();
jPanel6 = new javax.swing.JPanel();
btnSave = new javax.swing.JButton();
JButton btnExport = new javax.swing.JButton();
btnLoad = new javax.swing.JButton();
btnExportToSVG = new javax.swing.JButton();
btnTestSuiteForm = new javax.swing.JButton();
btnExit = new javax.swing.JButton();
panelStatistics = new JPanel();
panelStatCaptions = new javax.swing.JPanel();
lblL2Norm = new javax.swing.JLabel();
lblErrorFromExpectedArea = new javax.swing.JLabel();
lblExpectedArea = new javax.swing.JLabel();
lblActualArea = new javax.swing.JLabel();
lblExpectedPerimeter = new javax.swing.JLabel();
lblActualPerimeter = new javax.swing.JLabel();
panelStatLabels = new javax.swing.JPanel();
txtL2Norm = new javax.swing.JLabel();
txtErrorFromExpectedArea = new javax.swing.JLabel();
txtExpectedArea = new javax.swing.JLabel();
txtActualArea = new javax.swing.JLabel();
txtExpectedPerimeter = new javax.swing.JLabel();
txtActualPerimeter = new javax.swing.JLabel();
panelPoints = new JPanel();
panelPointsInner = new javax.swing.JPanel();
panelGenerate = new javax.swing.JPanel();
panelGenerationSelection = new javax.swing.JPanel();
txtLetter = new javax.swing.JTextField();
cboCountries = new javax.swing.JComboBox();
btnGenerate = new javax.swing.JButton();
panelGap1 = new javax.swing.JPanel();
panelPointOptions = new javax.swing.JPanel();
panelLeft = new javax.swing.JPanel();
lblGenerationType = new javax.swing.JLabel();
lblFont = new javax.swing.JLabel();
lblShapePoints = new javax.swing.JLabel();
lblInternalPoints = new javax.swing.JLabel();
lblShapePointMinDensity = new javax.swing.JLabel();
lblInternalMinDensity = new javax.swing.JLabel();
panelCenter = new javax.swing.JPanel();
panelGenerationType = new javax.swing.JPanel();
optLetterGeneration = new javax.swing.JRadioButton();
optCountryGeneration = new javax.swing.JRadioButton();
cboFont = new javax.swing.JComboBox();
cboShapePoints = new javax.swing.JComboBox();
cboInternalPoints = new javax.swing.JComboBox();
cboShapePointMinDensity = new javax.swing.JComboBox();
cboInternalMinDensity = new javax.swing.JComboBox();
panelGap = new javax.swing.JPanel();
panelClearPoints = new javax.swing.JPanel();
btnClearPoints = new javax.swing.JButton();
panelCheckBoxes = new javax.swing.JPanel();
chkShowPoints = new javax.swing.JCheckBox();
chkShowExpectedBorder = new javax.swing.JCheckBox();
chkShowIntersection = new javax.swing.JCheckBox();
chkAddShapePointsToSplitLongLines = new javax.swing.JCheckBox();
panelRepresentations = new JPanel();
optNone = new javax.swing.JRadioButton();
optVoronoiCells = new javax.swing.JRadioButton();
optSimpleTriangulation = new javax.swing.JRadioButton();
optEdgeRemoval = new javax.swing.JRadioButton();
optClustering = new javax.swing.JRadioButton();
panelEdgeRemoval = new JPanel();
jPanel4 = new javax.swing.JPanel();
jPanel1 = new javax.swing.JPanel();
optNoLengthRestriction = new javax.swing.JRadioButton();
optUserLengthRestriction = new javax.swing.JRadioButton();
jPanel2 = new javax.swing.JPanel();
panelGapWest = new javax.swing.JPanel();
sliderLengthRestriction = new javax.swing.JSlider();
panelGapSouth = new javax.swing.JPanel();
jPanel3 = new javax.swing.JPanel();
optNormalisedLengthRestriction = new javax.swing.JRadioButton();
panelGapWest2 = new javax.swing.JPanel();
sliderNormalisedLengthRestriction = new javax.swing.JSlider();
panelGapSouth1 = new javax.swing.JPanel();
jPanel7 = new javax.swing.JPanel();
optMaxEdgeOfMinSpanningTree = new javax.swing.JRadioButton();
optMaxEdgeOfSmallestTEdge = new javax.swing.JRadioButton();
optApplyAboveMSTAndSmallestTEdgeInProportion = new javax.swing.JRadioButton();
jPanel5 = new javax.swing.JPanel();
panelGapWest1 = new javax.swing.JPanel();
sliderApplyInProportion = new javax.swing.JSlider();
panelEdgeRemovalOptions = new JPanel();
jPanel8 = new javax.swing.JPanel();
chkShowEdgeLengths = new javax.swing.JCheckBox();
chkShowInternalTriangles = new javax.swing.JCheckBox();
chkShowMinimumSpanningTree = new javax.swing.JCheckBox();
chkShowDebugInfo = new javax.swing.JCheckBox();
chkMaxEdgesToRemove = new javax.swing.JCheckBox();
jPanel9 = new javax.swing.JPanel();
jPanel10 = new javax.swing.JPanel();
sliderMaxEdgesToRemove = new javax.swing.JSlider();
panelOptions = new JPanel();
chkShowMouseLocation = new javax.swing.JCheckBox();
chkShowPointCoordinates = new javax.swing.JCheckBox();
chkShowSweepline = new javax.swing.JCheckBox();
chkShowTreeStructure = new javax.swing.JCheckBox();
chkShowCircleEvents = new javax.swing.JCheckBox();
groupRepresentations.add(optBoundary);
optBoundary.setText("Boundary");
optBoundary.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
optBoundaryActionPerformed(evt);
}
});
groupRepresentations.add(optBoundaryUsingAngle20);
optBoundaryUsingAngle20.setText("Boundary (20\u02da)");
optBoundaryUsingAngle20.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
optBoundaryUsingAngle20ActionPerformed(evt);
}
});
groupRepresentations.add(optBoundaryUsingAngle30);
optBoundaryUsingAngle30.setText("Boundary (30\u02da)");
optBoundaryUsingAngle30.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
optBoundaryUsingAngle30ActionPerformed(evt);
}
});
groupRepresentations.add(optBoundaryEnhanced);
optBoundaryEnhanced.setText("Boundary Enhanced");
optBoundaryEnhanced.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
optBoundaryEnhancedActionPerformed(evt);
}
});
panelBoundaryEnhanced.setLayout(new java.awt.GridLayout(0, 1));
panelBoundaryEnhanced.setBorder(javax.swing.BorderFactory.createTitledBorder("Boundary Enhanced"));
sliderAreaCutOffToUse.setMajorTickSpacing(8000);
sliderAreaCutOffToUse.setMaximum(25000);
sliderAreaCutOffToUse.setPaintLabels(true);
sliderAreaCutOffToUse.setPaintTicks(true);
sliderAreaCutOffToUse.setValue(8000);
sliderAreaCutOffToUse.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
sliderAreaCutOffToUseStateChanged(evt);
}
});
panelBoundaryEnhanced.add(sliderAreaCutOffToUse);
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Non-convex Hull Test Program");
scrollRight.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollRight.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
panelRight.setLayout(new java.awt.BorderLayout());
panelRight.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
panelTop.setLayout(new javax.swing.BoxLayout(panelTop, javax.swing.BoxLayout.Y_AXIS));
panelActions.setLayout(new java.awt.BorderLayout());
panelActions.setBorder(javax.swing.BorderFactory.createTitledBorder("Actions"));
panelActionsInner.setLayout(new java.awt.GridLayout(0, 1, 0, 4));
jPanel6.setLayout(new java.awt.GridLayout(1, 0, 2, 0));
btnSave.setText("Save");
btnSave.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnSaveActionPerformed(evt);
}
});
jPanel6.add(btnSave);
btnExport.setText("Export");
btnExport.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnExportActionPerformed(evt);
}
});
jPanel6.add(btnExport);
btnLoad.setText("Load");
btnLoad.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnLoadActionPerformed(evt);
}
});
jPanel6.add(btnLoad);
panelActionsInner.add(jPanel6);
btnExportToSVG.setText("Export to SVG");
btnExportToSVG.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnExportToSVGActionPerformed(evt);
}
});
panelActionsInner.add(btnExportToSVG);
btnTestSuiteForm.setText("Test Suite Dialog");
btnTestSuiteForm.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnTestSuiteFormActionPerformed(evt);
}
});
//panelActionsInner.add(btnTestSuiteForm);
btnExit.setText("Exit");
btnExit.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnExitActionPerformed(evt);
}
});
panelActionsInner.add(btnExit);
panelActions.add(panelActionsInner, java.awt.BorderLayout.CENTER);
panelStatistics.setLayout(new java.awt.BorderLayout(6, 0));
panelStatistics.setBorder(javax.swing.BorderFactory.createTitledBorder("Statistics"));
panelStatCaptions.setLayout(new java.awt.GridLayout(0, 1, 0, 4));
lblL2Norm.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
lblL2Norm.setText("L2-Norm:");
panelStatCaptions.add(lblL2Norm);
lblErrorFromExpectedArea.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
lblErrorFromExpectedArea.setText("Error From Area:");
panelStatCaptions.add(lblErrorFromExpectedArea);
lblExpectedArea.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
lblExpectedArea.setText("Expected Area:");
panelStatCaptions.add(lblExpectedArea);
lblActualArea.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
lblActualArea.setText("Actual Area:");
panelStatCaptions.add(lblActualArea);
lblExpectedPerimeter.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
lblExpectedPerimeter.setText("Expected Perimeter:");
panelStatCaptions.add(lblExpectedPerimeter);
lblActualPerimeter.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
lblActualPerimeter.setText("Actual Perimeter:");
panelStatCaptions.add(lblActualPerimeter);
panelStatistics.add(panelStatCaptions, java.awt.BorderLayout.WEST);
panelStatLabels.setLayout(new java.awt.GridLayout(0, 1, 0, 4));
txtL2Norm.setText("n/a");
panelStatLabels.add(txtL2Norm);
txtErrorFromExpectedArea.setText("n/a");
panelStatLabels.add(txtErrorFromExpectedArea);
txtExpectedArea.setText("n/a");
panelStatLabels.add(txtExpectedArea);
txtActualArea.setText("n/a");
panelStatLabels.add(txtActualArea);
txtExpectedPerimeter.setText("n/a");
panelStatLabels.add(txtExpectedPerimeter);
txtActualPerimeter.setText("n/a");
panelStatLabels.add(txtActualPerimeter);
panelStatistics.add(panelStatLabels, java.awt.BorderLayout.CENTER);
panelPoints.setLayout(new java.awt.BorderLayout());
panelPoints.setBorder(javax.swing.BorderFactory.createTitledBorder("Points / Shape Generation"));
panelPointsInner.setLayout(new javax.swing.BoxLayout(panelPointsInner, javax.swing.BoxLayout.Y_AXIS));
panelGenerate.setLayout(new java.awt.BorderLayout(3, 0));
panelGenerationSelection.setLayout(new java.awt.GridLayout(0, 1));
txtLetter.setFont(new java.awt.Font("Tahoma", 1, 12));
txtLetter.setHorizontalAlignment(javax.swing.JTextField.CENTER);
txtLetter.setText("S");
txtLetter.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyTyped(java.awt.event.KeyEvent evt) {
txtLetterKeyTyped(evt);
}
});
panelGenerationSelection.add(txtLetter);
cboCountries.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cboCountriesActionPerformed(evt);
}
});
panelGenerationSelection.add(cboCountries);
panelGenerate.add(panelGenerationSelection, java.awt.BorderLayout.CENTER);
btnGenerate.setText("Generate");
btnGenerate.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnGenerateActionPerformed(evt);
}
});
panelGenerate.add(btnGenerate, java.awt.BorderLayout.EAST);
panelPointsInner.add(panelGenerate);
panelGap1.setLayout(null);
panelGap1.setPreferredSize(new java.awt.Dimension(4, 4));
panelPointsInner.add(panelGap1);
panelPointOptions.setLayout(new java.awt.BorderLayout(2, 0));
panelLeft.setLayout(new java.awt.GridLayout(0, 1, 0, 2));
lblGenerationType.setText("Generation Type:");
panelLeft.add(lblGenerationType);
lblFont.setText("Font:");
panelLeft.add(lblFont);
lblShapePoints.setText("Shape Points:");
panelLeft.add(lblShapePoints);
lblInternalPoints.setText("Internal Points:");
panelLeft.add(lblInternalPoints);
lblShapePointMinDensity.setText("Shape Point Min Density:");
panelLeft.add(lblShapePointMinDensity);
lblInternalMinDensity.setText("Internal Min Density:");
panelLeft.add(lblInternalMinDensity);
panelPointOptions.add(panelLeft, java.awt.BorderLayout.WEST);
panelCenter.setLayout(new java.awt.GridLayout(0, 1, 0, 2));
panelGenerationType.setLayout(new java.awt.BorderLayout());
groupGenerationType.add(optLetterGeneration);
optLetterGeneration.setSelected(true);
optLetterGeneration.setText("Letter");
optLetterGeneration.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
optLetterGenerationActionPerformed(evt);
}
});
panelGenerationType.add(optLetterGeneration, java.awt.BorderLayout.WEST);
groupGenerationType.add(optCountryGeneration);
optCountryGeneration.setText("Country");
optCountryGeneration.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
optCountryGenerationActionPerformed(evt);
}
});
panelGenerationType.add(optCountryGeneration, java.awt.BorderLayout.CENTER);
panelCenter.add(panelGenerationType);
cboFont.setEditable(true);
cboFont.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Arial", "Courier New", "Garamond", "Times New Roman", "Lucida Console" }));
cboFont.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cboFontActionPerformed(evt);
}
});
panelCenter.add(cboFont);
cboShapePoints.setEditable(true);
cboShapePoints.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "No Points", "10", "25", "50", "100", "250", "Maximum Possible" }));
cboShapePoints.setSelectedIndex(6);
cboShapePoints.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cboShapePointsActionPerformed(evt);
}
});
panelCenter.add(cboShapePoints);
cboInternalPoints.setEditable(true);
cboInternalPoints.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "No Points", "10", "25", "50", "100", "250", "Maximum Possible" }));
cboInternalPoints.setSelectedIndex(6);
cboInternalPoints.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cboInternalPointsActionPerformed(evt);
}
});
panelCenter.add(cboInternalPoints);
cboShapePointMinDensity.setEditable(true);
cboShapePointMinDensity.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "1", "2", "3", "4", "5", "6", "8", "10", "12", "15", "20", "25", "30", "40", "50", "100", "250" }));
cboShapePointMinDensity.setSelectedIndex(9);
cboShapePointMinDensity.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cboShapePointMinDensityActionPerformed(evt);
}
});
panelCenter.add(cboShapePointMinDensity);
cboInternalMinDensity.setEditable(true);
cboInternalMinDensity.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "1", "2", "3", "4", "5", "6", "8", "10", "12", "15", "20", "25", "30", "40", "50", "100", "250" }));
cboInternalMinDensity.setSelectedIndex(9);
cboInternalMinDensity.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cboInternalMinDensityActionPerformed(evt);
}
});
panelCenter.add(cboInternalMinDensity);
panelPointOptions.add(panelCenter, java.awt.BorderLayout.CENTER);
panelPointsInner.add(panelPointOptions);
panelGap.setLayout(null);
panelGap.setPreferredSize(new java.awt.Dimension(4, 4));
panelPointsInner.add(panelGap);
panelClearPoints.setLayout(new java.awt.BorderLayout());
btnClearPoints.setText("Clear Points");
btnClearPoints.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnClearPointsActionPerformed(evt);
}
});
panelClearPoints.add(btnClearPoints, java.awt.BorderLayout.SOUTH);
panelPointsInner.add(panelClearPoints);
panelCheckBoxes.setLayout(new java.awt.GridLayout(0, 1));
chkShowPoints.setSelected(true);
chkShowPoints.setText("Show Points");
chkShowPoints.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
chkShowPointsActionPerformed(evt);
}
});
panelCheckBoxes.add(chkShowPoints);
chkShowExpectedBorder.setSelected(true);
chkShowExpectedBorder.setText("Show Expected Border");
chkShowExpectedBorder.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
chkShowExpectedBorderActionPerformed(evt);
}
});
panelCheckBoxes.add(chkShowExpectedBorder);
chkShowIntersection.setSelected(true);
chkShowIntersection.setText("Show Intersection (L2 Norm)");
chkShowIntersection.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
chkShowIntersectionActionPerformed(evt);
}
});
panelCheckBoxes.add(chkShowIntersection);
chkAddShapePointsToSplitLongLines.setSelected(true);
chkAddShapePointsToSplitLongLines.setText("Add Shape Points to Split Long Lines");
chkAddShapePointsToSplitLongLines.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
chkAddShapePointsToSplitLongLinesActionPerformed(evt);
}
});
panelCheckBoxes.add(chkAddShapePointsToSplitLongLines);
panelPointsInner.add(panelCheckBoxes);
panelPoints.add(panelPointsInner, java.awt.BorderLayout.CENTER);
panelRepresentations.setLayout(new java.awt.GridLayout(0, 1));
panelRepresentations.setBorder(javax.swing.BorderFactory.createTitledBorder("Representations"));
groupRepresentations.add(optNone);
optNone.setSelected(true);
optNone.setText("None");
optNone.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
optNoneActionPerformed(evt);
}
});
panelRepresentations.add(optNone);
groupRepresentations.add(optVoronoiCells);
optVoronoiCells.setText("Voronoi");
optVoronoiCells.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
optVoronoiCellsActionPerformed(evt);
}
});
panelRepresentations.add(optVoronoiCells);
groupRepresentations.add(optSimpleTriangulation);
optSimpleTriangulation.setText("Triangulation");
optSimpleTriangulation.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
optSimpleTriangulationActionPerformed(evt);
}
});
panelRepresentations.add(optSimpleTriangulation);
groupRepresentations.add(optEdgeRemoval);
optEdgeRemoval.setText("Edge Removal");
optEdgeRemoval.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
optEdgeRemovalActionPerformed(evt);
}
});
panelRepresentations.add(optEdgeRemoval);
groupRepresentations.add(optClustering);
optClustering.setText("Clustering");
optClustering.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
optClusteringActionPerformed(evt);
}
});
panelRepresentations.add(optClustering);
panelEdgeRemoval.setLayout(new java.awt.BorderLayout());
panelEdgeRemoval.setBorder(javax.swing.BorderFactory.createTitledBorder("Edge Removal"));
jPanel4.setLayout(new java.awt.BorderLayout());
jPanel1.setLayout(new javax.swing.BoxLayout(jPanel1, javax.swing.BoxLayout.Y_AXIS));
groupEdgeRemoval.add(optNoLengthRestriction);
//optNoLengthRestriction.setSelected(true);
optNoLengthRestriction.setText("No Length Cut-off");
optNoLengthRestriction.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
optNoLengthRestrictionActionPerformed(evt);
}
});
//jPanel1.add(optNoLengthRestriction);
groupEdgeRemoval.add(optUserLengthRestriction);
optUserLengthRestriction.setText("User Length Cut-off");
optUserLengthRestriction.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
optUserLengthRestrictionActionPerformed(evt);
}
});
//jPanel1.add(optUserLengthRestriction);
jPanel4.add(jPanel1, java.awt.BorderLayout.NORTH);
jPanel2.setLayout(new java.awt.BorderLayout());
panelGapWest.setLayout(null);
panelGapWest.setPreferredSize(new java.awt.Dimension(16, 5));
jPanel2.add(panelGapWest, java.awt.BorderLayout.WEST);
sliderLengthRestriction.setMajorTickSpacing(100);
sliderLengthRestriction.setPaintLabels(true);
sliderLengthRestriction.setPaintTicks(true);
sliderLengthRestriction.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
sliderLengthRestrictionStateChanged(evt);
}
});
//jPanel2.add(sliderLengthRestriction, java.awt.BorderLayout.CENTER);
panelGapSouth.setLayout(null);
panelGapSouth.setPreferredSize(new java.awt.Dimension(2, 2));
jPanel2.add(panelGapSouth, java.awt.BorderLayout.SOUTH);
jPanel4.add(jPanel2, java.awt.BorderLayout.CENTER);
jPanel3.setLayout(new java.awt.BorderLayout());
groupEdgeRemoval.add(optNormalisedLengthRestriction);
optNormalisedLengthRestriction.setText("Normalised Length");
optNormalisedLengthRestriction.setSelected(true);
optNormalisedLengthRestriction.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
optNormalisedLengthRestrictionActionPerformed(evt);
}
});
jPanel3.add(optNormalisedLengthRestriction, java.awt.BorderLayout.NORTH);
panelGapWest2.setLayout(null);
panelGapWest2.setPreferredSize(new java.awt.Dimension(16, 5));
jPanel3.add(panelGapWest2, java.awt.BorderLayout.WEST);
sliderNormalisedLengthRestriction.setMajorTickSpacing(25);
sliderNormalisedLengthRestriction.setMinorTickSpacing(5);
sliderNormalisedLengthRestriction.setPaintLabels(true);
sliderNormalisedLengthRestriction.setPaintTicks(true);
sliderNormalisedLengthRestriction.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
sliderNormalisedLengthRestrictionStateChanged(evt);
}
});
jPanel3.add(sliderNormalisedLengthRestriction, java.awt.BorderLayout.CENTER);
panelGapSouth1.setLayout(null);
panelGapSouth1.setPreferredSize(new java.awt.Dimension(2, 2));
jPanel3.add(panelGapSouth1, java.awt.BorderLayout.SOUTH);
jPanel4.add(jPanel3, java.awt.BorderLayout.SOUTH);
panelEdgeRemoval.add(jPanel4, java.awt.BorderLayout.NORTH);
jPanel7.setLayout(new javax.swing.BoxLayout(jPanel7, javax.swing.BoxLayout.Y_AXIS));
groupEdgeRemoval.add(optMaxEdgeOfMinSpanningTree);
optMaxEdgeOfMinSpanningTree.setText("Max Edge of Minimum Spanning Tree");
optMaxEdgeOfMinSpanningTree.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
optMaxEdgeOfMinSpanningTreeActionPerformed(evt);
}
});
jPanel7.add(optMaxEdgeOfMinSpanningTree);
groupEdgeRemoval.add(optMaxEdgeOfSmallestTEdge);
optMaxEdgeOfSmallestTEdge.setText("Max of Smallest Triangle Edge");
optMaxEdgeOfSmallestTEdge.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
optMaxEdgeOfSmallestTEdgeActionPerformed(evt);
}
});
jPanel7.add(optMaxEdgeOfSmallestTEdge);
//groupEdgeRemoval.add(optApplyAboveMSTAndSmallestTEdgeInProportion);
optApplyAboveMSTAndSmallestTEdgeInProportion.setText("Apply above two in following proportion");
optApplyAboveMSTAndSmallestTEdgeInProportion.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
optApplyAboveMSTAndSmallestTEdgeInProportionActionPerformed(evt);
}
});
//jPanel7.add(optApplyAboveMSTAndSmallestTEdgeInProportion);
panelEdgeRemoval.add(jPanel7, java.awt.BorderLayout.CENTER);
jPanel5.setLayout(new java.awt.BorderLayout());
panelGapWest1.setLayout(null);
panelGapWest1.setPreferredSize(new java.awt.Dimension(16, 5));
jPanel5.add(panelGapWest1, java.awt.BorderLayout.WEST);
sliderApplyInProportion.setMajorTickSpacing(10);
sliderApplyInProportion.setMinorTickSpacing(1);
sliderApplyInProportion.setPaintLabels(true);
sliderApplyInProportion.setPaintTicks(true);
sliderApplyInProportion.setValue(15);
sliderApplyInProportion.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
sliderApplyInProportionStateChanged(evt);
}
});
//jPanel5.add(sliderApplyInProportion, java.awt.BorderLayout.CENTER);
panelEdgeRemoval.add(jPanel5, java.awt.BorderLayout.SOUTH);
panelEdgeRemovalOptions.setLayout(new javax.swing.BoxLayout(panelEdgeRemovalOptions, javax.swing.BoxLayout.Y_AXIS));
panelEdgeRemovalOptions.setBorder(javax.swing.BorderFactory.createTitledBorder("Edge Removal Options"));
jPanel8.setLayout(new java.awt.GridLayout(0, 1));
chkShowEdgeLengths.setText("Show Edge Lengths");
chkShowEdgeLengths.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
chkShowEdgeLengthsActionPerformed(evt);
}
});
jPanel8.add(chkShowEdgeLengths);
chkShowInternalTriangles.setText("Show Internal Triangles");
chkShowInternalTriangles.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
chkShowInternalTrianglesActionPerformed(evt);
}
});
jPanel8.add(chkShowInternalTriangles);
chkShowMinimumSpanningTree.setText("Show Minimum Spanning Tree");
chkShowMinimumSpanningTree.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
chkShowMinimumSpanningTreeActionPerformed(evt);
}
});
jPanel8.add(chkShowMinimumSpanningTree);
chkShowDebugInfo.setText("Show Debug Information");
chkShowDebugInfo.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
chkShowDebugInfoActionPerformed(evt);
}
});
jPanel8.add(chkShowDebugInfo);
chkMaxEdgesToRemove.setText("Max Edges to Remove");
chkMaxEdgesToRemove.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
chkMaxEdgesToRemoveActionPerformed(evt);
}
});
jPanel8.add(chkMaxEdgesToRemove);
panelEdgeRemovalOptions.add(jPanel8);
jPanel9.setLayout(new java.awt.BorderLayout());
jPanel10.setLayout(null);
jPanel10.setPreferredSize(new java.awt.Dimension(16, 5));
jPanel9.add(jPanel10, java.awt.BorderLayout.WEST);
sliderMaxEdgesToRemove.setMajorTickSpacing(100);
sliderMaxEdgesToRemove.setMaximum(500);
sliderMaxEdgesToRemove.setMinorTickSpacing(1);
sliderMaxEdgesToRemove.setPaintLabels(true);
sliderMaxEdgesToRemove.setPaintTicks(true);
sliderMaxEdgesToRemove.setValue(0);
sliderMaxEdgesToRemove.addChangeListener(new javax.swing.event.ChangeListener() {
public void stateChanged(javax.swing.event.ChangeEvent evt) {
sliderMaxEdgesToRemoveStateChanged(evt);
}
});
jPanel9.add(sliderMaxEdgesToRemove, java.awt.BorderLayout.CENTER);
panelEdgeRemovalOptions.add(jPanel9);
panelOptions.setLayout(new java.awt.GridLayout(0, 1));
panelOptions.setBorder(javax.swing.BorderFactory.createTitledBorder("Debug Options"));
chkShowMouseLocation.setText("Show Mouse Location");
chkShowMouseLocation.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
chkShowMouseLocationActionPerformed(evt);
}
});
panelOptions.add(chkShowMouseLocation);
chkShowPointCoordinates.setText("Show Coordinates");
chkShowPointCoordinates.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
chkShowPointCoordinatesActionPerformed(evt);
}
});
panelOptions.add(chkShowPointCoordinates);
chkShowSweepline.setText("Show Sweepline");
chkShowSweepline.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
chkShowSweeplineActionPerformed(evt);
}
});
panelOptions.add(chkShowSweepline);
chkShowTreeStructure.setText("Show Tree Structure");
chkShowTreeStructure.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
chkShowTreeStructureActionPerformed(evt);
}
});
panelOptions.add(chkShowTreeStructure);
chkShowCircleEvents.setText("Show Circle Events");
chkShowCircleEvents.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
chkShowCircleEventsActionPerformed(evt);
}
});
panelOptions.add(chkShowCircleEvents);
//((JCollapsiblePanel)panelStatistics).setCollapsed(true);
//((JCollapsiblePanel)panelPoints).setCollapsed(true);
//((JCollapsiblePanel)panelOptions).setCollapsed(true);
//((JCollapsiblePanel)panelRepresentations).setCollapsed(true);
//((JCollapsiblePanel)panelEdgeRemovalOptions).setCollapsed(true);
//((JCollapsiblePanel)panelActions).setCollapsed(true);
panelTop.add(panelEdgeRemoval);
panelTop.add(panelStatistics);
panelTop.add(panelPoints);
panelTop.add(panelOptions);
panelTop.add(panelRepresentations);
panelTop.add(panelEdgeRemovalOptions);
//panelTop.add(panelActions);
panelRight.add(panelTop, java.awt.BorderLayout.NORTH);
scrollRight.setViewportView(panelRight);
getContentPane().add(scrollRight, java.awt.BorderLayout.EAST);
}// //GEN-END:initComponents
private void chkShowMouseLocationActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkShowMouseLocationActionPerformed
SHOW_MOUSE_LOCATION = chkShowMouseLocation.isSelected();
this.repaint();
}//GEN-LAST:event_chkShowMouseLocationActionPerformed
private void chkShowPointsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkShowPointsActionPerformed
SHOW_POINTS = chkShowPoints.isSelected();
this.repaint();
}//GEN-LAST:event_chkShowPointsActionPerformed
private void optNormalisedLengthRestrictionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_optNormalisedLengthRestrictionActionPerformed
updateControls();
}//GEN-LAST:event_optNormalisedLengthRestrictionActionPerformed
private void sliderNormalisedLengthRestrictionStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sliderNormalisedLengthRestrictionStateChanged
// No need to updateControls() - just repaint
this.repaint();
}//GEN-LAST:event_sliderNormalisedLengthRestrictionStateChanged
private void btnExportToSVGActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnExportToSVGActionPerformed
}//GEN-LAST:event_btnExportToSVGActionPerformed
private void cboInternalMinDensityActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cboInternalMinDensityActionPerformed
btnGenerate.doClick();
}//GEN-LAST:event_cboInternalMinDensityActionPerformed
private void cboShapePointsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cboShapePointsActionPerformed
btnGenerate.doClick();
}//GEN-LAST:event_cboShapePointsActionPerformed
private void btnExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnExitActionPerformed
System.exit(0);
}//GEN-LAST:event_btnExitActionPerformed
private void chkShowIntersectionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkShowIntersectionActionPerformed
SHOW_INTERSECTION_WITH_EXPECTED = chkShowIntersection.isSelected();
this.repaint();
}//GEN-LAST:event_chkShowIntersectionActionPerformed
private void chkAddShapePointsToSplitLongLinesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkAddShapePointsToSplitLongLinesActionPerformed
btnGenerate.doClick();
}//GEN-LAST:event_chkAddShapePointsToSplitLongLinesActionPerformed
private void cboCountriesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cboCountriesActionPerformed
btnGenerate.doClick();
}//GEN-LAST:event_cboCountriesActionPerformed
private void optCountryGenerationActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_optCountryGenerationActionPerformed
// By default, don't split long lines for countries
chkAddShapePointsToSplitLongLines.setSelected(false);
// Setup panel combo box
panelGenerationSelection.removeAll();
panelGenerationSelection.add( cboCountries );
panelGenerationSelection.validate();
panelGenerationSelection.repaint();
}//GEN-LAST:event_optCountryGenerationActionPerformed
private void optLetterGenerationActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_optLetterGenerationActionPerformed
// By default, split long lines for letters
chkAddShapePointsToSplitLongLines.setSelected(true);
// Setup letter text field
panelGenerationSelection.removeAll();
panelGenerationSelection.add( txtLetter );
panelGenerationSelection.validate();
panelGenerationSelection.repaint();
}//GEN-LAST:event_optLetterGenerationActionPerformed
private void btnLoadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLoadActionPerformed
JFileChooser fileChooser = new JFileChooser();
fileChooser.setDialogType(JFileChooser.OPEN_DIALOG);
fileChooser.setDialogTitle("Choose Points File to Load");
String directory = ( lastdirectoryopened!=null ? lastdirectoryopened : fileChooser.getCurrentDirectory().getAbsolutePath() );
fileChooser.setSelectedFile( new File( directory + File.separator + "pointsfile.txt" ) );
int returnval = fileChooser.showOpenDialog(this);
if( returnval==JFileChooser.APPROVE_OPTION ) {
File file = fileChooser.getSelectedFile();
// Set last directory
lastdirectoryopened = file.getPath();
// Load the points file
boolean loadsuccessful;
try {
loadPoints(file.getAbsolutePath());
loadsuccessful = true;
} catch ( IOException e ) {
displayError(e);
loadsuccessful = false;
}
// Refresh the screen
panel.repaint();
// Save the points file back to our default save file
if ( loadsuccessful ) {
try {
savePoints();
} catch ( IOException e ) {
displayError(e);
}
}
}
}//GEN-LAST:event_btnLoadActionPerformed
private void btnSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveActionPerformed
JFileChooser fileChooser = new JFileChooser();
fileChooser.setDialogType(JFileChooser.SAVE_DIALOG);
fileChooser.setDialogTitle("Choose location to Save Points File");
String directory = ( lastdirectoryopened!=null ? lastdirectoryopened : fileChooser.getCurrentDirectory().getAbsolutePath() );
fileChooser.setSelectedFile( new File( directory + File.separator + "pointsfile.txt" ) );
int returnval = fileChooser.showSaveDialog(this);
if( returnval==JFileChooser.APPROVE_OPTION ) {
File file = fileChooser.getSelectedFile();
// Set last directory
lastdirectoryopened = file.getPath();
// Write the file
try {
savePoints(file.getAbsolutePath());
} catch ( IOException e ) {
displayError(e);
}
}
}//GEN-LAST:event_btnSaveActionPerformed
private void btnExportActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveActionPerformed
JFileChooser fileChooser = new JFileChooser();
fileChooser.setDialogType(JFileChooser.SAVE_DIALOG);
fileChooser.setDialogTitle("Choose location to Save Points File");
String directory = ( lastdirectoryopened!=null ? lastdirectoryopened : fileChooser.getCurrentDirectory().getAbsolutePath() );
fileChooser.setSelectedFile( new File( directory + File.separator + "pointsfile.txt" ) );
int returnval = fileChooser.showSaveDialog(this);
if( returnval==JFileChooser.APPROVE_OPTION ) {
File file = fileChooser.getSelectedFile();
// Set last directory
lastdirectoryopened = file.getPath();
// Write the file
try {
exportPoints(file.getAbsolutePath());
} catch ( IOException e ) {
displayError(e);
}
}
}//GEN-LAST:event_btnSaveActionPerformed
private void cboFontActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cboFontActionPerformed
if ( optLetterGeneration.isSelected() ) {
btnGenerate.doClick();
}
}//GEN-LAST:event_cboFontActionPerformed
private void chkShowExpectedBorderActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkShowExpectedBorderActionPerformed
SHOW_EXPECTED_BORDER = chkShowExpectedBorder.isSelected();
this.repaint();
}//GEN-LAST:event_chkShowExpectedBorderActionPerformed
private void cboShapePointMinDensityActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cboShapePointMinDensityActionPerformed
btnGenerate.doClick();
}//GEN-LAST:event_cboShapePointMinDensityActionPerformed
private void cboInternalPointsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cboInternalPointsActionPerformed
btnGenerate.doClick();
}//GEN-LAST:event_cboInternalPointsActionPerformed
private void btnGenerateActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnGenerateActionPerformed
StatusDialog.start(this,"Generating Shape", "Please wait while shape is generated", new Thread() {
public void run() {
// Print text layout
Rectangle shapebounds = new Rectangle(SHAPEMARGIN_LEFTRIGHT, SHAPEMARGIN_TOPBOTTOM, (int)panel.getWidth()-2*SHAPEMARGIN_LEFTRIGHT, (int)panel.getHeight()-2*SHAPEMARGIN_TOPBOTTOM);
// Get Point
Font font = new Font((String)cboFont.getSelectedItem(),Font.BOLD,200);
// Get Shape Point Varibles
int shapepoint_mindensity = Integer.parseInt((String)cboShapePointMinDensity.getSelectedItem());
int shapepoints;
String strshapepoints = ((String)cboShapePoints.getSelectedItem()).toLowerCase();
if ( strshapepoints.startsWith("n") ) {
shapepoints = 0;
} else if ( strshapepoints.startsWith("m") ) {
shapepoints = Integer.MAX_VALUE;
} else {
try {
shapepoints = Integer.parseInt(strshapepoints);
} catch ( NumberFormatException e ) {
displayError("Unrecognised number of points required - \"" + strshapepoints + "\"");
return;
}
}
// Get Internal Point Varibles
int internal_mindensity = Integer.parseInt((String)cboInternalMinDensity.getSelectedItem());
int internalpoints;
String strinternalpoints = ((String)cboInternalPoints.getSelectedItem()).toLowerCase();
if ( strinternalpoints.startsWith("n") ) {
internalpoints = 0;
} else if ( strinternalpoints.startsWith("m") ) {
internalpoints = Integer.MAX_VALUE;
} else {
try {
internalpoints = Integer.parseInt(strinternalpoints);
} catch ( NumberFormatException e ) {
displayError("Unrecognised number of points required - \"" + strinternalpoints + "\"");
return;
}
}
// Remove the set of old points
points = null;
borderpoints = null;
// Create the shape
ArrayList newborderpoints = null;
if ( optLetterGeneration.isSelected() ) {
try {
newborderpoints = ShapeGeneration.createShapeOutline(txtLetter.getText(), shapebounds, font);
} catch ( ShapeGenerationException e ) {
displayError(e);
return;
}
} else if ( optCountryGeneration.isSelected() ) {
// Get the selected country file
String countryfile = countrylistmodel.getSelectedCountry();
// Get the points that form this country
try {
newborderpoints = CountryData.getCountryData(countryfile, shapebounds);
} catch ( IOException e ) {
displayError(e);
return;
}
} else {
displayError("Unknown generation type selected");
return;
}
// Generate random points
ArrayList newpoints = null;
try {
boolean splitlonglines = chkAddShapePointsToSplitLongLines.isSelected();
newpoints = ShapeGeneration.addRandomPoints(newborderpoints, splitlonglines,
shapepoints, shapepoint_mindensity,
internalpoints, internal_mindensity);
} catch ( ShapeGenerationException e ) {
displayError(e);
return;
}
// Calculate the expected area and perimeter
expectedarea = VoronoiShared.calculateAreaOfShape(newborderpoints);
txtExpectedArea.setText( String.format("%.1f",expectedarea) + " pixels^2");
txtExpectedPerimeter.setText( String.format("%.1f",VoronoiShared.calculatePerimeterOfShape(newborderpoints)) + " pixels");
// Convert points to the right form
borderpoints = newborderpoints;
if ( optNone.isSelected() ) {
points = newpoints;
} else if ( optVoronoiCells.isSelected() ) {
points = RepresentationFactory.convertPointsToVoronoiCellPoints(newpoints);
} else if ( optSimpleTriangulation.isSelected() ) {
points = RepresentationFactory.convertPointsToSimpleTriangulationPoints(newpoints);
} else if ( optEdgeRemoval.isSelected() ) {
points = RepresentationFactory.convertPointsToTriangulationPoints(newpoints);
} else if ( optClustering.isSelected() ) {
points = RepresentationFactory.convertPointsToTriangulationPoints(newpoints);
} else {
throw new RuntimeException("Unknown option selected");
}
// Save the points
try {
savePoints();
} catch ( IOException e2 ) {
displayError(e2);
}
// Repaint
repaint();
// Update controls (post repaint)
updateControls();
}
});
// Repaint
this.repaint();
// Update controls (post repaint)
updateControls();
}//GEN-LAST:event_btnGenerateActionPerformed
private void txtLetterKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_txtLetterKeyTyped
txtLetter.setText( Character.toString(evt.getKeyChar()) );
evt.consume();
btnGenerate.doClick();
}//GEN-LAST:event_txtLetterKeyTyped
private void optClusteringActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_optClusteringActionPerformed
enableEdgeRemovePanel( false );
points = RepresentationFactory.convertPointsToTriangulationPoints(points);
representation = RepresentationFactory.createTriangulationRepresentation();
((TriangulationRepresentation)representation).setDetermineClustersMode();
this.repaint();
}//GEN-LAST:event_optClusteringActionPerformed
private void sliderApplyInProportionStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sliderApplyInProportionStateChanged
// No need to updateControls() - just repaint
this.repaint();
}//GEN-LAST:event_sliderApplyInProportionStateChanged
private void optApplyAboveMSTAndSmallestTEdgeInProportionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_optApplyAboveMSTAndSmallestTEdgeInProportionActionPerformed
updateControls();
}//GEN-LAST:event_optApplyAboveMSTAndSmallestTEdgeInProportionActionPerformed
private void chkShowMinimumSpanningTreeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkShowMinimumSpanningTreeActionPerformed
if ( representation==null ) return;
TriangulationRepresentation triangularrep = (TriangulationRepresentation) representation;
if ( chkShowMinimumSpanningTree.isSelected() ) {
triangularrep.setDetermineMinSpanningTreeMode();
} else {
triangularrep.setReduceOuterBoundariesMode();
}
this.repaint();
}//GEN-LAST:event_chkShowMinimumSpanningTreeActionPerformed
private void chkShowDebugInfoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkShowDebugInfoActionPerformed
TriangulationRepresentation.SHOW_DEBUG_INFO = chkShowDebugInfo.isSelected();
this.repaint();
}//GEN-LAST:event_chkShowDebugInfoActionPerformed
private void sliderMaxEdgesToRemoveStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sliderMaxEdgesToRemoveStateChanged
TriangulationRepresentation.MAX_EDGES_TO_REMOVE = sliderMaxEdgesToRemove.getValue();
this.repaint();
}//GEN-LAST:event_sliderMaxEdgesToRemoveStateChanged
private void chkMaxEdgesToRemoveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkMaxEdgesToRemoveActionPerformed
if ( chkMaxEdgesToRemove.isSelected() ) {
sliderMaxEdgesToRemove.setEnabled(true);
TriangulationRepresentation.MAX_EDGES_TO_REMOVE = sliderMaxEdgesToRemove.getValue();
} else {
sliderMaxEdgesToRemove.setEnabled(false);
TriangulationRepresentation.MAX_EDGES_TO_REMOVE = -1;
}
this.repaint();
}//GEN-LAST:event_chkMaxEdgesToRemoveActionPerformed
private void chkShowInternalTrianglesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkShowInternalTrianglesActionPerformed
TriangulationRepresentation.SHOW_INTERNAL_TRIANGLES = chkShowInternalTriangles.isSelected();
this.repaint();
}//GEN-LAST:event_chkShowInternalTrianglesActionPerformed
private void chkShowEdgeLengthsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkShowEdgeLengthsActionPerformed
TriangulationRepresentation.SHOW_EDGE_LENGTHS = chkShowEdgeLengths.isSelected();
this.repaint();
}//GEN-LAST:event_chkShowEdgeLengthsActionPerformed
private void updateControls() {
if ( optEdgeRemoval.isSelected() ) {
TriangulationRepresentation trianglarrep = (TriangulationRepresentation) representation;
// Set slider lengths
if ( trianglarrep.getMinLength()>0 &&trianglarrep.getMaxLength()>0 ) {
sliderLengthRestriction.setMinimum( trianglarrep.getMinLength()-1 );
sliderLengthRestriction.setMaximum( (int)(trianglarrep.getMaxLength()*1.25) );
}
// Enable/disable slider, select new cutoff value
TriangulationRepresentation.CalcCutOff calccutoff;
if ( optNoLengthRestriction.isSelected() ) {
sliderApplyInProportion.setEnabled(false);
sliderLengthRestriction.setEnabled(false);
sliderNormalisedLengthRestriction.setEnabled(false);
calccutoff = new TriangulationRepresentation.CalcCutOff() {
public int calculateCutOff(TriangulationRepresentation rep) {
int val = 0;
updateLengthSlider(rep, val);
updateNormalisedLengthSlider(rep, val);
return val;
}
};
} else if ( optUserLengthRestriction.isSelected() ) {
sliderApplyInProportion.setEnabled(false);
sliderLengthRestriction.setEnabled(true);
sliderNormalisedLengthRestriction.setEnabled(false);
calccutoff = new TriangulationRepresentation.CalcCutOff() {
public int calculateCutOff(TriangulationRepresentation rep) {
// Update sliders
if ( rep.getMinLength()>0 && rep.getMaxLength()>0 ) {
sliderLengthRestriction.setMinimum( rep.getMinLength()-1 );
sliderLengthRestriction.setMaximum( (int)(rep.getMaxLength()*1.25) );
}
// Calculate value
int val = sliderLengthRestriction.getValue();
//updateLengthSlider(rep, val);
updateNormalisedLengthSlider(rep, val);
return val;
}
};
} else if ( optNormalisedLengthRestriction.isSelected() ) {
sliderApplyInProportion.setEnabled(false);
sliderLengthRestriction.setEnabled(false);
sliderNormalisedLengthRestriction.setEnabled(true);
calccutoff = new TriangulationRepresentation.CalcCutOff() {
public int calculateCutOff(TriangulationRepresentation rep) {
// Get variables
double percentage = (double)sliderNormalisedLengthRestriction.getValue() / 100.0;
double min = rep.getMinLength();
double max = rep.getMaxLength();
// Calculate normalised length based off percentage
int val = (int)( percentage * (max-min) + min );
// Return value
updateLengthSlider(rep, val);
//updateNormalisedLengthSlider(rep, val);
return val;
}
};
} else if ( optMaxEdgeOfMinSpanningTree.isSelected() ) {
sliderApplyInProportion.setEnabled(false);
sliderLengthRestriction.setEnabled(false);
sliderNormalisedLengthRestriction.setEnabled(false);
calccutoff = new TriangulationRepresentation.CalcCutOff() {
public int calculateCutOff(TriangulationRepresentation rep) {
int val = rep.getMaxLengthOfMinimumSpanningTree();
updateLengthSlider(rep, val);
updateNormalisedLengthSlider(rep, val);
return val;
}
};
} else if ( optMaxEdgeOfSmallestTEdge.isSelected() ) {
sliderApplyInProportion.setEnabled(false);
sliderLengthRestriction.setEnabled(false);
sliderNormalisedLengthRestriction.setEnabled(false);
calccutoff = new TriangulationRepresentation.CalcCutOff() {
public int calculateCutOff(TriangulationRepresentation rep) {
int val = rep.getMaxLengthOfSmallestTriangleEdge();
updateLengthSlider(rep, val);
updateNormalisedLengthSlider(rep, val);
return val;
}
};
} else if ( optApplyAboveMSTAndSmallestTEdgeInProportion.isSelected() ) {
sliderApplyInProportion.setEnabled(true);
sliderLengthRestriction.setEnabled(false);
sliderNormalisedLengthRestriction.setEnabled(false);
calccutoff = new TriangulationRepresentation.CalcCutOff() {
public int calculateCutOff(TriangulationRepresentation rep) {
double proportion = (double)sliderApplyInProportion.getValue()/100.0;
int val = (int)(
(double)rep.getMaxLengthOfMinimumSpanningTree()*(1-proportion) +
(double)rep.getMaxLengthOfSmallestTriangleEdge()*proportion);
updateLengthSlider(rep, val);
updateNormalisedLengthSlider(rep, val);
return val;
}
};
} else {
displayError("Unknown selection option");
return;
}
// Set the appropriate cutoff calculator
trianglarrep.setCalcCutOff(calccutoff);
// Repaint Panel
this.repaint();
} else {
return;
}
}
private void updateLengthSlider(TriangulationRepresentation rep, int cutoff) {
// Update sliders
int min = rep.getMinLength();
int max = rep.getMaxLength();
if ( min>0 && max>0 ) {
sliderLengthRestriction.setMinimum( min-1 );
sliderLengthRestriction.setMaximum( (int)(max*1.25) );
}
// Set value
sliderLengthRestriction.setValue(cutoff);
}
private void updateNormalisedLengthSlider(TriangulationRepresentation rep, int cutoff) {
// Get variables
int min = rep.getMinLength();
int max = rep.getMaxLength();
if ( min<=0 && max<=0 ) return;
// Set slider position
int percentage = (int)( (double)(cutoff - min) / (double)(max - min) * 100.0);
sliderNormalisedLengthRestriction.setValue( percentage );
}
private void optMaxEdgeOfSmallestTEdgeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_optMaxEdgeOfSmallestTEdgeActionPerformed
updateControls();
}//GEN-LAST:event_optMaxEdgeOfSmallestTEdgeActionPerformed
private void optMaxEdgeOfMinSpanningTreeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_optMaxEdgeOfMinSpanningTreeActionPerformed
updateControls();
}//GEN-LAST:event_optMaxEdgeOfMinSpanningTreeActionPerformed
private void sliderLengthRestrictionStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sliderLengthRestrictionStateChanged
// No need to updateControls() - just repaint
this.repaint();
}//GEN-LAST:event_sliderLengthRestrictionStateChanged
private void optUserLengthRestrictionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_optUserLengthRestrictionActionPerformed
updateControls();
}//GEN-LAST:event_optUserLengthRestrictionActionPerformed
private void optNoLengthRestrictionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_optNoLengthRestrictionActionPerformed
updateControls();
}//GEN-LAST:event_optNoLengthRestrictionActionPerformed
private void optEdgeRemovalActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_optEdgeRemovalActionPerformed
// Set up new points/representation
points = RepresentationFactory.convertPointsToTriangulationPoints(points);
representation = RepresentationFactory.createTriangulationRepresentation();
// Update user selection
enableEdgeRemovePanel( true );
//optNoLengthRestriction.setSelected(true);
//optNoLengthRestrictionActionPerformed(null);
optApplyAboveMSTAndSmallestTEdgeInProportion.setSelected(true);
optApplyAboveMSTAndSmallestTEdgeInProportionActionPerformed(null);
// Repaint panel
this.repaint();
}//GEN-LAST:event_optEdgeRemovalActionPerformed
private void enableEdgeRemovePanel(boolean flag) {
optNoLengthRestriction.setEnabled( flag );
optUserLengthRestriction.setEnabled( flag );
sliderLengthRestriction.setEnabled( flag );
optNormalisedLengthRestriction.setEnabled( flag );
sliderNormalisedLengthRestriction.setEnabled( flag );
sliderApplyInProportion.setEnabled( flag );
optMaxEdgeOfMinSpanningTree.setEnabled( flag );
optMaxEdgeOfSmallestTEdge.setEnabled( flag );
optApplyAboveMSTAndSmallestTEdgeInProportion.setEnabled( flag );
chkShowEdgeLengths.setEnabled( flag );
chkShowInternalTriangles.setEnabled( flag );
chkShowMinimumSpanningTree.setEnabled( flag );
chkShowDebugInfo.setEnabled( flag );
chkMaxEdgesToRemove.setEnabled( flag );
if ( flag && chkMaxEdgesToRemove.isSelected()==false ) {
sliderMaxEdgesToRemove.setEnabled( false );
} else {
sliderMaxEdgesToRemove.setEnabled( flag );
}
}
private void sliderAreaCutOffToUseStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_sliderAreaCutOffToUseStateChanged
if ( BoundaryProblemRepresentation.VORONOICELLAREA_CUTOFF!=sliderAreaCutOffToUse.getValue() ) {
BoundaryProblemRepresentation.VORONOICELLAREA_CUTOFF = sliderAreaCutOffToUse.getValue();
backupboundaryenhancedvalue = sliderAreaCutOffToUse.getValue();
this.repaint();
}
}//GEN-LAST:event_sliderAreaCutOffToUseStateChanged
private void optBoundaryEnhancedActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_optBoundaryEnhancedActionPerformed
enableEdgeRemovePanel( false );
BoundaryProblemRepresentation.MIN_ANGLE_TO_ALLOW = 0.0 / 180.0 * Math.PI;
if ( sliderAreaCutOffToUse.getValue()>0 ) {
BoundaryProblemRepresentation.VORONOICELLAREA_CUTOFF = sliderAreaCutOffToUse.getValue();
backupboundaryenhancedvalue = sliderAreaCutOffToUse.getValue();
} else if ( backupboundaryenhancedvalue>0 ) {
BoundaryProblemRepresentation.VORONOICELLAREA_CUTOFF = backupboundaryenhancedvalue;
sliderAreaCutOffToUse.setValue(backupboundaryenhancedvalue);
} else {
backupboundaryenhancedvalue = 8000;
BoundaryProblemRepresentation.VORONOICELLAREA_CUTOFF = 8000;
sliderAreaCutOffToUse.setValue(8000);
}
points = RepresentationFactory.convertPointsToBoundaryProblemPoints(points);
representation = RepresentationFactory.createBoundaryProblemRepresentation();
this.repaint();
}//GEN-LAST:event_optBoundaryEnhancedActionPerformed
private void optVoronoiCellsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_optVoronoiCellsActionPerformed
enableEdgeRemovePanel( false );
points = RepresentationFactory.convertPointsToVoronoiCellPoints(points);
representation = RepresentationFactory.createVoronoiCellRepresentation();
this.repaint();
}//GEN-LAST:event_optVoronoiCellsActionPerformed
private void optBoundaryUsingAngle30ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_optBoundaryUsingAngle30ActionPerformed
enableEdgeRemovePanel( false );
BoundaryProblemRepresentation.MIN_ANGLE_TO_ALLOW = 30.0 / 180.0 * Math.PI;
BoundaryProblemRepresentation.VORONOICELLAREA_CUTOFF = 0;
sliderAreaCutOffToUse.setValue(0);
points = RepresentationFactory.convertPointsToBoundaryProblemPoints(points);
representation = RepresentationFactory.createBoundaryProblemRepresentation();
this.repaint();
}//GEN-LAST:event_optBoundaryUsingAngle30ActionPerformed
private void optBoundaryUsingAngle20ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_optBoundaryUsingAngle20ActionPerformed
enableEdgeRemovePanel( false );
BoundaryProblemRepresentation.MIN_ANGLE_TO_ALLOW = 20.0 / 180.0 * Math.PI;
BoundaryProblemRepresentation.VORONOICELLAREA_CUTOFF = 0;
sliderAreaCutOffToUse.setValue(0);
points = RepresentationFactory.convertPointsToBoundaryProblemPoints(points);
representation = RepresentationFactory.createBoundaryProblemRepresentation();
this.repaint();
}//GEN-LAST:event_optBoundaryUsingAngle20ActionPerformed
private void optSimpleTriangulationActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_optSimpleTriangulationActionPerformed
enableEdgeRemovePanel( false );
points = RepresentationFactory.convertPointsToSimpleTriangulationPoints(points);
representation = RepresentationFactory.createSimpleTriangulationRepresentation();
this.repaint();
}//GEN-LAST:event_optSimpleTriangulationActionPerformed
private void optBoundaryActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_optBoundaryActionPerformed
enableEdgeRemovePanel( false );
BoundaryProblemRepresentation.MIN_ANGLE_TO_ALLOW = 0.0 / 180.0 * Math.PI;
BoundaryProblemRepresentation.VORONOICELLAREA_CUTOFF = 0;
sliderAreaCutOffToUse.setValue(0);
points = RepresentationFactory.convertPointsToBoundaryProblemPoints(points);
representation = RepresentationFactory.createBoundaryProblemRepresentation();
this.repaint();
}//GEN-LAST:event_optBoundaryActionPerformed
private void optNoneActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_optNoneActionPerformed
enableEdgeRemovePanel( false );
points = RepresentationFactory.convertPointsToVPoints(points);
representation = null;
this.repaint();
}//GEN-LAST:event_optNoneActionPerformed
private void chkShowPointCoordinatesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkShowPointCoordinatesActionPerformed
SHOW_POINT_COORDINATES = chkShowPointCoordinates.isSelected();
this.repaint();
}//GEN-LAST:event_chkShowPointCoordinatesActionPerformed
private void chkShowCircleEventsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkShowCircleEventsActionPerformed
SHOW_CIRCLEEVENTS = chkShowCircleEvents.isSelected();
this.repaint();
}//GEN-LAST:event_chkShowCircleEventsActionPerformed
private void chkShowTreeStructureActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkShowTreeStructureActionPerformed
if ( chkShowTreeStructure.isSelected() ) {
if ( treedialog==null ) {
treedialog = new DebugTree(this);
}
treedialog.setVisible(true);
} else {
if ( treedialog!=null ) {
treedialog.setVisible(false);
treedialog.dispose();
treedialog = null;
}
}
this.repaint();
}//GEN-LAST:event_chkShowTreeStructureActionPerformed
private void chkShowSweeplineActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkShowSweeplineActionPerformed
SHOW_INTERACTIVE_SWEEPLINE = chkShowSweepline.isSelected();
if ( chkShowSweepline.isSelected() ) {
chkShowTreeStructure.setEnabled( true );
} else {
chkShowTreeStructure.setSelected( false );
chkShowTreeStructure.setEnabled( false );
}
this.repaint();
}//GEN-LAST:event_chkShowSweeplineActionPerformed
private void btnClearPointsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnClearPointsActionPerformed
// Clear and save the points
points.clear();
borderpoints = null;
try {
savePoints();
} catch ( IOException e2 ) {
displayError(e2);
}
// Repaint
this.repaint();
}//GEN-LAST:event_btnClearPointsActionPerformed
private void btnTestSuiteFormActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnTestSuiteFormActionPerformed
TestSuite form = new TestSuite(false, this);
form.setVisible(true);
}//GEN-LAST:event_btnTestSuiteFormActionPerformed
private void displayError(String message) {
if(true)return;
JOptionPane.showMessageDialog(this, message, "Error", JOptionPane.ERROR_MESSAGE);
}
static private void displayError(JFrame parent, String message) {
if(true)return;
JOptionPane.showMessageDialog(parent, message, "Error", JOptionPane.ERROR_MESSAGE);
}
private void displayError(Throwable e) {
if(true)return;
e.printStackTrace();
JOptionPane.showMessageDialog(this, e.getMessage(), e.getClass().getName(), JOptionPane.ERROR_MESSAGE);
}
static private void displayError(JFrame parent, Throwable e) {
if(true)return;
e.printStackTrace();
JOptionPane.showMessageDialog(parent, e.getMessage(), e.getClass().getName(), JOptionPane.ERROR_MESSAGE);
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton btnClearPoints;
private javax.swing.JButton btnExit;
private javax.swing.JButton btnExportToSVG;
private javax.swing.JButton btnGenerate;
private javax.swing.JButton btnLoad;
private javax.swing.JButton btnSave;
private javax.swing.JButton btnTestSuiteForm;
private javax.swing.JComboBox cboCountries;
private javax.swing.JComboBox cboFont;
private javax.swing.JComboBox cboInternalMinDensity;
private javax.swing.JComboBox cboInternalPoints;
private javax.swing.JComboBox cboShapePointMinDensity;
private javax.swing.JComboBox cboShapePoints;
private javax.swing.JCheckBox chkAddShapePointsToSplitLongLines;
private javax.swing.JCheckBox chkMaxEdgesToRemove;
private javax.swing.JCheckBox chkShowCircleEvents;
private javax.swing.JCheckBox chkShowDebugInfo;
private javax.swing.JCheckBox chkShowEdgeLengths;
private javax.swing.JCheckBox chkShowExpectedBorder;
private javax.swing.JCheckBox chkShowInternalTriangles;
private javax.swing.JCheckBox chkShowIntersection;
private javax.swing.JCheckBox chkShowMinimumSpanningTree;
private javax.swing.JCheckBox chkShowMouseLocation;
private javax.swing.JCheckBox chkShowPointCoordinates;
private javax.swing.JCheckBox chkShowPoints;
private javax.swing.JCheckBox chkShowSweepline;
private javax.swing.JCheckBox chkShowTreeStructure;
private javax.swing.ButtonGroup groupEdgeRemoval;
private javax.swing.ButtonGroup groupGenerationType;
private javax.swing.ButtonGroup groupRepresentations;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel10;
private javax.swing.JPanel jPanel2;
private javax.swing.JPanel jPanel3;
private javax.swing.JPanel jPanel4;
private javax.swing.JPanel jPanel5;
private javax.swing.JPanel jPanel6;
private javax.swing.JPanel jPanel7;
private javax.swing.JPanel jPanel8;
private javax.swing.JPanel jPanel9;
private javax.swing.JLabel lblActualArea;
private javax.swing.JLabel lblActualPerimeter;
private javax.swing.JLabel lblErrorFromExpectedArea;
private javax.swing.JLabel lblExpectedArea;
private javax.swing.JLabel lblExpectedPerimeter;
private javax.swing.JLabel lblFont;
private javax.swing.JLabel lblGenerationType;
private javax.swing.JLabel lblInternalMinDensity;
private javax.swing.JLabel lblInternalPoints;
private javax.swing.JLabel lblL2Norm;
private javax.swing.JLabel lblShapePointMinDensity;
private javax.swing.JLabel lblShapePoints;
private javax.swing.JRadioButton optApplyAboveMSTAndSmallestTEdgeInProportion;
private javax.swing.JRadioButton optBoundary;
private javax.swing.JRadioButton optBoundaryEnhanced;
private javax.swing.JRadioButton optBoundaryUsingAngle20;
private javax.swing.JRadioButton optBoundaryUsingAngle30;
private javax.swing.JRadioButton optClustering;
private javax.swing.JRadioButton optCountryGeneration;
private javax.swing.JRadioButton optEdgeRemoval;
private javax.swing.JRadioButton optLetterGeneration;
private javax.swing.JRadioButton optMaxEdgeOfMinSpanningTree;
private javax.swing.JRadioButton optMaxEdgeOfSmallestTEdge;
private javax.swing.JRadioButton optNoLengthRestriction;
private javax.swing.JRadioButton optNone;
private javax.swing.JRadioButton optNormalisedLengthRestriction;
private javax.swing.JRadioButton optSimpleTriangulation;
private javax.swing.JRadioButton optUserLengthRestriction;
private javax.swing.JRadioButton optVoronoiCells;
private javax.swing.JPanel panelActions;
private javax.swing.JPanel panelActionsInner;
private javax.swing.JPanel panelBoundaryEnhanced;
private javax.swing.JPanel panelCenter;
private javax.swing.JPanel panelCheckBoxes;
private javax.swing.JPanel panelClearPoints;
private javax.swing.JPanel panelEdgeRemoval;
private javax.swing.JPanel panelEdgeRemovalOptions;
private javax.swing.JPanel panelGap;
private javax.swing.JPanel panelGap1;
private javax.swing.JPanel panelGapSouth;
private javax.swing.JPanel panelGapSouth1;
private javax.swing.JPanel panelGapWest;
private javax.swing.JPanel panelGapWest1;
private javax.swing.JPanel panelGapWest2;
private javax.swing.JPanel panelGenerate;
private javax.swing.JPanel panelGenerationSelection;
private javax.swing.JPanel panelGenerationType;
private javax.swing.JPanel panelLeft;
private javax.swing.JPanel panelOptions;
private javax.swing.JPanel panelPointOptions;
private javax.swing.JPanel panelPoints;
private javax.swing.JPanel panelPointsInner;
private javax.swing.JPanel panelRepresentations;
private javax.swing.JPanel panelRight;
private javax.swing.JPanel panelStatCaptions;
private javax.swing.JPanel panelStatLabels;
private javax.swing.JPanel panelStatistics;
private javax.swing.JPanel panelTop;
private javax.swing.JScrollPane scrollRight;
private javax.swing.JSlider sliderApplyInProportion;
private javax.swing.JSlider sliderAreaCutOffToUse;
private javax.swing.JSlider sliderLengthRestriction;
private javax.swing.JSlider sliderMaxEdgesToRemove;
private javax.swing.JSlider sliderNormalisedLengthRestriction;
private javax.swing.JLabel txtActualArea;
private javax.swing.JLabel txtActualPerimeter;
private javax.swing.JLabel txtErrorFromExpectedArea;
private javax.swing.JLabel txtExpectedArea;
private javax.swing.JLabel txtExpectedPerimeter;
private javax.swing.JLabel txtL2Norm;
private javax.swing.JTextField txtLetter;
// End of variables declaration//GEN-END:variables
public class TestRepresentationWrapper implements RepresentationInterface {
/* ***************************************************** */
// Variables
private final ArrayList circleevents = new ArrayList();
private RepresentationInterface innerrepresentation = null;
/* ***************************************************** */
// Data/Representation Interface Method
// Executed before the algorithm begins to process (can be used to
// initialise any data structures required)
public void beginAlgorithm(Collection points) {
// Reset the triangle array list
circleevents.clear();
// Call the inner representation
if ( innerrepresentation!=null ) {
innerrepresentation.beginAlgorithm(points);
}
}
// Called to record that a vertex has been found
public void siteEvent( VLinkedNode n1 , VLinkedNode n2 , VLinkedNode n3 ) {
// Call the inner representation
if ( innerrepresentation!=null ) {
innerrepresentation.siteEvent(n1, n2, n3);
}
}
public void circleEvent( VLinkedNode n1 , VLinkedNode n2 , VLinkedNode n3 , int circle_x , int circle_y ) {
// Add the circle event
circleevents.add( new VPoint(circle_x, circle_y) );
// Call the inner representation
if ( innerrepresentation!=null ) {
innerrepresentation.circleEvent(n1, n2, n3, circle_x, circle_y);
}
}
// Called when the algorithm has finished processing
public void endAlgorithm(Collection points, int lastsweeplineposition, VLinkedNode headnode) {
// Call the inner representation
if ( innerrepresentation!=null ) {
innerrepresentation.endAlgorithm(points, lastsweeplineposition, headnode);
}
}
/* ***************************************************** */
}
}