001/* Ellipse2D.java -- represents an ellipse in 2-D space 002 Copyright (C) 2000, 2002, 2004 Free Software Foundation 003 004This file is part of GNU Classpath. 005 006GNU Classpath is free software; you can redistribute it and/or modify 007it under the terms of the GNU General Public License as published by 008the Free Software Foundation; either version 2, or (at your option) 009any later version. 010 011GNU Classpath is distributed in the hope that it will be useful, but 012WITHOUT ANY WARRANTY; without even the implied warranty of 013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014General Public License for more details. 015 016You should have received a copy of the GNU General Public License 017along with GNU Classpath; see the file COPYING. If not, write to the 018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 01902110-1301 USA. 020 021Linking this library statically or dynamically with other modules is 022making a combined work based on this library. Thus, the terms and 023conditions of the GNU General Public License cover the whole 024combination. 025 026As a special exception, the copyright holders of this library give you 027permission to link this library with independent modules to produce an 028executable, regardless of the license terms of these independent 029modules, and to copy and distribute the resulting executable under 030terms of your choice, provided that you also meet, for each linked 031independent module, the terms and conditions of the license of that 032module. An independent module is a module which is not derived from 033or based on this library. If you modify this library, you may extend 034this exception to your version of the library, but you are not 035obligated to do so. If you do not wish to do so, delete this 036exception statement from your version. */ 037 038package java.awt.geom; 039 040 041/** 042 * Ellipse2D is the shape of an ellipse. 043 * <BR> 044 * <img src="doc-files/Ellipse-1.png" width="347" height="221" 045 * alt="A drawing of an ellipse" /><BR> 046 * The ellipse is defined by it's bounding box (shown in red), 047 * and is defined by the implicit curve:<BR> 048 * <blockquote>(<i>x</i>/<i>a</i>)<sup>2</sup> + 049 * (<i>y</i>/<i>b</i>)<sup>2</sup> = 1<BR><BR></blockquote> 050 * 051 * @author Tom Tromey (tromey@cygnus.com) 052 * @author Eric Blake (ebb9@email.byu.edu) 053 * 054 * @since 1.2 055 */ 056public abstract class Ellipse2D extends RectangularShape 057{ 058 /** 059 * Ellipse2D is defined as abstract. 060 * Implementing classes are Ellipse2D.Float and Ellipse2D.Double. 061 */ 062 protected Ellipse2D() 063 { 064 } 065 066 /** 067 * Determines if a point is contained within the ellipse. <P> 068 * @param x - x coordinate of the point. 069 * @param y - y coordinate of the point. 070 * @return true if the point is within the ellipse, false otherwise. 071 */ 072 public boolean contains(double x, double y) 073 { 074 double rx = getWidth() / 2; 075 double ry = getHeight() / 2; 076 double tx = (x - (getX() + rx)) / rx; 077 double ty = (y - (getY() + ry)) / ry; 078 return tx * tx + ty * ty < 1.0; 079 } 080 081 /** 082 * Determines if a rectangle is completely contained within the 083 * ellipse. <P> 084 * @param x - x coordinate of the upper-left corner of the rectangle 085 * @param y - y coordinate of the upper-left corner of the rectangle 086 * @param w - width of the rectangle 087 * @param h - height of the rectangle 088 * @return true if the rectangle is completely contained, false otherwise. 089 */ 090 public boolean contains(double x, double y, double w, double h) 091 { 092 double x2 = x + w; 093 double y2 = y + h; 094 return (contains(x, y) && contains(x, y2) && contains(x2, y) 095 && contains(x2, y2)); 096 } 097 098 /** 099 * 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