From 12be91a78c9f6caadd4024d3af5bc468f9a32130 Mon Sep 17 00:00:00 2001 From: Sascha Brawer Date: Wed, 22 Oct 2003 10:54:19 +0200 Subject: [PATCH] QuadCurve2D.java (subdivide): Added documentation. 2003-10-22 Sascha Brawer * java/awt/geom/QuadCurve2D.java (subdivide): Added documentation. java/awt/geom/doc-files/QuadCurve2D-3.png: New illustration. 2003-10-22 Sascha Brawer * java/awt/geom/QuadCurve2D.java: Reformatted, wrote Javadoc. * java/awt/geom/doc-files: New directory. * java/awt/geom/doc-files/QuadCurve2D-1.png, java/awt/geom/doc-files/QuadCurve2D-2.png: New illustrations. 2003-10-22 Sascha Brawer * java/awt/geom/QuadCurve2D.java (subdivide): Implement. 2003-10-22 Sascha Brawer * java/awt/geom/QuadCurve2D.java (getFlatness, getFlatnessSq): Implement. From-SVN: r72791 --- libjava/ChangeLog | 20 + libjava/java/awt/geom/QuadCurve2D.java | 779 +++++++++++++++--- .../java/awt/geom/doc-files/QuadCurve2D-1.png | Bin 0 -> 6363 bytes .../java/awt/geom/doc-files/QuadCurve2D-2.png | Bin 0 -> 5872 bytes .../java/awt/geom/doc-files/QuadCurve2D-3.png | Bin 0 -> 12334 bytes 5 files changed, 706 insertions(+), 93 deletions(-) create mode 100644 libjava/java/awt/geom/doc-files/QuadCurve2D-1.png create mode 100644 libjava/java/awt/geom/doc-files/QuadCurve2D-2.png create mode 100644 libjava/java/awt/geom/doc-files/QuadCurve2D-3.png diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 7f53a3625640..1d3e7bbb0148 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,23 @@ +2003-10-22 Sascha Brawer + + * java/awt/geom/QuadCurve2D.java (subdivide): Added documentation. + java/awt/geom/doc-files/QuadCurve2D-3.png: New illustration. + +2003-10-22 Sascha Brawer + + * java/awt/geom/QuadCurve2D.java: Reformatted, wrote Javadoc. + * java/awt/geom/doc-files: New directory. + * java/awt/geom/doc-files/QuadCurve2D-1.png, + java/awt/geom/doc-files/QuadCurve2D-2.png: New illustrations. + +2003-10-22 Sascha Brawer + + * java/awt/geom/QuadCurve2D.java (subdivide): Implement. + +2003-10-22 Sascha Brawer + + * java/awt/geom/QuadCurve2D.java (getFlatness, getFlatnessSq): Implement. + 2003-10-22 Michael Koch * java/io/File.java diff --git a/libjava/java/awt/geom/QuadCurve2D.java b/libjava/java/awt/geom/QuadCurve2D.java index 6aed05907562..e737ec1a4706 100644 --- a/libjava/java/awt/geom/QuadCurve2D.java +++ b/libjava/java/awt/geom/QuadCurve2D.java @@ -1,5 +1,5 @@ /* QuadCurve2D.java -- represents a parameterized quadratic curve in 2-D space - Copyright (C) 2002 Free Software Foundation + Copyright (C) 2002, 2003 Free Software Foundation This file is part of GNU Classpath. @@ -42,124 +42,361 @@ import java.awt.Rectangle; import java.awt.Shape; import java.util.NoSuchElementException; + /** - * STUBS ONLY - * XXX Implement and document. + * A two-dimensional curve that is parameterized with a quadratic + * function. + * + *

A drawing of a QuadCurve2D + * + * @author Eric Blake (ebb9@email.byu.edu) + * @author Sascha Brawer (brawer@dandelis.ch) + * + * @since 1.2 */ -public abstract class QuadCurve2D implements Shape, Cloneable +public abstract class QuadCurve2D + implements Shape, Cloneable { + /** + * Constructs a new QuadCurve2D. Typical users will want to + * construct instances of a subclass, such as {@link + * QuadCurve2D.Float} or {@link QuadCurve2D.Double}. + */ protected QuadCurve2D() { } + + /** + * Returns the x coordinate of the curve’s start + * point. + */ public abstract double getX1(); + + + /** + * Returns the y coordinate of the curve’s start + * point. + */ public abstract double getY1(); + + + /** + * Returns the curve’s start point. + */ public abstract Point2D getP1(); + + + /** + * Returns the x coordinate of the curve’s control + * point. + */ public abstract double getCtrlX(); + + + /** + * Returns the y coordinate of the curve’s control + * point. + */ public abstract double getCtrlY(); + + + /** + * Returns the curve’s control point. + */ public abstract Point2D getCtrlPt(); + + + /** + * Returns the x coordinate of the curve’s end + * point. + */ public abstract double getX2(); + + + /** + * Returns the y coordinate of the curve’s end + * point. + */ public abstract double getY2(); + + + /** + * Returns the curve’s end point. + */ public abstract Point2D getP2(); + + /** + * Changes the geometry of the curve. + * + * @param x1 the x coordinate of the curve’s new start + * point. + * + * @param y1 the y coordinate of the curve’s new start + * point. + * + * @param cx the x coordinate of the curve’s new + * control point. + * + * @param cy the y coordinate of the curve’s new + * control point. + * + * @param x2 the x coordinate of the curve’s new end + * point. + * + * @param y2 the y coordinate of the curve’s new end + * point. + */ public abstract void setCurve(double x1, double y1, double cx, double cy, double x2, double y2); + + public void setCurve(double[] coords, int offset) { setCurve(coords[offset++], coords[offset++], coords[offset++], coords[offset++], coords[offset++], coords[offset++]); } + + public void setCurve(Point2D p1, Point2D c, Point2D p2) { setCurve(p1.getX(), p1.getY(), c.getX(), c.getY(), p2.getX(), p2.getY()); } + + public void setCurve(Point2D[] pts, int offset) { setCurve(pts[offset].getX(), pts[offset++].getY(), pts[offset].getX(), pts[offset++].getY(), pts[offset].getX(), pts[offset++].getY()); } + + + /** + * Changes the geometry of the curve to that of another curve. + * + * @param c the curve whose coordinates will be copied. + */ public void setCurve(QuadCurve2D c) { setCurve(c.getX1(), c.getY1(), c.getCtrlX(), c.getCtrlY(), c.getX2(), c.getY2()); } + + public static double getFlatnessSq(double x1, double y1, double cx, double cy, double x2, double y2) { - // XXX Implement. - throw new Error("not implemented"); + return Line2D.ptSegDistSq(x1, y1, x2, y2, cx, cy); } + + public static double getFlatness(double x1, double y1, double cx, double cy, double x2, double y2) { - return Math.sqrt(getFlatnessSq(x1, y1, cx, cy, x2, y2)); + return Line2D.ptSegDist(x1, y1, x2, y2, cx, cy); } + + public static double getFlatnessSq(double[] coords, int offset) { - return getFlatnessSq(coords[offset++], coords[offset++], - coords[offset++], coords[offset++], - coords[offset++], coords[offset++]); + return Line2D.ptSegDistSq(coords[offset], coords[offset + 1], + coords[offset + 4], coords[offset + 5], + coords[offset + 2], coords[offset + 3]); } + + public static double getFlatness(double[] coords, int offset) { - return Math.sqrt(getFlatnessSq(coords[offset++], coords[offset++], - coords[offset++], coords[offset++], - coords[offset++], coords[offset++])); + return Line2D.ptSegDist(coords[offset], coords[offset + 1], + coords[offset + 4], coords[offset + 5], + coords[offset + 2], coords[offset + 3]); } + + public double getFlatnessSq() { - return getFlatnessSq(getX1(), getY1(), getCtrlX(), getCtrlY(), - getX2(), getY2()); + return Line2D.ptSegDistSq(getX1(), getY1(), + getX2(), getY2(), + getCtrlX(), getCtrlY()); } + + public double getFlatness() { - return Math.sqrt(getFlatnessSq(getX1(), getY1(), getCtrlX(), getCtrlY(), - getX2(), getY2())); + return Line2D.ptSegDist(getX1(), getY1(), + getX2(), getY2(), + getCtrlX(), getCtrlY()); } - public void subdivide(QuadCurve2D l, QuadCurve2D r) + + /** + * Subdivides this curve into two halves. + * + *

A drawing that illustrates the effects of
+   * subdividing a QuadCurve2D + * + * @param left a curve whose geometry will be set to the left half + * of this curve, or null if the caller is not + * interested in the left half. + * + * @param right a curve whose geometry will be set to the right half + * of this curve, or null if the caller is not + * interested in the right half. + */ + public void subdivide(QuadCurve2D left, QuadCurve2D right) { - if (l == null) - l = new QuadCurve2D.Double(); - if (r == null) - r = new QuadCurve2D.Double(); // Use empty slots at end to share single array. double[] d = new double[] { getX1(), getY1(), getCtrlX(), getCtrlY(), getX2(), getY2(), 0, 0, 0, 0 }; subdivide(d, 0, d, 0, d, 4); - l.setCurve(d, 0); - r.setCurve(d, 4); + if (left != null) + left.setCurve(d, 0); + if (right != null) + right.setCurve(d, 4); } - public static void subdivide(QuadCurve2D src, QuadCurve2D l, QuadCurve2D r) + + + /** + * Subdivides a quadratic curve into two halves. + * + *

A drawing that illustrates the effects of
+   * subdividing a QuadCurve2D + * + * @param src the curve to be subdivided. + * + * @param left a curve whose geometry will be set to the left half + * of src, or null if the caller is not + * interested in the left half. + * + * @param right a curve whose geometry will be set to the right half + * of src, or null if the caller is not + * interested in the right half. + */ + public static void subdivide(QuadCurve2D src, QuadCurve2D left, + QuadCurve2D right) { - src.subdivide(l, r); + src.subdivide(left, right); } + + + /** + * Subdivides a quadratic curve into two halves, passing all + * coordinates in an array. + * + *

A drawing that illustrates the effects of
+   * subdividing a QuadCurve2D + * + *

The left end point and the right start point will always be + * identical. Memory-concious programmers thus may want to pass the + * same array for both left and right, and + * set rightOff to leftOff + 4. + * + * @param src an array containing the coordinates of the curve to be + * subdivided. The x coordinate of the start point is + * located at src[srcOff], its y at + * src[srcOff + 1]. The x coordinate of the + * control point is located at src[srcOff + 2], its + * y at src[srcOff + 3]. The x + * coordinate of the end point is located at src[srcOff + + * 4], its y at src[srcOff + 5]. + * + * @param srcOff an offset into src, specifying + * the index of the start point’s x coordinate. + * + * @param left an array that will receive the coordinates of the + * left half of src. It is acceptable to pass + * src. A caller who is not interested in the left half + * can pass null. + * + * @param leftOff an offset into left, specifying the + * index where the start point’s x coordinate will be + * stored. + * + * @param right an array that will receive the coordinates of the + * right half of src. It is acceptable to pass + * src or left. A caller who is not + * interested in the right half can pass null. + * + * @param rightOff an offset into right, specifying the + * index where the start point’s x coordinate will be + * stored. + */ public static void subdivide(double[] src, int srcOff, double[] left, int leftOff, double[] right, int rightOff) { - // XXX Implement. - throw new Error("not implemented"); + double x1, y1, xc, yc, x2, y2; + + x1 = src[srcOff]; + y1 = src[srcOff + 1]; + xc = src[srcOff + 2]; + yc = src[srcOff + 3]; + x2 = src[srcOff + 4]; + y2 = src[srcOff + 5]; + + if (left != null) + { + left[leftOff] = x1; + left[leftOff + 1] = y1; + } + + if (right != null) + { + right[rightOff + 4] = x2; + right[rightOff + 5] = y2; + } + + x1 = (x1 + xc) / 2; + x2 = (xc + x2) / 2; + xc = (x1 + x2) / 2; + y1 = (y1 + yc) / 2; + y2 = (y2 + yc) / 2; + yc = (y1 + y2) / 2; + + if (left != null) + { + left[leftOff + 2] = x1; + left[leftOff + 3] = y1; + left[leftOff + 4] = xc; + left[leftOff + 5] = yc; + } + + if (right != null) + { + right[rightOff] = xc; + right[rightOff + 1] = yc; + right[rightOff + 2] = x2; + right[rightOff + 3] = y2; + } } + + public static int solveQuadratic(double[] eqn) { return solveQuadratic(eqn, eqn); } + + public static int solveQuadratic(double[] eqn, double[] res) { double c = eqn[0]; double b = eqn[1]; double a = eqn[2]; if (a == 0) - { - if (b == 0) - return -1; - res[0] = -c / b; - return 1; - } + { + if (b == 0) + return -1; + res[0] = -c / b; + return 1; + } c /= a; b /= a * 2; double det = Math.sqrt(b * b - c); @@ -167,49 +404,74 @@ public abstract class QuadCurve2D implements Shape, Cloneable return 0; // For fewer rounding errors, we calculate the two roots differently. if (b > 0) - { - res[0] = -b - det; - res[1] = -c / (b + det); - } + { + res[0] = -b - det; + res[1] = -c / (b + det); + } else - { - res[0] = -c / (b - det); - res[1] = -b + det; - } + { + res[0] = -c / (b - det); + res[1] = -b + det; + } return 2; } + public boolean contains(double x, double y) { // XXX Implement. throw new Error("not implemented"); } + + public boolean contains(Point2D p) { return contains(p.getX(), p.getY()); } + + public boolean intersects(double x, double y, double w, double h) { // XXX Implement. throw new Error("not implemented"); } + + public boolean intersects(Rectangle2D r) { return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight()); } + + public boolean contains(double x, double y, double w, double h) { // XXX Implement. throw new Error("not implemented"); } + + public boolean contains(Rectangle2D r) { return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight()); } + + + /** + * Determines the smallest rectangle that encloses the + * curve’s start, end and control point. As the illustration + * below shows, the invisible control point may cause the bounds to + * be much larger than the area that is actually covered by the + * curve. + * + *

An illustration of the bounds of a QuadCurve2D + */ public Rectangle getBounds() { return getBounds2D().getBounds(); } + + public PathIterator getPathIterator(final AffineTransform at) { return new PathIterator() @@ -217,115 +479,190 @@ public abstract class QuadCurve2D implements Shape, Cloneable /** Current coordinate. */ private int current = 0; + public int getWindingRule() { return WIND_NON_ZERO; } + public boolean isDone() { return current >= 2; } + public void next() { current++; } + public int currentSegment(float[] coords) { int result; switch (current) - { - case 0: - coords[0] = (float) getX1(); - coords[1] = (float) getY1(); - result = SEG_MOVETO; - break; - case 1: - coords[0] = (float) getCtrlX(); - coords[1] = (float) getCtrlY(); - coords[2] = (float) getX2(); - coords[3] = (float) getY2(); - result = SEG_QUADTO; - break; - default: - throw new NoSuchElementException("quad iterator out of bounds"); - } + { + case 0: + coords[0] = (float) getX1(); + coords[1] = (float) getY1(); + result = SEG_MOVETO; + break; + + case 1: + coords[0] = (float) getCtrlX(); + coords[1] = (float) getCtrlY(); + coords[2] = (float) getX2(); + coords[3] = (float) getY2(); + result = SEG_QUADTO; + break; + + default: + throw new NoSuchElementException("quad iterator out of bounds"); + } if (at != null) at.transform(coords, 0, coords, 0, 2); return result; } + public int currentSegment(double[] coords) { int result; switch (current) - { - case 0: - coords[0] = getX1(); - coords[1] = getY1(); - result = SEG_MOVETO; - break; - case 1: - coords[0] = getCtrlX(); - coords[1] = getCtrlY(); - coords[2] = getX2(); - coords[3] = getY2(); - result = SEG_QUADTO; - break; - default: - throw new NoSuchElementException("quad iterator out of bounds"); - } + { + case 0: + coords[0] = getX1(); + coords[1] = getY1(); + result = SEG_MOVETO; + break; + + case 1: + coords[0] = getCtrlX(); + coords[1] = getCtrlY(); + coords[2] = getX2(); + coords[3] = getY2(); + result = SEG_QUADTO; + break; + + default: + throw new NoSuchElementException("quad iterator out of bounds"); + } if (at != null) at.transform(coords, 0, coords, 0, 2); return result; } }; } + + public PathIterator getPathIterator(AffineTransform at, double flatness) { return new FlatteningPathIterator(getPathIterator(at), flatness); } + /** - * Create a new curve of the same run-time type with the same contents as + * Creates a new curve with the same contents as * this one. * - * @return the clone - * - * @exception OutOfMemoryError If there is not enough memory available. - * - * @since 1.2 + * @return the clone. */ public Object clone() { try - { - return super.clone(); - } + { + return super.clone(); + } catch (CloneNotSupportedException e) - { - throw (Error) new InternalError().initCause(e); // Impossible - } + { + throw (Error) new InternalError().initCause(e); // Impossible + } } + /** - * STUBS ONLY + * A two-dimensional curve that is parameterized with a quadratic + * function and stores coordinate values in double-precision + * floating-point format. + * + * @see QuadCurve2D.Float + * + * @author Eric Blake (ebb9@email.byu.edu) + * @author Sascha Brawer (brawer@dandelis.ch) */ - public static class Double extends QuadCurve2D + public static class Double + extends QuadCurve2D { + /** + * The x coordinate of the curve’s start point. + */ public double x1; + + + /** + * The y coordinate of the curve’s start point. + */ public double y1; + + + /** + * The x coordinate of the curve’s control point. + */ public double ctrlx; + + + /** + * The y coordinate of the curve’s control point. + */ public double ctrly; + + + /** + * The x coordinate of the curve’s end point. + */ public double x2; + + + /** + * The y coordinate of the curve’s end point. + */ public double y2; + + /** + * Constructs a new QuadCurve2D that stores its coordinate values + * in double-precision floating-point format. All points are + * initially at position (0, 0). + */ public Double() { } + + /** + * Constructs a new QuadCurve2D that stores its coordinate values + * in double-precision floating-point format, specifying the + * initial position of each point. + * + * @param x1 the x coordinate of the curve’s start + * point. + * + * @param y1 the y coordinate of the curve’s start + * point. + * + * @param cx the x coordinate of the curve’s control + * point. + * + * @param cy the y coordinate of the curve’s control + * point. + * + * @param x2 the x coordinate of the curve’s end + * point. + * + * @param y2 the y coordinate of the curve’s end + * point. + */ public Double(double x1, double y1, double cx, double cy, double x2, double y2) { @@ -337,45 +674,115 @@ public abstract class QuadCurve2D implements Shape, Cloneable this.y2 = y2; } + + /** + * Returns the x coordinate of the curve’s start + * point. + */ public double getX1() { return x1; } + + + /** + * Returns the y coordinate of the curve’s start + * point. + */ public double getY1() { return y1; } + + + /** + * Returns the curve’s start point. + */ public Point2D getP1() { return new Point2D.Double(x1, y1); } + + /** + * Returns the x coordinate of the curve’s control + * point. + */ public double getCtrlX() { return ctrlx; } + + + /** + * Returns the y coordinate of the curve’s control + * point. + */ public double getCtrlY() { return ctrly; } + + + /** + * Returns the curve’s control point. + */ public Point2D getCtrlPt() { return new Point2D.Double(ctrlx, ctrly); } + + /** + * Returns the x coordinate of the curve’s end + * point. + */ public double getX2() { return x2; } + + + /** + * Returns the y coordinate of the curve’s end + * point. + */ public double getY2() { return y2; } + + + /** + * Returns the curve’s end point. + */ public Point2D getP2() { return new Point2D.Double(x2, y2); } + + /** + * Changes the geometry of the curve. + * + * @param x1 the x coordinate of the curve’s new + * start point. + * + * @param y1 the y coordinate of the curve’s new + * start point. + * + * @param cx the x coordinate of the curve’s new + * control point. + * + * @param cy the y coordinate of the curve’s new + * control point. + * + * @param x2 the x coordinate of the curve’s new + * end point. + * + * @param y2 the y coordinate of the curve’s new + * end point. + */ public void setCurve(double x1, double y1, double cx, double cy, double x2, double y2) { @@ -386,6 +793,18 @@ public abstract class QuadCurve2D implements Shape, Cloneable this.x2 = x2; this.y2 = y2; } + + + /** + * Determines the smallest rectangle that encloses the + * curve’s start, end and control point. As the + * illustration below shows, the invisible control point may cause + * the bounds to be much larger than the area that is actually + * covered by the curve. + * + *

An illustration of the bounds of a QuadCurve2D + */ public Rectangle2D getBounds2D() { double nx1 = Math.min(Math.min(x1, ctrlx), x2); @@ -394,24 +813,91 @@ public abstract class QuadCurve2D implements Shape, Cloneable double ny2 = Math.max(Math.max(y1, ctrly), y2); return new Rectangle2D.Double(nx1, ny1, nx2 - nx1, ny2 - ny1); } - } // class Double + } + /** - * STUBS ONLY + * A two-dimensional curve that is parameterized with a quadratic + * function and stores coordinate values in single-precision + * floating-point format. + * + * @see QuadCurve2D.Double + * + * @author Eric Blake (ebb9@email.byu.edu) + * @author Sascha Brawer (brawer@dandelis.ch) */ - public static class Float extends QuadCurve2D + public static class Float + extends QuadCurve2D { + /** + * The x coordinate of the curve’s start point. + */ public float x1; + + + /** + * The y coordinate of the curve’s start point. + */ public float y1; + + + /** + * The x coordinate of the curve’s control point. + */ public float ctrlx; + + + /** + * The y coordinate of the curve’s control point. + */ public float ctrly; + + + /** + * The x coordinate of the curve’s end point. + */ public float x2; + + + /** + * The y coordinate of the curve’s end point. + */ public float y2; + + /** + * Constructs a new QuadCurve2D that stores its coordinate values + * in single-precision floating-point format. All points are + * initially at position (0, 0). + */ public Float() { } + + /** + * Constructs a new QuadCurve2D that stores its coordinate values + * in single-precision floating-point format, specifying the + * initial position of each point. + * + * @param x1 the x coordinate of the curve’s start + * point. + * + * @param y1 the y coordinate of the curve’s start + * point. + * + * @param cx the x coordinate of the curve’s control + * point. + * + * @param cy the y coordinate of the curve’s control + * point. + * + * @param x2 the x coordinate of the curve’s end + * point. + * + * @param y2 the y coordinate of the curve’s end + * point. + */ public Float(float x1, float y1, float cx, float cy, float x2, float y2) { @@ -423,45 +909,116 @@ public abstract class QuadCurve2D implements Shape, Cloneable this.y2 = y2; } + + /** + * Returns the x coordinate of the curve’s start + * point. + */ public double getX1() { return x1; } + + + /** + * Returns the y coordinate of the curve’s start + * point. + */ public double getY1() { return y1; } + + + /** + * Returns the curve’s start point. + */ public Point2D getP1() { return new Point2D.Float(x1, y1); } + + /** + * Returns the x coordinate of the curve’s control + * point. + */ public double getCtrlX() { return ctrlx; } + + + /** + * Returns the y coordinate of the curve’s control + * point. + */ public double getCtrlY() { return ctrly; } + + + /** + * Returns the curve’s control point. + */ public Point2D getCtrlPt() { return new Point2D.Float(ctrlx, ctrly); } + + /** + * Returns the x coordinate of the curve’s end + * point. + */ public double getX2() { return x2; } + + + /** + * Returns the y coordinate of the curve’s end + * point. + */ public double getY2() { return y2; } + + + /** + * Returns the curve’s end point. + */ public Point2D getP2() { return new Point2D.Float(x2, y2); } + + /** + * Changes the geometry of the curve, specifying coordinate values + * as double-precision floating-point numbers. + * + * @param x1 the x coordinate of the curve’s new + * start point. + * + * @param y1 the y coordinate of the curve’s new + * start point. + * + * @param cx the x coordinate of the curve’s new + * control point. + * + * @param cy the y coordinate of the curve’s new + * control point. + * + * @param x2 the x coordinate of the curve’s new + * end point. + * + * @param y2 the y coordinate of the curve’s new + * end point. + */ public void setCurve(double x1, double y1, double cx, double cy, double x2, double y2) { @@ -472,6 +1029,30 @@ public abstract class QuadCurve2D implements Shape, Cloneable this.x2 = (float) x2; this.y2 = (float) y2; } + + + /** + * Changes the geometry of the curve, specifying coordinate values + * as single-precision floating-point numbers. + * + * @param x1 the x coordinate of the curve’s new + * start point. + * + * @param y1 the y coordinate of the curve’s new + * start point. + * + * @param cx the x coordinate of the curve’s new + * control point. + * + * @param cy the y coordinate of the curve’s new + * control point. + * + * @param x2 the x coordinate of the curve’s new + * end point. + * + * @param y2 the y coordinate of the curve’s new + * end point. + */ public void setCurve(float x1, float y1, float cx, float cy, float x2, float y2) { @@ -482,6 +1063,18 @@ public abstract class QuadCurve2D implements Shape, Cloneable this.x2 = x2; this.y2 = y2; } + + + /** + * Determines the smallest rectangle that encloses the + * curve’s start, end and control point. As the + * illustration below shows, the invisible control point may cause + * the bounds to be much larger than the area that is actually + * covered by the curve. + * + *

An illustration of the bounds of a QuadCurve2D + */ public Rectangle2D getBounds2D() { float nx1 = (float) Math.min(Math.min(x1, ctrlx), x2); @@ -490,5 +1083,5 @@ public abstract class QuadCurve2D implements Shape, Cloneable float ny2 = (float) Math.max(Math.max(y1, ctrly), y2); return new Rectangle2D.Float(nx1, ny1, nx2 - nx1, ny2 - ny1); } - } // class Float -} // class CubicCurve2D + } +} diff --git a/libjava/java/awt/geom/doc-files/QuadCurve2D-1.png b/libjava/java/awt/geom/doc-files/QuadCurve2D-1.png new file mode 100644 index 0000000000000000000000000000000000000000..7c2ec0ea9cbc4bb0516c12cd357ba63b0aa27404 GIT binary patch literal 6363 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 M$*IArWXwYU17xKFH~;_u literal 0 Hc-jL100001 diff --git a/libjava/java/awt/geom/doc-files/QuadCurve2D-3.png b/libjava/java/awt/geom/doc-files/QuadCurve2D-3.png new file mode 100644 index 0000000000000000000000000000000000000000..a7557ba7bafd1b658aedf94074fb6307083c1c1f GIT binary patch literal 12334 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 Gf&T-ve6=e8 literal 0 Hc-jL100001 -- 2.47.3