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