1 /* Ellipse2D.java -- represents an ellipse in 2-D space 2 Copyright (C) 2000, 2002, 2004 Free Software Foundation 3 4 This file is part of GNU Classpath. 5 6 GNU Classpath is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Classpath is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Classpath; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 independent module, the terms and conditions of the license of that 32 module. An independent module is a module which is not derived from 33 or based on this library. If you modify this library, you may extend 34 this exception to your version of the library, but you are not 35 obligated to do so. If you do not wish to do so, delete this 36 exception statement from your version. */ 37 38 package java.awt.geom; 39 40 41 /** 42 * Ellipse2D is the shape of an ellipse. 43 * <BR> 44 * <img src="doc-files/Ellipse-1.png" width="347" height="221" 45 * alt="A drawing of an ellipse" /><BR> 46 * The ellipse is defined by it's bounding box (shown in red), 47 * and is defined by the implicit curve:<BR> 48 * <blockquote>(<i>x</i>/<i>a</i>)<sup>2</sup> + 49 * (<i>y</i>/<i>b</i>)<sup>2</sup> = 1<BR><BR></blockquote> 50 * 51 * @author Tom Tromey (tromey@cygnus.com) 52 * @author Eric Blake (ebb9@email.byu.edu) 53 * 54 * @since 1.2 55 */ 56 public abstract class Ellipse2D extends RectangularShape 57 { 58 /** 59 * Ellipse2D is defined as abstract. 60 * Implementing classes are Ellipse2D.Float and Ellipse2D.Double. 61 */ Ellipse2D()62 protected Ellipse2D() 63 { 64 } 65 66 /** 67 * Determines if a point is contained within the ellipse. <P> 68 * @param x - x coordinate of the point. 69 * @param y - y coordinate of the point. 70 * @return true if the point is within the ellipse, false otherwise. 71 */ contains(double x, double y)72 public boolean contains(double x, double y) 73 { 74 double rx = getWidth() / 2; 75 double ry = getHeight() / 2; 76 double tx = (x - (getX() + rx)) / rx; 77 double ty = (y - (getY() + ry)) / ry; 78 return tx * tx + ty * ty < 1.0; 79 } 80 81 /** 82 * Determines if a rectangle is completely contained within the 83 * ellipse. <P> 84 * @param x - x coordinate of the upper-left corner of the rectangle 85 * @param y - y coordinate of the upper-left corner of the rectangle 86 * @param w - width of the rectangle 87 * @param h - height of the rectangle 88 * @return true if the rectangle is completely contained, false otherwise. 89 */ contains(double x, double y, double w, double h)90 public boolean contains(double x, double y, double w, double h) 91 { 92 double x2 = x + w; 93 double y2 = y + h; 94 return (contains(x, y) && contains(x, y2) && contains(x2, y) 95 && contains(x2, y2)); 96 } 97 98 /** 99 * Returns a PathIterator object corresponding to the ellipse.<P> 100 * 101 * Note: An ellipse cannot be represented exactly in PathIterator 102 * segments, the outline is thefore approximated with cubic 103 * Bezier segments. 104 * 105 * @param at an optional transform. 106 * @return A path iterator. 107 */ getPathIterator(AffineTransform at)108 public PathIterator getPathIterator(AffineTransform at) 109 { 110 // An ellipse is just a complete arc. 111 return new Arc2D.ArcIterator(this, at); 112 } 113 114 /** 115 * Determines if a rectangle intersects any part of the ellipse.<P> 116 * @param x - x coordinate of the upper-left corner of the rectangle 117 * @param y - y coordinate of the upper-left corner of the rectangle 118 * @param w - width of the rectangle 119 * @param h - height of the rectangle 120 * @return true if the rectangle intersects the ellipse, false otherwise. 121 */ intersects(double x, double y, double w, double h)122 public boolean intersects(double x, double y, double w, double h) 123 { 124 Rectangle2D r = new Rectangle2D.Double(x, y, w, h); 125 if (! r.intersects(getX(), getY(), getWidth(), getHeight())) 126 return false; 127 128 if (contains(x, y) || contains(x, y + h) || contains(x + w, y) 129 || contains(x + w, y + h)) 130 return true; 131 132 Line2D l1 = new Line2D.Double(getX(), getY() + (getHeight() / 2), 133 getX() + getWidth(), 134 getY() + (getHeight() / 2)); 135 Line2D l2 = new Line2D.Double(getX() + (getWidth() / 2), getY(), 136 getX() + (getWidth() / 2), 137 getY() + getHeight()); 138 139 if (l1.intersects(r) || l2.intersects(r)) 140 return true; 141 142 return false; 143 } 144 145 /** 146 * An {@link Ellipse2D} that stores its coordinates using <code>double</code> 147 * primitives. 148 */ 149 public static class Double extends Ellipse2D 150 { 151 /** 152 * The height of the ellipse. 153 */ 154 public double height; 155 156 /** 157 * The width of the ellipse. 158 */ 159 public double width; 160 161 /** 162 * The upper-left x coordinate of the bounding-box 163 */ 164 public double x; 165 166 /** 167 * The upper-left y coordinate of the bounding-box 168 */ 169 public double y; 170 171 /** 172 * Creates a new Ellipse2D with an upper-left coordinate of (0,0) 173 * and a zero size. 174 */ Double()175 public Double() 176 { 177 } 178 179 /** 180 * Creates a new Ellipse2D within a given rectangle 181 * using double-precision coordinates.<P> 182 * @param x - x coordinate of the upper-left of the bounding rectangle 183 * @param y - y coordinate of the upper-left of the bounding rectangle 184 * @param w - width of the ellipse 185 * @param h - height of the ellipse 186 */ Double(double x, double y, double w, double h)187 public Double(double x, double y, double w, double h) 188 { 189 this.x = x; 190 this.y = y; 191 height = h; 192 width = w; 193 } 194 195 /** 196 * Returns the bounding-box of the ellipse. 197 * @return The bounding box. 198 */ getBounds2D()199 public Rectangle2D getBounds2D() 200 { 201 return new Rectangle2D.Double(x, y, width, height); 202 } 203 204 /** 205 * Returns the height of the ellipse. 206 * @return The height of the ellipse. 207 */ getHeight()208 public double getHeight() 209 { 210 return height; 211 } 212 213 /** 214 * Returns the width of the ellipse. 215 * @return The width of the ellipse. 216 */ getWidth()217 public double getWidth() 218 { 219 return width; 220 } 221 222 /** 223 * Returns x coordinate of the upper-left corner of 224 * the ellipse's bounding-box. 225 * @return The x coordinate. 226 */ getX()227 public double getX() 228 { 229 return x; 230 } 231 232 /** 233 * Returns y coordinate of the upper-left corner of 234 * the ellipse's bounding-box. 235 * @return The y coordinate. 236 */ getY()237 public double getY() 238 { 239 return y; 240 } 241 242 /** 243 * Returns <code>true</code> if the ellipse encloses no area, and 244 * <code>false</code> otherwise. 245 * 246 * @return A boolean. 247 */ isEmpty()248 public boolean isEmpty() 249 { 250 return height <= 0 || width <= 0; 251 } 252 253 /** 254 * Sets the geometry of the ellipse's bounding box.<P> 255 * 256 * @param x - x coordinate of the upper-left of the bounding rectangle 257 * @param y - y coordinate of the upper-left of the bounding rectangle 258 * @param w - width of the ellipse 259 * @param h - height of the ellipse 260 */ setFrame(double x, double y, double w, double h)261 public void setFrame(double x, double y, double w, double h) 262 { 263 this.x = x; 264 this.y = y; 265 height = h; 266 width = w; 267 } 268 } // class Double 269 270 /** 271 * An {@link Ellipse2D} that stores its coordinates using <code>float</code> 272 * primitives. 273 */ 274 public static class Float extends Ellipse2D 275 { 276 /** 277 * The height of the ellipse. 278 */ 279 public float height; 280 281 /** 282 * The width of the ellipse. 283 */ 284 public float width; 285 286 /** 287 * The upper-left x coordinate of the bounding-box 288 */ 289 public float x; 290 291 /** 292 * The upper-left y coordinate of the bounding-box 293 */ 294 public float y; 295 296 /** 297 * Creates a new Ellipse2D with an upper-left coordinate of (0,0) 298 * and a zero size. 299 */ Float()300 public Float() 301 { 302 } 303 304 /** 305 * Creates a new Ellipse2D within a given rectangle 306 * using floating-point precision.<P> 307 * @param x - x coordinate of the upper-left of the bounding rectangle 308 * @param y - y coordinate of the upper-left of the bounding rectangle 309 * @param w - width of the ellipse 310 * @param h - height of the ellipse 311 * 312 */ Float(float x, float y, float w, float h)313 public Float(float x, float y, float w, float h) 314 { 315 this.x = x; 316 this.y = y; 317 this.height = h; 318 this.width = w; 319 } 320 321 /** 322 * Returns the bounding-box of the ellipse. 323 * @return The bounding box. 324 */ getBounds2D()325 public Rectangle2D getBounds2D() 326 { 327 return new Rectangle2D.Float(x, y, width, height); 328 } 329 330 /** 331 * Returns the height of the ellipse. 332 * @return The height of the ellipse. 333 */ getHeight()334 public double getHeight() 335 { 336 return height; 337 } 338 339 /** 340 * Returns the width of the ellipse. 341 * @return The width of the ellipse. 342 */ getWidth()343 public double getWidth() 344 { 345 return width; 346 } 347 348 /** 349 * Returns x coordinate of the upper-left corner of 350 * the ellipse's bounding-box. 351 * @return The x coordinate. 352 */ getX()353 public double getX() 354 { 355 return x; 356 } 357 358 /** 359 * Returns y coordinate of the upper-left corner of 360 * the ellipse's bounding-box. 361 * @return The y coordinate. 362 */ getY()363 public double getY() 364 { 365 return y; 366 } 367 368 /** 369 * Returns <code>true</code> if the ellipse encloses no area, and 370 * <code>false</code> otherwise. 371 * 372 * @return A boolean. 373 */ isEmpty()374 public boolean isEmpty() 375 { 376 return height <= 0 || width <= 0; 377 } 378 379 /** 380 * Sets the geometry of the ellipse's bounding box.<P> 381 * 382 * @param x - x coordinate of the upper-left of the bounding rectangle 383 * @param y - y coordinate of the upper-left of the bounding rectangle 384 * @param w - width of the ellipse 385 * @param h - height of the ellipse 386 */ setFrame(float x, float y, float w, float h)387 public void setFrame(float x, float y, float w, float h) 388 { 389 this.x = x; 390 this.y = y; 391 height = h; 392 width = w; 393 } 394 395 /** 396 * Sets the geometry of the ellipse's bounding box. 397 * 398 * Note: This leads to a loss of precision.<P> 399 * 400 * @param x - x coordinate of the upper-left of the bounding rectangle 401 * @param y - y coordinate of the upper-left of the bounding rectangle 402 * @param w - width of the ellipse 403 * @param h - height of the ellipse 404 */ setFrame(double x, double y, double w, double h)405 public void setFrame(double x, double y, double w, double h) 406 { 407 this.x = (float) x; 408 this.y = (float) y; 409 height = (float) h; 410 width = (float) w; 411 } 412 } // class Float 413 } // class Ellipse2D 414