import java.awt.Point; import java.awt.Polygon; import java.awt.Graphics; import java.lang.Math; // A square that's transformable. Not based on java.awt.Polygon // because it's hopelessly broken. // This doesn't store a square in terms of screen coordinates - // instead it simply stores a scale factor, rotation, and translation. // That keeps the round-off error at bay. // When you need to do something useful with the square, you can call // getPolygon() which will lazily create a regular Java polygon for // drawing, etc. // nelson@media.mit.edu 3/20/97 public class TransformableSquare extends Object implements Cloneable { public double scaleFactor, rotation; public Point center; Polygon poly; // use getPolygon() to access this variable // create a square centered at x, y public TransformableSquare(int x, int y, double size) { center = new Point(x, y); scaleFactor = size; rotation = 0; poly = null; } // return a normal java.awt.Polygon out of this thing. Lazy creation. public Polygon getPolygon() { if (poly == null) { double xpoints[] = new double[5], ypoints[] = new double[5]; int xp[] = new int[5], yp[] = new int[5]; xpoints[0] = -0.5; ypoints[0] = -0.5; xpoints[1] = 0.5; ypoints[1] = -0.5; xpoints[2] = 0.5; ypoints[2] = 0.5; xpoints[3] = -0.5; ypoints[3] = 0.5; xpoints[4] = -0.5; ypoints[4] = -0.5; // rotate, scale, translate int i; double costheta = Math.cos(rotation), sintheta = Math.sin(rotation); double rx, ry; for (i = 0; i < 5; i++) { rx = xpoints[i] * costheta - ypoints[i] * sintheta; ry = xpoints[i] * sintheta + ypoints[i] * costheta; xp[i] = (int)Math.round(rx * scaleFactor + center.x); yp[i] = (int)Math.round(ry * scaleFactor + center.y); } poly = new Polygon(xp, yp, 5); } return poly; } // rotate - radians public void rotate(double theta) { poly = null; rotation += theta; } public void scale(double s) { poly = null; scaleFactor *= s; } // scale by n pixels public void scalePixels(int n) { poly = null; scaleFactor += n; } public void translate(int x, int y) { poly = null; center.x += x; center.y += y; } public boolean inside(int x, int y) { return getPolygon().inside(x, y); } public Object clone() throws CloneNotSupportedException { TransformableSquare s = (TransformableSquare)super.clone(); s.poly = null; return s; } }