View Javadoc
1   package org.newdawn.slick.geom;
2   
3   import javax.annotation.Nonnull;
4   
5   /**
6    * A simple Circle geometry
7    * 
8    * @author Kevin Glass
9    */
10  public strictfp class Circle extends Ellipse {
11      /**
12       * 
13       */
14      private static final long serialVersionUID = 1L;
15      /** The radius of the circle */
16      private float radius;
17  
18      /**
19       * Create a new circle based on its radius
20       *
21       * @param centerPointX The x location of the center of the circle
22       * @param centerPointY The y location of the center of the circle
23       * @param radius The radius of the circle
24       */
25      public Circle(float centerPointX, float centerPointY, float radius) {
26          this(centerPointX, centerPointY, radius, DEFAULT_SEGMENT_COUNT);
27      }
28  
29      /**
30       * Create a new circle based on its radius
31       *
32       * @param centerPointX The x location of the center of the circle
33       * @param centerPointY The y location of the center of the circle
34       * @param radius The radius of the circle
35       * @param segmentCount The number of segments to build the circle out of
36       */
37      private Circle(float centerPointX, float centerPointY, float radius, int segmentCount) {
38          super(centerPointX, centerPointY, radius, radius, segmentCount);
39          this.x = centerPointX - radius;
40          this.y = centerPointY - radius;
41          this.radius = radius;
42          boundingCircleRadius = radius;
43      }
44  
45      /**
46       * Get the x coordinate of the centre of the circle
47       *
48       * @return The x coordinate of the centre of the circle
49       */
50      float getCenterX() {
51          return getX() + radius;
52      }
53  
54      /**
55       * Get the y coordinate of the centre of the circle
56       *
57       * @return The y coordinate of the centre of the circle
58       */
59      float getCenterY() {
60          return getY() + radius;
61      }
62  
63      /**
64       * Set the radius of this circle
65       *
66       * @param radius The radius of this circle
67       */
68      public void setRadius(float radius) {
69          if (radius != this.radius) {
70              pointsDirty = true;
71              this.radius = radius;
72              setRadii(radius, radius);
73          }
74      }
75  
76      /**
77       * Get the radius of the circle
78       *
79       * @return The radius of the circle
80       */
81      float getRadius() {
82          return radius;
83      }
84  
85      /**
86       * Check if this circle touches another
87       *
88       * @param shape The other circle
89       * @return True if they touch
90       */
91      public boolean intersects(@Nonnull Shape shape) {
92          if(shape instanceof Circle) {
93              Circle other = (Circle)shape;
94              float totalRad2 = getRadius() + other.getRadius();
95  
96              if (Math.abs(other.getCenterX() - getCenterX()) > totalRad2) {
97                  return false;
98              }
99              if (Math.abs(other.getCenterY() - getCenterY()) > totalRad2) {
100                 return false;
101             }
102 
103             totalRad2 *= totalRad2;
104 
105             float dx = Math.abs(other.getCenterX() - getCenterX());
106             float dy = Math.abs(other.getCenterY() - getCenterY());
107 
108             return totalRad2 >= ((dx*dx) + (dy*dy));
109         }
110         else if(shape instanceof Rectangle) {
111             return intersects((Rectangle)shape);
112         }
113         else {
114             return super.intersects(shape);
115         }
116     }
117 
118     /**
119      * Check if a point is contained by this circle
120      *
121      * @param x The x coordinate of the point to check
122      * @param y The y coordinate of the point to check
123      * @return True if the point is contained by this circle
124      */
125     public boolean contains(float x, float y) 
126     { 
127         return (x - getCenterX()) * (x - getCenterX()) + (y - getCenterY()) * (y - getCenterY()) < getRadius() * getRadius();
128     }
129     
130     /**
131      * @see org.newdawn.slick.geom.Ellipse#findCenter()
132      */
133     protected void findCenter() {
134         center = new float[2];
135         center[0] = x + radius;
136         center[1] = y + radius;
137     }
138 
139     /**
140      * @see org.newdawn.slick.geom.Ellipse#calculateRadius()
141      */
142     protected void calculateRadius() {
143         boundingCircleRadius = radius;
144     }
145 
146     /**
147      * Check if this circle touches a rectangle
148      *
149      * @param other The rectangle to check against
150      * @return True if they touch
151      */
152     private boolean intersects(Rectangle other) {
153         Rectangle box = other;
154         Circle circle = this;
155 
156         if (box.contains(x+radius,y+radius)) {
157             return true;
158         }
159 
160         float x1 = box.getX();
161         float y1 = box.getY();
162         float x2 = box.getX() + box.getWidth();
163         float y2 = box.getY() + box.getHeight();
164 
165         Line[] lines = new Line[4];
166         lines[0] = new Line(x1,y1,x2,y1);
167         lines[1] = new Line(x2,y1,x2,y2);
168         lines[2] = new Line(x2,y2,x1,y2);
169         lines[3] = new Line(x1,y2,x1,y1);
170 
171         float r2 = circle.getRadius() * circle.getRadius();
172 
173         Vector2f pos = new Vector2f(circle.getCenterX(), circle.getCenterY());
174 
175         for (int i=0;i<4;i++) {
176             float dis = lines[i].distanceSquared(pos);
177             if (dis < r2) {
178                 return true;
179             }
180         }
181 
182         return false;
183     } 
184 }