import java.applet.*; import java.awt.*; import java.lang.Math; // This class defines functionality for canvas // for drawing polygons. public class PolygonCanvas extends Canvas { int num_points; // Current number of points in canvas. Point points[]; // Polygon. Image im; // Image object. Graphics buffer; // Graphics object. Color bg_color; // Current color of the background. boolean closed; static final int PT_TOLERANCE = 5; static final int PT_DIAMETER = 2; // Initialize the canvas. public void initImageBuffer() { im = createImage( size().width, size().height ); buffer = im.getGraphics(); points = new Point[100]; num_points = 0; closed = false; bg_color = Color.lightGray; } public void update( Graphics g ) { // This prevents canvas flickering. paint( g ); } public void renderImageBuffer() { buffer.setColor( bg_color ); buffer.fillRect( 0, 0, size().width, size().height ); Color prev_color = buffer.getColor(); buffer.setColor( Color.black ); if (num_points > 0) { buffer.fillOval( points[0].x - PT_DIAMETER, points[0].y - PT_DIAMETER, 2*PT_DIAMETER, 2*PT_DIAMETER); } for ( int ii = 1; ii < num_points; ii++ ) { buffer.drawLine( points[ii - 1].x, points[ii - 1].y, points[ii].x, points[ii].y ); buffer.fillOval( points[ii].x - PT_DIAMETER, points[ii].y - PT_DIAMETER, 2*PT_DIAMETER, 2*PT_DIAMETER); } if (closed == true && num_points > 2) { buffer.drawLine( points[num_points - 1].x, points[num_points - 1].y, points[0].x, points[0].y ); points = new Point[100]; num_points = 0; closed = false; } if (num_points == 100) { points = new Point[100]; num_points = 0; closed = false; } buffer.setColor( prev_color); repaint(); } public void paint( Graphics g) { // Paint places the image stored in memory // onto the screen as a single maneuver. g.drawImage( im, 0, 0, this ); } public void setBGColor( Color color ) { bg_color = color; } public void addPoint( Point pt) { Point a = pt; if (num_points == 0) { points[num_points] = pt; num_points++; return; } Point b = points[num_points - 1]; if (num_points == 1) { if (pt.x != b.x && pt.y != b.y) { points[num_points] = pt; num_points++; } return; } // Number of points is more than 1. Point c = points[num_points - 2]; if (Collinear( a, b, c )) { return; } //if ( Math.abs( pt.x - points[0].x ) < 5 && //Math.abs( pt.y - points[0].y ) < 5) if ( Math.abs(( pt.x - points[0].x )*( pt.x - points[0].x ) - ( pt.y - points[0].y )*( pt.y - points[0].y ) ) < PT_TOLERANCE*PT_TOLERANCE ) { pt.x = points[0].x; pt.y = points[0].y; for (int ii = 1; ii < num_points - 2; ii++) { Point d = points[ii]; c = points[ii + 1]; if (intersectSegments( a, b, c, d )) { return; } } closed = true; return; } for (int ii = 0; ii < num_points - 2; ii++) { Point d = points[ii]; c = points[ii + 1]; if (intersectSegments( a, b, c, d ) || Collinear( a, c, d )) { return; } } points[num_points] = pt; num_points++; return; } public int Area2( Point a, Point b, Point c ) { return (b.x - a.x)*(c.y - a.y) - (c.x - a.x)*(b.y - a.y); } public boolean LeftOn( Point a, Point b, Point c ) { return Area2( a, b, c ) >= 0; } public boolean RightOn( Point a, Point b, Point c ) { return Area2( a, b, c ) <= 0; } public boolean Collinear( Point a, Point b, Point c ) { return Area2( a, b, c ) == 0; } public boolean intersectSegments( Point a, Point b, Point c, Point d ) { if (((LeftOn( a, b, c ) && RightOn( a, b, d )) || (RightOn( a, b, c ) && LeftOn( a, b, d ))) && ((LeftOn( c, d, a ) && RightOn( c, d, b )) || (RightOn( c, d, a ) && LeftOn( c, d, b )))) { return true; } return false; } }