[kaffe] CVS kaffe (dalibor): Resynced with GNU Classpath: 2D fixes

Kaffe CVS cvs-commits at kaffe.org
Wed Aug 25 15:21:27 PDT 2004


PatchSet 5105 
Date: 2004/08/25 22:17:35
Author: dalibor
Branch: HEAD
Tag: (none) 
Log:
Resynced with GNU Classpath: 2D fixes

2004-08-25  Dalibor Topic  <robilad at kaffe.org>

        * libraries/javalib/java/awt/geom/Arc2D.java,
        libraries/javalib/java/awt/geom/Ellipse2D.java,
        libraries/javalib/java/awt/geom/Line2D.java:
        Resynced with GNU Classpath.

        2004-08-25  Mark Wielaard  <mark at klomp.org>

        * java/awt/geom/Arc2D.java (ArcIterator): Make package private.

        2004-08-25  Sven de Marothy <sven at physto.se>

        * java/awt/geom/Arc2D.java
        Reformatted.
        setArc(): Correct documentation to say 'upper left corner'.
        (setArcByTangent,contains,intersects): Implemented.
        (containsAngle): Corrected to handle negative extents.
        ArcIterator: Set to private.
        ArcIterator: Corrected for CHORD-type arcs, negative extents.
        * java/awt/geom/Ellipse2D.java
        Documented.
        (contains,intersects): Implemented.
        * java/awt/geom/Line2D.java
        (linesIntersect): Correct handling of special cases.

Members: 
	ChangeLog:1.2661->1.2662 
	libraries/javalib/java/awt/geom/Arc2D.java:1.4->1.5 
	libraries/javalib/java/awt/geom/Ellipse2D.java:1.1->1.2 
	libraries/javalib/java/awt/geom/Line2D.java:1.3->1.4 

Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.2661 kaffe/ChangeLog:1.2662
--- kaffe/ChangeLog:1.2661	Wed Aug 25 22:06:00 2004
+++ kaffe/ChangeLog	Wed Aug 25 22:17:35 2004
@@ -1,5 +1,31 @@
 2004-08-25  Dalibor Topic  <robilad at kaffe.org>
 
+	* libraries/javalib/java/awt/geom/Arc2D.java,
+	libraries/javalib/java/awt/geom/Ellipse2D.java,
+	libraries/javalib/java/awt/geom/Line2D.java:
+	Resynced with GNU Classpath.
+
+	2004-08-25  Mark Wielaard  <mark at klomp.org>
+
+        * java/awt/geom/Arc2D.java (ArcIterator): Make package private.
+
+	2004-08-25  Sven de Marothy <sven at physto.se>
+
+        * java/awt/geom/Arc2D.java
+        Reformatted.
+        setArc(): Correct documentation to say 'upper left corner'.
+        (setArcByTangent,contains,intersects): Implemented.
+        (containsAngle): Corrected to handle negative extents.
+        ArcIterator: Set to private.
+        ArcIterator: Corrected for CHORD-type arcs, negative extents.
+        * java/awt/geom/Ellipse2D.java
+        Documented.
+        (contains,intersects): Implemented.
+        * java/awt/geom/Line2D.java
+        (linesIntersect): Correct handling of special cases.
+
+2004-08-25  Dalibor Topic  <robilad at kaffe.org>
+
 	* libraries/javalib/java/awt/Label.java,
 	libraries/javalib/java/awt/Canvas.java,
 	libraries/javalib/java/awt/KeyboardFocusManager.java:
Index: kaffe/libraries/javalib/java/awt/geom/Arc2D.java
diff -u kaffe/libraries/javalib/java/awt/geom/Arc2D.java:1.4 kaffe/libraries/javalib/java/awt/geom/Arc2D.java:1.5
--- kaffe/libraries/javalib/java/awt/geom/Arc2D.java:1.4	Tue May 18 13:39:04 2004
+++ kaffe/libraries/javalib/java/awt/geom/Arc2D.java	Wed Aug 25 22:17:38 2004
@@ -1,5 +1,5 @@
 /* Arc2D.java -- represents an arc in 2-D space
-   Copyright (C) 2002, 2003 Free Software Foundation
+   Copyright (C) 2002, 2003, 2004 Free Software Foundation
 
 This file is part of GNU Classpath.
 
@@ -35,11 +35,11 @@
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
-
 package java.awt.geom;
 
 import java.util.NoSuchElementException;
 
+
 /**
  * This class represents all arcs (segments of an ellipse in 2-D space). The
  * arcs are defined by starting angle and extent (arc length) in degrees, as
@@ -51,8 +51,8 @@
  * first 360 degrees. Storage is up to the subclasses.
  *
  * @author Eric Blake (ebb9 at email.byu.edu)
+ * @author Sven de Marothy (sven at physto.se)
  * @since 1.2
- * @status updated to 1.4, but still missing functionality
  */
 public abstract class Arc2D extends RectangularShape
 {
@@ -154,8 +154,8 @@
    * extent sweeps counterclockwise (from the positive x-axis to the negative
    * y-axis).
    *
-   * @param x the new x coordinate of the lower left of the bounding box
-   * @param y the new y coordinate of the lower left of the bounding box
+   * @param x the new x coordinate of the upper left of the bounding box
+   * @param y the new y coordinate of the upper left of the bounding box
    * @param w the new width of the bounding box
    * @param h the new height of the bounding box
    * @param start the start angle, in degrees
@@ -171,7 +171,7 @@
    * extent sweeps counterclockwise (from the positive x-axis to the negative
    * y-axis).
    *
-   * @param p the lower left point of the bounding box
+   * @param p the upper left point of the bounding box
    * @param d the dimensions of the bounding box
    * @param start the start angle, in degrees
    * @param extent the arc extent, in degrees
@@ -179,11 +179,10 @@
    * @throws IllegalArgumentException if type is invalid
    * @throws NullPointerException if p or d is null
    */
-  public void setArc(Point2D p, Dimension2D d,
-                     double start, double extent, int type)
+  public void setArc(Point2D p, Dimension2D d, double start, double extent,
+                     int type)
   {
-    setArc(p.getX(), p.getY(), d.getWidth(), d.getHeight(),
-           start, extent, type);
+    setArc(p.getX(), p.getY(), d.getWidth(), d.getHeight(), start, extent, type);
   }
 
   /**
@@ -200,8 +199,7 @@
    */
   public void setArc(Rectangle2D r, double start, double extent, int type)
   {
-    setArc(r.getX(), r.getY(), r.getWidth(), r.getHeight(),
-           start, extent, type);
+    setArc(r.getX(), r.getY(), r.getWidth(), r.getHeight(), start, extent, type);
   }
 
   /**
@@ -212,8 +210,8 @@
    */
   public void setArc(Arc2D a)
   {
-    setArc(a.getX(), a.getY(), a.getWidth(), a.getHeight(),
-           a.getAngleStart(), a.getAngleExtent(), a.getArcType());
+    setArc(a.getX(), a.getY(), a.getWidth(), a.getHeight(), a.getAngleStart(),
+           a.getAngleExtent(), a.getArcType());
   }
 
   /**
@@ -230,8 +228,8 @@
    * @param type one of {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
    * @throws IllegalArgumentException if type is invalid
    */
-  public void setArcByCenter(double x, double y, double r,
-                             double start, double extent, int type)
+  public void setArcByCenter(double x, double y, double r, double start,
+                             double extent, int type)
   {
     setArc(x - r, y - r, r + r, r + r, start, extent, type);
   }
@@ -252,8 +250,50 @@
    */
   public void setArcByTangent(Point2D p1, Point2D p2, Point2D p3, double r)
   {
-    // XXX Implement.
-    throw new Error("not implemented");
+    if ((p2.getX() - p1.getX()) * (p3.getY() - p1.getY())
+        - (p3.getX() - p1.getX()) * (p2.getY() - p1.getY()) > 0)
+      {
+	Point2D p = p3;
+	p3 = p1;
+	p1 = p;
+      }
+
+    // normalized tangent vectors
+    double dx1 = (p1.getX() - p2.getX()) / p1.distance(p2);
+    double dy1 = (p1.getY() - p2.getY()) / p1.distance(p2);
+    double dx2 = (p2.getX() - p3.getX()) / p3.distance(p2);
+    double dy2 = (p2.getY() - p3.getY()) / p3.distance(p2);
+    double theta1 = Math.atan2(dx1, dy1);
+    double theta2 = Math.atan2(dx2, dy2);
+
+    double dx = r * Math.cos(theta2) - r * Math.cos(theta1);
+    double dy = -r * Math.sin(theta2) + r * Math.sin(theta1);
+
+    if (theta1 < 0)
+      theta1 += 2 * Math.PI;
+    if (theta2 < 0)
+      theta2 += 2 * Math.PI;
+    if (theta2 < theta1)
+      theta2 += 2 * Math.PI;
+
+    // Vectors of the lines, not normalized, note we change 
+    // the direction of line 2.
+    dx1 = p1.getX() - p2.getX();
+    dy1 = p1.getY() - p2.getY();
+    dx2 = p3.getX() - p2.getX();
+    dy2 = p3.getY() - p2.getY();
+
+    // Calculate the tangent point to the second line
+    double t2 = -(dx1 * dy - dy1 * dx) / (dx2 * dy1 - dx1 * dy2);
+    double x2 = t2 * (p3.getX() - p2.getX()) + p2.getX();
+    double y2 = t2 * (p3.getY() - p2.getY()) + p2.getY();
+
+    // calculate the center point
+    double x = x2 - r * Math.cos(theta2);
+    double y = y2 + r * Math.sin(theta2);
+
+    setArc(x - r, y - r, 2 * r, 2 * r, Math.toDegrees(theta1),
+           Math.toDegrees(theta2 - theta1), getArcType());
   }
 
   /**
@@ -413,8 +453,8 @@
    * @param h the height
    * @return the rectangle for use in getBounds2D
    */
-  protected abstract Rectangle2D makeBounds(double x, double y,
-                                            double w, double h);
+  protected abstract Rectangle2D makeBounds(double x, double y, double w,
+                                            double h);
 
   /**
    * Tests if the given angle, in degrees, is included in the arc.
@@ -426,18 +466,28 @@
   public boolean containsAngle(double a)
   {
     double start = getAngleStart();
-    double end = start + getAngleExtent();
+    double extent = getAngleExtent();
+    double end = start + extent;
+
+    if (extent >= 360 || extent <= -360)
+      return true;
+
+    if (extent < 0)
+      {
+	end = start;
+	start += extent;
+      }
 
     start %= 360;
-    if (start < 0)
+    while (start < 0)
       start += 360;
 
     end %= 360;
-    if (end < 0)
+    while (end < start)
       end += 360;
 
     a %= 360;
-    if (a < 0)
+    while (a < start)
       a += 360;
 
     return a >= start && a <= end;
@@ -447,6 +497,10 @@
    * Determines if the arc contains the given point. If the bounding box
    * is empty, then this will return false.
    *
+   * The area considered 'inside' an arc of type OPEN is the same as the
+   * area inside an equivalent filled PIE-type arc. The area considered
+   * 'inside' a CHORD-type arc is the same as the filled area.
+   *
    * @param x the x coordinate to test
    * @param y the y coordinate to test
    * @return true if the point is inside the arc
@@ -455,15 +509,50 @@
   {
     double w = getWidth();
     double h = getHeight();
-    if (w <= 0 || h <= 0)
+    double extent = getAngleExtent();
+    if (w <= 0 || h <= 0 || extent == 0)
+      return false;
+
+    double mx = getX() + w / 2;
+    double my = getY() + h / 2;
+    double dx = (x - mx) * 2 / w;
+    double dy = (y - my) * 2 / h;
+    if ((dx * dx + dy * dy) >= 1.0)
       return false;
-    // XXX Finish implementing.
-    throw new Error("not implemented");
+
+    double angle = Math.toDegrees(Math.atan2(-dy, dx));
+    if (getArcType() != CHORD)
+      return containsAngle(angle);
+
+    double a1 = Math.toRadians(getAngleStart());
+    double a2 = Math.toRadians(getAngleStart() + extent);
+    double x1 = mx + getWidth() * Math.cos(a1) / 2;
+    double y1 = my - getHeight() * Math.sin(a1) / 2;
+    double x2 = mx + getWidth() * Math.cos(a2) / 2;
+    double y2 = my - getHeight() * Math.sin(a2) / 2;
+    double sgn = ((x2 - x1) * (my - y1) - (mx - x1) * (y2 - y1)) * ((x2 - x1) * (y
+                 - y1) - (x - x1) * (y2 - y1));
+
+    if (Math.abs(extent) > 180)
+      {
+	if (containsAngle(angle))
+	  return true;
+	return sgn > 0;
+      }
+    else
+      {
+	if (! containsAngle(angle))
+	  return false;
+	return sgn < 0;
+      }
   }
 
   /**
    * Tests if a given rectangle intersects the area of the arc.
    *
+   * For a definition of the 'inside' area, see the contains() method.
+   * @see #contains(double, double)
+   *
    * @param x the x coordinate of the rectangle
    * @param y the y coordinate of the rectangle
    * @param w the width of the rectangle
@@ -472,12 +561,51 @@
    */
   public boolean intersects(double x, double y, double w, double h)
   {
-    double mw = getWidth();
-    double mh = getHeight();
-    if (mw <= 0 || mh <= 0 || w <= 0 || h <= 0)
+    double extent = getAngleExtent();
+    if (extent == 0)
       return false;
-    // XXX Finish implementing.
-    throw new Error("not implemented");
+
+    if (contains(x, y) || contains(x, y + h) || contains(x + w, y)
+        || contains(x + w, y + h))
+      return true;
+
+    double mx = getX() + getWidth() / 2;
+    double my = getY() + getHeight() / 2;
+    double x1 = mx
+                + getWidth() * Math.cos(Math.toRadians(getAngleStart())) / 2;
+    double y1 = my
+                - getHeight() * Math.sin(Math.toRadians(getAngleStart())) / 2;
+    double x2 = mx
+                + getWidth() * Math.cos(Math.toRadians(getAngleStart()
+                                                       + extent)) / 2;
+    double y2 = my
+                - getHeight() * Math.sin(Math.toRadians(getAngleStart()
+                                                        + extent)) / 2;
+    if (getArcType() != CHORD)
+      {
+	// check intersections against the pie radii
+	if (Line2D.linesIntersect(mx, my, x1, y1, x, y, x + w, y)
+	    || Line2D.linesIntersect(mx, my, x1, y1, x + w, y, x + w, y + h)
+	    || Line2D.linesIntersect(mx, my, x1, y1, x, y, x, y + h)
+	    || Line2D.linesIntersect(mx, my, x1, y1, x, y + h, x + w, y + h))
+	  return true;
+
+	if (Line2D.linesIntersect(mx, my, x2, y2, x, y, x + w, y)
+	    || Line2D.linesIntersect(mx, my, x2, y2, x + w, y, x + w, y + h)
+	    || Line2D.linesIntersect(mx, my, x2, y2, x, y, x, y + h)
+	    || Line2D.linesIntersect(mx, my, x2, y2, x, y + h, x + w, y + h))
+	  return true;
+      }
+    else if (Line2D.linesIntersect(x1, y1, x2, y2, x, y, x + w, y)
+             || Line2D.linesIntersect(x1, y1, x2, y2, x + w, y, x + w, y + h)
+             || Line2D.linesIntersect(x1, y1, x2, y2, x, y, x, y + h)
+             || Line2D.linesIntersect(x1, y1, x2, y2, x, y + h, x + w, y + h))
+      return true;
+
+    if ((new Rectangle2D.Double(x, y, w, h)).contains(x1, y1))
+      return true;
+
+    return false;
   }
 
   /**
@@ -491,12 +619,47 @@
    */
   public boolean contains(double x, double y, double w, double h)
   {
-    double mw = getWidth();
-    double mh = getHeight();
-    if (mw <= 0 || mh <= 0 || w <= 0 || h <= 0)
+    double extent = getAngleExtent();
+    if (extent == 0)
+      return false;
+
+    if (! (contains(x, y) && contains(x, y + h) && contains(x + w, y)
+        && contains(x + w, y + h)))
+      return false;
+
+    double mx = getX() + getWidth() / 2;
+    double my = getY() + getHeight() / 2;
+    double x1 = mx
+                + getWidth() * Math.cos(Math.toRadians(getAngleStart())) / 2;
+    double y1 = my
+                - getHeight() * Math.sin(Math.toRadians(getAngleStart())) / 2;
+    double x2 = mx
+                + getWidth() * Math.cos(Math.toRadians(getAngleStart()
+                                                       + extent)) / 2;
+    double y2 = my
+                - getHeight() * Math.sin(Math.toRadians(getAngleStart()
+                                                        + extent)) / 2;
+    if (getArcType() != CHORD)
+      {
+	// check intersections against the pie radii
+	if (Line2D.linesIntersect(mx, my, x1, y1, x, y, x + w, y)
+	    || Line2D.linesIntersect(mx, my, x1, y1, x + w, y, x + w, y + h)
+	    || Line2D.linesIntersect(mx, my, x1, y1, x, y, x, y + h)
+	    || Line2D.linesIntersect(mx, my, x1, y1, x, y + h, x + w, y + h))
+	  return false;
+
+	if (Line2D.linesIntersect(mx, my, x2, y2, x, y, x + w, y)
+	    || Line2D.linesIntersect(mx, my, x2, y2, x + w, y, x + w, y + h)
+	    || Line2D.linesIntersect(mx, my, x2, y2, x, y, x, y + h)
+	    || Line2D.linesIntersect(mx, my, x2, y2, x, y + h, x + w, y + h))
+	  return false;
+      }
+    else if (Line2D.linesIntersect(x1, y1, x2, y2, x, y, x + w, y)
+             || Line2D.linesIntersect(x1, y1, x2, y2, x + w, y, x + w, y + h)
+             || Line2D.linesIntersect(x1, y1, x2, y2, x, y, x, y + h)
+             || Line2D.linesIntersect(x1, y1, x2, y2, x, y + h, x + w, y + h))
       return false;
-    // XXX Finish implementing.
-    throw new Error("not implemented");
+    return true;
   }
 
   /**
@@ -567,29 +730,37 @@
      * @param a the arc
      * @param xform the transform
      */
-    ArcIterator(Arc2D a, AffineTransform xform)
+    public ArcIterator(Arc2D a, AffineTransform xform)
     {
       this.xform = xform;
       x = a.getX();
       y = a.getY();
       w = a.getWidth();
       h = a.getHeight();
-      start = a.getAngleStart() * (Math.PI / 180);
-      extent = a.getAngleExtent() * (Math.PI / 180);
+      double start = a.getAngleStart() * (Math.PI / 180);
+      double extent = a.getAngleExtent() * (Math.PI / 180);
+
+      if (extent < 0)
+        {
+	  extent = -extent;
+	  start = 2 * Math.PI - extent + start;
+        }
+      this.start = start;
+      this.extent = extent;
+
       type = a.type;
-      double e = extent < 0 ? -extent : extent;
       if (w < 0 || h < 0)
-        limit = -1;
-      else if (e == 0)
-        limit = type;
-      else if (e <= Math.PI / 2.0)
-        limit = type + 1;
-      else if (e <= Math.PI)
-        limit = type + 2;
-      else if (e <= 3.0 * (Math.PI / 2.0))
-        limit = type + 3;
+	limit = -1;
+      else if (extent == 0)
+	limit = type;
+      else if (extent <= Math.PI / 2.0)
+	limit = type + 1;
+      else if (extent <= Math.PI)
+	limit = type + 2;
+      else if (extent <= 3.0 * (Math.PI / 2.0))
+	limit = type + 3;
       else
-        limit = type + 4;
+	limit = type + 4;
     }
 
     /**
@@ -598,7 +769,7 @@
      * @param e the ellipse
      * @param xform the transform
      */
-    ArcIterator(Ellipse2D e, AffineTransform xform)
+    public ArcIterator(Ellipse2D e, AffineTransform xform)
     {
       this.xform = xform;
       x = e.getX();
@@ -606,7 +777,7 @@
       w = e.getWidth();
       h = e.getHeight();
       start = 0;
-      extent = -2 * Math.PI;
+      extent = 2 * Math.PI;
       type = CHORD;
       limit = (w < 0 || h < 0) ? -1 : 5;
     }
@@ -650,9 +821,9 @@
     public int currentSegment(float[] coords)
     {
       double[] double_coords = new double[6];
-      int code = currentSegment (double_coords);
+      int code = currentSegment(double_coords);
       for (int i = 0; i < 6; ++i)
-        coords[i] = (float) double_coords[i];
+	coords[i] = (float) double_coords[i];
       return code;
     }
 
@@ -666,48 +837,38 @@
      */
     public int currentSegment(double[] coords)
     {
-      double rx = w/2;
-      double ry = h/2;
+      double rx = w / 2;
+      double ry = h / 2;
       double xmid = x + rx;
       double ymid = y + ry;
-     
+
       if (current > limit)
-        throw new NoSuchElementException("arc iterator out of bounds");
+	throw new NoSuchElementException("arc iterator out of bounds");
 
       if (current == 0)
         {
-          coords[0] = xmid + rx * Math.cos(start);
-          coords[1] = ymid - ry * Math.sin(start);
-          if (xform != null)
-            xform.transform(coords, 0, coords, 0, 1);
-          return SEG_MOVETO;
+	  coords[0] = xmid + rx * Math.cos(start);
+	  coords[1] = ymid - ry * Math.sin(start);
+	  if (xform != null)
+	    xform.transform(coords, 0, coords, 0, 1);
+	  return SEG_MOVETO;
         }
 
       if (type != OPEN && current == limit)
-        return SEG_CLOSE;
+	return SEG_CLOSE;
 
-      if ((current == limit - 1) &&
-          (type == PIE) || (type == CHORD))
+      if ((current == limit - 1) && (type == PIE))
         {
-          if (type == PIE)
-            {
-              coords[0] = xmid;
-              coords[1] = ymid;
-            }
-          else if (type == CHORD)
-            {
-              coords[0] = xmid + rx * Math.cos(start);
-              coords[1] = ymid - ry * Math.sin(start);
-            }
-          if (xform != null)
-            xform.transform(coords, 0, coords, 0, 1);
-          return SEG_LINETO;
+	  coords[0] = xmid;
+	  coords[1] = ymid;
+	  if (xform != null)
+	    xform.transform(coords, 0, coords, 0, 1);
+	  return SEG_LINETO;
         }
 
       // note that this produces a cubic approximation of the arc segment,
       // not a true ellipsoid. there's no ellipsoid path segment code,
       // unfortunately. the cubic approximation looks about right, though.
-
       double kappa = (Math.sqrt(2.0) - 1.0) * (4.0 / 3.0);
       double quad = (Math.PI / 2.0);
 
@@ -717,14 +878,14 @@
 
       double x0 = xmid + rx * Math.cos(curr_begin);
       double y0 = ymid - ry * Math.sin(curr_begin);
-      
+
       double x1 = xmid + rx * Math.cos(curr_begin + curr_extent);
       double y1 = ymid - ry * Math.sin(curr_begin + curr_extent);
 
-      AffineTransform trans = new AffineTransform ();
-      double [] cvec = new double[2];
-      double len = kappa * portion_of_a_quadrant; 
-      double angle = curr_begin; 
+      AffineTransform trans = new AffineTransform();
+      double[] cvec = new double[2];
+      double len = kappa * portion_of_a_quadrant;
+      double angle = curr_begin;
 
       // in a hypothetical "first quadrant" setting, our first control
       // vector would be sticking up, from [1,0] to [1,kappa].
@@ -733,31 +894,29 @@
       // from what one would consider "normal" first quadrant rules, so we
       // will *subtract* the y value of this control vector from our first
       // point.
-      
       cvec[0] = 0;
       cvec[1] = len;
-      trans.scale (rx, ry);
-      trans.rotate (angle);
+      trans.scale(rx, ry);
+      trans.rotate(angle);
       trans.transform(cvec, 0, cvec, 0, 1);
       coords[0] = x0 + cvec[0];
       coords[1] = y0 - cvec[1];
 
       // control vector #2 would, ideally, be sticking out and to the
       // right, in a first quadrant arc segment. again, subtraction of y.
-
       cvec[0] = 0;
       cvec[1] = -len;
-      trans.rotate (curr_extent);
+      trans.rotate(curr_extent);
       trans.transform(cvec, 0, cvec, 0, 1);
       coords[2] = x1 + cvec[0];
       coords[3] = y1 - cvec[1];
-      
+
       // end point
       coords[4] = x1;
       coords[5] = y1;
 
       if (xform != null)
-        xform.transform(coords, 0, coords, 0, 3);
+	xform.transform(coords, 0, coords, 0, 3);
 
       return SEG_CUBICTO;
     }
@@ -820,8 +979,8 @@
      * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
      * @throws IllegalArgumentException if type is invalid
      */
-    public Double(double x, double y, double w, double h,
-                  double start, double extent, int type)
+    public Double(double x, double y, double w, double h, double start,
+                  double extent, int type)
     {
       super(type);
       this.x = x;
@@ -831,7 +990,7 @@
       this.start = start;
       this.extent = extent;
     }
-      
+
     /**
      * Create a new arc with the given dimensions.
      *
@@ -935,8 +1094,8 @@
      * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
      * @throws IllegalArgumentException if type is invalid
      */
-    public void setArc(double x, double y, double w, double h,
-                       double start, double extent, int type)
+    public void setArc(double x, double y, double w, double h, double start,
+                       double extent, int type)
     {
       this.x = x;
       this.y = y;
@@ -1039,8 +1198,8 @@
      * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
      * @throws IllegalArgumentException if type is invalid
      */
-    public Float(float x, float y, float w, float h,
-                  float start, float extent, int type)
+    public Float(float x, float y, float w, float h, float start,
+                 float extent, int type)
     {
       super(type);
       this.x = x;
@@ -1050,7 +1209,7 @@
       this.start = start;
       this.extent = extent;
     }
-      
+
     /**
      * Create a new arc with the given dimensions.
      *
@@ -1069,7 +1228,7 @@
       width = (float) r.getWidth();
       height = (float) r.getHeight();
       this.start = start;
-      this.extent = extent;
+      this.extent = (float) extent;
     }
 
     /**
@@ -1154,8 +1313,8 @@
      * @param type the arc type: {@link #OPEN}, {@link #CHORD}, or {@link #PIE}
      * @throws IllegalArgumentException if type is invalid
      */
-    public void setArc(double x, double y, double w, double h,
-                       double start, double extent, int type)
+    public void setArc(double x, double y, double w, double h, double start,
+                       double extent, int type)
     {
       this.x = (float) x;
       this.y = (float) y;
Index: kaffe/libraries/javalib/java/awt/geom/Ellipse2D.java
diff -u kaffe/libraries/javalib/java/awt/geom/Ellipse2D.java:1.1 kaffe/libraries/javalib/java/awt/geom/Ellipse2D.java:1.2
--- kaffe/libraries/javalib/java/awt/geom/Ellipse2D.java:1.1	Wed Nov  6 11:52:24 2002
+++ kaffe/libraries/javalib/java/awt/geom/Ellipse2D.java	Wed Aug 25 22:17:38 2004
@@ -1,5 +1,5 @@
 /* Ellipse2D.java -- represents an ellipse in 2-D space
-   Copyright (C) 2000, 2002 Free Software Foundation
+   Copyright (C) 2000, 2002, 2004 Free Software Foundation
 
 This file is part of GNU Classpath.
 
@@ -37,58 +37,147 @@
 
 package java.awt.geom;
 
+
 /**
+ * Ellipse2D is the shape of an ellipse.
+ * <BR>
+ * <img src="doc-files/Ellipse-1.png" width="347" height="221"
+ * alt="A drawing of an ellipse" /><BR>
+ * The ellipse is defined by it's bounding box (shown in red),
+ * and is defined by the implicit curve:<BR>
+ * <blockquote>(<i>x</i>/<i>a</i>)<sup>2</sup> +
+ * (<i>y</i>/<i>b</i>)<sup>2</sup> = 1<BR><BR>
+ *
  * @author Tom Tromey <tromey at cygnus.com>
  * @author Eric Blake <ebb9 at email.byu.edu>
+ *
  * @since 1.2
- * @status still needs documentation
  */
 public abstract class Ellipse2D extends RectangularShape
 {
+  /**
+   * Ellipse2D is defined as abstract.
+   * Implementing classes are Ellipse2D.Float and Ellipse2D.Double.
+   */
   protected Ellipse2D()
   {
   }
 
+  /**
+   * Determines if a point is contained within the ellipse. <P>
+   * @param x - x coordinate of the point.
+   * @param y - y coordinate of the point.
+   * @return true if the point is within the ellipse, false otherwise.
+   */
   public boolean contains(double x, double y)
   {
     double rx = getWidth() / 2;
     double ry = getHeight() / 2;
-    double tx = (x - getCenterX()) / rx;
-    double ty = (y - getCenterY()) / ry;
-    return tx * tx + ty * ty <= 1.0;
+    double tx = (x - (getX() + rx)) / rx;
+    double ty = (y - (getY() + ry)) / ry;
+    return tx * tx + ty * ty < 1.0;
   }
 
+  /**
+   * Determines if a rectangle is completely contained within the
+   * ellipse. <P>
+   * @param x - x coordinate of the upper-left corner of the rectangle
+   * @param y - y coordinate of the upper-left corner of the rectangle
+   * @param w - width of the rectangle
+   * @param h - height of the rectangle
+   * @return true if the rectangle is completely contained, false otherwise.
+   */
   public boolean contains(double x, double y, double w, double h)
   {
     double x2 = x + w;
     double y2 = y + h;
-    return (contains(x, y) && contains(x, y2)
-            && contains(x2, y) && contains(x2, y2));
+    return (contains(x, y) && contains(x, y2) && contains(x2, y)
+           && contains(x2, y2));
   }
 
+  /**
+   * Returns a PathIterator object corresponding to the ellipse.<P>
+   *
+   * Note: An ellipse cannot be represented exactly in PathIterator
+   * segments, the outline is thefore approximated with cubic
+   * Bezier segments.
+   */
   public PathIterator getPathIterator(AffineTransform at)
   {
     // An ellipse is just a complete arc.
     return new Arc2D.ArcIterator(this, at);
   }
 
+  /**
+   * Determines if a rectangle intersects any part of the ellipse.<P>
+   * @param x - x coordinate of the upper-left corner of the rectangle
+   * @param y - y coordinate of the upper-left corner of the rectangle
+   * @param w - width of the rectangle
+   * @param h - height of the rectangle
+   * @return true if the rectangle intersects the ellipse, false otherwise.
+   */
   public boolean intersects(double x, double y, double w, double h)
   {
-    // fixme
+    Rectangle2D r = new Rectangle2D.Double(x, y, w, h);
+    if (! r.intersects(getX(), getY(), getWidth(), getHeight()))
+      return false;
+
+    if (contains(x, y) || contains(x, y + h) || contains(x + w, y)
+        || contains(x + w, y + h))
+      return true;
+
+    Line2D l1 = new Line2D.Double(getX(), getY() + (getHeight() / 2),
+                                  getX() + getWidth(),
+                                  getY() + (getHeight() / 2));
+    Line2D l2 = new Line2D.Double(getX() + (getWidth() / 2), getY(),
+                                  getX() + (getWidth() / 2),
+                                  getY() + getHeight());
+
+    if (l1.intersects(r) || l2.intersects(r))
+      return true;
+
     return false;
   }
 
   public static class Double extends Ellipse2D
   {
+    /**
+     * The height of the ellipse.
+     */
     public double height;
+
+    /**
+     * The width of the ellipse.
+     */
     public double width;
+
+    /**
+     * The upper-left x coordinate of the bounding-box
+     */
     public double x;
+
+    /**
+     * The upper-left y coordinate of the bounding-box
+     */
     public double y;
 
+    /**
+     * Creates a new Ellipse2D with an upper-right coordinate of (0,0)
+     * and a zero size.
+     */
     public Double()
     {
     }
 
+    /**
+     * Creates a new Ellipse2D within a given rectangle
+     * using double-precision coordinates.<P>
+     * @param x - x coordinate of the upper-right of the bounding rectangle
+     * @param y - y coordinate of the upper-right of the bounding rectangle
+     * @param w - width of the ellipse
+     * @param h - height of the ellipse
+     *
+     */
     public Double(double x, double y, double w, double h)
     {
       this.x = x;
@@ -97,36 +186,64 @@
       width = w;
     }
 
+    /**
+     * Returns the bounding-box of the ellipse.
+     */
     public Rectangle2D getBounds2D()
     {
       return new Rectangle2D.Double(x, y, width, height);
     }
 
+    /**
+     * Returns the height of the ellipse.
+     */
     public double getHeight()
     {
       return height;
     }
 
+    /**
+     * Returns the width of the ellipse.
+     */
     public double getWidth()
     {
       return width;
     }
 
+    /**
+     * Returns x coordinate of the upper-left corner of
+     * the ellipse's bounding-box.
+     */
     public double getX()
     {
       return x;
     }
 
+    /**
+     * Returns y coordinate of the upper-left corner of
+     * the ellipse's bounding-box.
+     */
     public double getY()
     {
       return y;
     }
 
+    /**
+     * Returns true if the ellipse encloses any area.
+     */
     public boolean isEmpty()
     {
       return height <= 0 || width <= 0;
     }
 
+    /**
+     * Sets the geometry of the ellipse's bounding box.<P>
+     *
+     * @param x - x coordinate of the upper-right of the bounding rectangle
+     * @param y - y coordinate of the upper-right of the bounding rectangle
+     * @param w - width of the ellipse
+     * @param h - height of the ellipse
+     */
     public void setFrame(double x, double y, double w, double h)
     {
       this.x = x;
@@ -138,15 +255,43 @@
 
   public static class Float extends Ellipse2D
   {
+    /**
+     * The height of the ellipse.
+     */
     public float height;
+
+    /**
+     * The width of the ellipse.
+     */
     public float width;
+
+    /**
+     * The upper-left x coordinate of the bounding-box
+     */
     public float x;
+
+    /**
+     * The upper-left y coordinate of the bounding-box
+     */
     public float y;
 
+    /**
+     * Creates a new Ellipse2D with an upper-right coordinate of (0,0)
+     * and a zero size.
+     */
     public Float()
     {
     }
 
+    /**
+     * Creates a new Ellipse2D within a given rectangle
+     * using floating-point precision.<P>
+     * @param x - x coordinate of the upper-right of the bounding rectangle
+     * @param y - y coordinate of the upper-right of the bounding rectangle
+     * @param w - width of the ellipse
+     * @param h - height of the ellipse
+     *
+     */
     public Float(float x, float y, float w, float h)
     {
       this.x = x;
@@ -155,36 +300,64 @@

*** Patch too long, truncated ***




More information about the kaffe mailing list