Source for java.awt.geom.Ellipse2D

   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:    */
  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:    */
  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:    */
  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:    */
 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:    */
 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:      */
 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:      */
 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:      */
 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:      */
 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:      */
 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:      */
 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:      */
 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:      */
 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:      */
 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:      */
 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:      */
 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:      */
 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:      */
 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:      */
 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:      */
 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:      */
 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:      */
 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:      */
 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:      */
 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