[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