View Javadoc
1   package org.newdawn.slick.geom;
2   
3   import javax.annotation.Nonnull;
4   
5   /**
6    * An axis oriented used for shape bounds
7    * 
8    * @author Kevin Glass
9    */
10  public class Rectangle extends Shape {
11      /**
12       * 
13       */
14      private static final long serialVersionUID = 1L;
15      /** The width of the box */
16      private float width;
17      /** The height of the box */
18      private float height;
19  
20      /**
21       * Create a new bounding box
22       *
23       * @param x The x position of the box
24       * @param y The y position of the box
25       * @param width The width of the box
26       * @param height The hieght of the box
27       */
28      public Rectangle(float x, float y, float width, float height) {
29          this.x = x;
30          this.y = y;
31          this.width = width;
32          this.height = height;
33          maxX = x+width;
34          maxY = y+height;
35          checkPoints();
36      }
37  
38      /**
39       * Check if this rectangle contains a point
40       *
41       * @param xp The x coordinate of the point to check
42       * @param yp The y coordinate of the point to check
43       * @return True if the point is within the rectangle
44       */
45      public boolean contains(float xp, float yp) {
46          if (xp < getX()) {
47              return false;
48          }
49          if (yp < getY()) {
50              return false;
51          }
52          if (xp >= maxX) {
53              return false;
54          }
55          if (yp >= maxY) {
56              return false;
57          }
58  
59          return true;
60      }
61  
62      /**
63       * Set the bounds of this rectangle based on the given rectangle
64       *
65       * @param other The other rectangle whose bounds should be applied
66       */
67      public void setBounds(@Nonnull Rectangle other) {
68          setBounds(other.getX(), other.getY(), other.getWidth(), other.getHeight());
69      }
70  
71      /**
72       * Set the bounds of this rectangle
73       *
74       * @param x The x coordinate of this rectangle
75       * @param y The y coordinate of this rectangle
76       * @param width The width to set in this rectangle
77       * @param height The height to set in this rectangle
78       */
79      public void setBounds(float x, float y, float width, float height) {
80          setX(x);
81          setY(y);
82          setSize(width, height);
83      }
84  
85      /**
86       * Set the size (widtha and height) of this rectangle
87       *
88       * @param width The width to set in this rectangle
89       * @param height The height to set in this rectangle
90       */
91      void setSize(float width, float height) {
92          setWidth(width);
93          setHeight(height);
94      }
95  
96  
97      /**
98       * Get the width of the box
99       *
100      * @return The width of the box
101      */
102     public float getWidth() {
103         return width;
104     }
105 
106     /**
107      * Get the height of the box
108      *
109      * @return The height of the box
110      */
111     public float getHeight() {
112         return height;
113     }
114 
115     /**
116      * Grow the rectangle at all edges by the given amounts. This will result in the
117      * rectangle getting larger around it's centre.
118      *
119      * @param h The amount to adjust horizontally
120      * @param v The amount to ajust vertically
121      */
122     void grow(float h, float v) {
123         setX(getX() - h);
124         setY(getY() - v);
125         setWidth(getWidth() + (h*2));
126         setHeight(getHeight() + (v*2));
127     }
128 
129     /**
130      * Grow the rectangle based on scaling it's size
131      *
132      * @param h The scale to apply to the horizontal
133      * @param v The scale to appy to the vertical
134      */
135     public void scaleGrow(float h, float v) {
136         grow(getWidth() * (h-1), getHeight() * (v-1));
137     }
138 
139     /**
140      * Set the width of this box
141      *
142      * @param width The new width of this box
143      */
144     void setWidth(float width) {
145         if (width != this.width) {
146             pointsDirty = true;
147             this.width = width;
148             maxX = x+width;
149         }
150     }
151 
152     /**
153      * Set the heightof this box
154      *
155      * @param height The height of this box
156      */
157     void setHeight(float height) {
158         if (height != this.height) {
159             pointsDirty = true;
160             this.height = height;
161             maxY = y+height;
162         }
163     }
164 
165     /**
166      * Check if this box touches another
167      *
168      * @param shape The other shape to check against
169      * @return True if the rectangles touch
170      */
171     public boolean intersects(@Nonnull Shape shape) {
172         if(shape instanceof Rectangle) {
173             Rectangle other = (Rectangle)shape;
174             if ((x > (other.x + other.width)) || ((x + width) < other.x)) {
175                 return false;
176             }
177             if ((y > (other.y + other.height)) || ((y + height) < other.y)) {
178                 return false;
179             }
180             return true;
181         }
182         else if(shape instanceof Circle) {
183             return intersects((Circle)shape);
184         }
185         else {
186             return super.intersects(shape);
187         }
188     }
189 
190     protected void createPoints() {
191         float useWidth = width ;
192         float useHeight = height;
193         points = new float[8];
194         
195         points[0] = x;
196         points[1] = y;
197         
198         points[2] = x + useWidth;
199         points[3] = y;
200         
201         points[4] = x + useWidth;
202         points[5] = y + useHeight;
203         
204         points[6] = x;
205         points[7] = y + useHeight;
206         
207         maxX = points[2];
208         maxY = points[5];
209         minX = points[0];
210         minY = points[1];
211         
212         findCenter();
213         calculateRadius();
214     }
215 
216     /**
217      * Check if a circle touches this rectangle
218      *
219      * @param other The circle to check against
220      * @return True if they touch
221      */
222     private boolean intersects(@Nonnull Circle other) {
223         return other.intersects(this);
224     }
225 
226     /**
227      * @see java.lang.Object#toString()
228      */
229     @Nonnull
230     public String toString() {
231         return "[Rectangle "+width+"x"+height+"]";
232     }
233 
234     /**
235      * Check if a rectangle contains a point (static to use it everywhere)
236      *
237      * @param xp
238      *            The x coordinate of the point to check
239      * @param yp
240      *            The y coordinate of the point to check
241      * @param xr
242      *            The x coordinate of the rectangle
243      * @param yr
244      *            The y coordinate of the rectangle
245      * @param widthr
246      *            The width of the rectangle
247      * @param heightr The height of the rectangle
248      * @return True if the point is within the rectangle
249      */
250     public static boolean contains(float xp, float yp, float xr, float yr,
251             float widthr, float heightr) {
252         return (xp >= xr) && (yp >= yr) && (xp <= xr + widthr)
253                 && (yp <= yr + heightr);
254     }
255 
256     /**
257      * Apply a transformation and return a new shape.  This will not alter the current shape but will 
258      * return the transformed shape.
259      * 
260      * @param transform The transform to be applied
261      * @return The transformed shape.
262      */
263     @Nonnull
264     public Shape transform(@Nonnull Transform transform) {
265         checkPoints();
266         
267         Polygon resultPolygon = new Polygon();
268         
269         float result[] = new float[points.length];
270         transform.transform(points, 0, result, 0, points.length / 2);
271         resultPolygon.points = result;
272         resultPolygon.findCenter();
273         resultPolygon.checkPoints();
274 
275         return resultPolygon;
276     }
277 }