1  /*
  2   *  File:  MovablePolygon.java
  3   *
  4   *  Custom polygon class for Java 1.1
  5   *
  6   *  Copyright:  Northeast Parallel Architectures Center
  7   *  
  8   */
  9  
 10  import java.awt.Polygon;
 11  import java.awt.Color;
 12  import java.awt.Point;
 13  import java.awt.Graphics;
 14  import java.awt.Component;
 15  
 16  /*
 17   *  MovablePolygon inherits variables xpoints[], ypoints[], 
 18   *  npoints and bounds, and numerous methods from java.awt.Polygon
 19   *  
 20   */
 21  
 22  public class MovablePolygon extends Polygon 
 23                               implements Drawable, Movable {
 24  
 25     /*
 26      *  Constructors
 27      *
 28      */
 29     
 30     // MovablePolygon constructor #1:
 31     public MovablePolygon() {
 32  
 33        // invoke the no-argument constructor of the superclass:
 34        super();
 35  
 36     }
 37  
 38     // MovablePolygon constructor #2 (for compatibility with Polygon):
 39     public MovablePolygon( int[] xpoints, int[] ypoints, int npoints ) {
 40         
 41        // invoke a constructor of the superclass:
 42        super( xpoints, ypoints, npoints );
 43        
 44     }
 45  
 46     // MovablePolygon constructor #3:
 47     public MovablePolygon( Point[] points, int npoints ) {
 48        
 49        // invoke MovablePolygon constructor #1:
 50        this();
 51  
 52        for ( int i = 0; i < npoints; i++ ) {
 53           this.addPoint( points[i] );        // TEST!
 54        }
 55        
 56     }
 57  
 58    
 59     // MovablePolygon constructor #4:
 60     // (a regular n-gon with center (x,y) and radius r)
 61     public MovablePolygon( int x, int y, int r, int n ) {
 62         
 63        // invoke MovablePolygon constructor #1:
 64        this();
 65        
 66        // rotation angle:
 67        double theta = 2 * Math.PI/n;
 68        
 69        // initial point is at twelve o'clock:
 70        MovablePoint p = new MovablePoint( 0, -r );
 71        this.addPoint( p );
 72        for ( int i = 1; i < n; i++ ) {
 73           // rotate the previous point:
 74           p = p.rotate( theta );
 75           this.addPoint( p );
 76        }
 77        this.translate( x, y );
 78        
 79     }
 80  
 81     /*
 82      *  Implement the Drawable interface
 83      *
 84      */
 85     
 86     // instance variable:
 87     private Color color;
 88     
 89     public Color getColor() { return color; }
 90     public void setColor( Color color ) {
 91        this.color = color;
 92     }
 93     
 94     public void draw( Graphics g ) {
 95        if ( this.color != null ) g.setColor( this.color );
 96        g.drawPolygon( this );
 97     }
 98     public void draw( Component c ) {
 99        this.draw( c.getGraphics() );
100     }
101     
102     public void fill( Graphics g ) {
103        if ( this.color != null ) g.setColor( this.color );
104        g.fillPolygon( this );
105     }
106     public void fill( Component c ) {
107        this.fill( c.getGraphics() );
108     }
109     
110     /*
111      *  Implement the Movable interface
112      *
113      */
114     
115     // Displacement in the  x  and  y  directions:
116     private int dx = 1, dy = 1;
117  
118     public void setDelta( int dx, int dy ) {
119        this.dx = dx; this.dy = dy;
120     }
121  
122     public void move() {
123        // the translate method is inherited from Polygon:
124        this.translate( dx, dy );
125     }
126  
127     public void checkBounds( java.awt.Rectangle r ) {
128  
129        java.awt.Rectangle bb = this.getBounds();
130  
131        int w = bb.width, h = bb.height;
132        int nx = bb.x + dx, ny = bb.y + dy;
133  
134        if ( ( nx < r.x ) || ( nx + w > r.x + r.width ) )  dx *= -1;
135        if ( ( ny < r.y ) || ( ny + h > r.y + r.height ) )  dy *= -1;
136  
137     }
138  
139     /*
140      *  Note:  All rotation methods mutate the current polygon!
141      *
142      */
143      
144     // rotate this polygon about the top lefthand corner
145     // of its bounding box:
146     public MovablePolygon rotate( double theta ) {
147     
148        // return the rotated polygon as a side effect:
149        return this.rotate( theta, new Point( this.getBounds().x,
150                                              this.getBounds().y  ) );
151        
152     }
153     
154     // rotate this polygon about the center of its bounding box:
155     public MovablePolygon centerRotate( double theta ) {
156     
157        // compute the center of this polygon:
158        java.awt.Rectangle r = this.getBounds();
159        int x0 = r.x + r.width/2;
160        int y0 = r.y + r.height/2;
161  
162        // return the rotated polygon as a side effect:
163        return this.rotate( theta, new Point( x0, y0 ) );
164        
165     }
166     
167     // rotate this polygon about an arbitrary point:
168     public MovablePolygon rotate( double theta, Point p ) {  // should this by MovablePoint?
169                                                               // things will break!
170        // local variables:
171        int x, y; MovablePoint q;
172  
173        // translate to the origin:
174        this.translate( -p.x, -p.y );
175        
176        // rotate each vertex of this polygon:
177        for ( int i = 0; i < this.npoints; i++ ) {
178           x = this.xpoints[i]; y = this.ypoints[i];
179           q = new MovablePoint( x, y );
180           q.rotate( theta );
181           this.xpoints[i] = q.x;
182           this.ypoints[i] = q.y;
183        }
184        
185        // the bounding box is no longer valid:
186        this.bounds = null;
187        
188        // translate back to original coordinates:
189        this.translate( p.x, p.y );
190  
191        // return the rotated polygon as a side effect:
192        return this;
193        
194     }
195  
196     /*
197      *  Other instance methods
198      *
199      */
200     
201     // overload Polygon.addPoint( int, int ):
202     public void addPoint( Point p ) {  // should this be MovablePoint?
203        super.addPoint( p.x, p.y );     // things will break!
204     }
205     
206     // get all vertices of this polygon:
207     public Point[] getPoints() {
208     
209        Point[] points = new Point[ npoints ];
210        for ( int i = 0; i < npoints; i++ ) {
211           points[i] = new Point( xpoints[i], ypoints[i] );
212        }
213        return points;
214        
215     }
216     
217  }