< prev index next >

src/java.desktop/share/classes/java/awt/geom/QuadCurve2D.java

Print this page




  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.awt.geom;
  27 
  28 import java.awt.Shape;
  29 import java.awt.Rectangle;
  30 import java.io.Serializable;
  31 import sun.awt.geom.Curve;
  32 
  33 /**
  34  * The <code>QuadCurve2D</code> class defines a quadratic parametric curve
  35  * segment in {@code (x,y)} coordinate space.
  36  * <p>
  37  * This class is only the abstract superclass for all objects that
  38  * store a 2D quadratic curve segment.
  39  * The actual storage representation of the coordinates is left to
  40  * the subclass.
  41  *
  42  * @author      Jim Graham
  43  * @since 1.2
  44  */
  45 public abstract class QuadCurve2D implements Shape, Cloneable {
  46 
  47     /**
  48      * A quadratic parametric curve segment specified with
  49      * {@code float} coordinates.
  50      *
  51      * @since 1.2
  52      */
  53     public static class Float extends QuadCurve2D implements Serializable {
  54         /**


  83          */
  84         public float ctrly;
  85 
  86         /**
  87          * The X coordinate of the end point of the quadratic curve
  88          * segment.
  89          * @since 1.2
  90          * @serial
  91          */
  92         public float x2;
  93 
  94         /**
  95          * The Y coordinate of the end point of the quadratic curve
  96          * segment.
  97          * @since 1.2
  98          * @serial
  99          */
 100         public float y2;
 101 
 102         /**
 103          * Constructs and initializes a <code>QuadCurve2D</code> with
 104          * coordinates (0, 0, 0, 0, 0, 0).
 105          * @since 1.2
 106          */
 107         public Float() {
 108         }
 109 
 110         /**
 111          * Constructs and initializes a <code>QuadCurve2D</code> from the
 112          * specified {@code float} coordinates.
 113          *
 114          * @param x1 the X coordinate of the start point
 115          * @param y1 the Y coordinate of the start point
 116          * @param ctrlx the X coordinate of the control point
 117          * @param ctrly the Y coordinate of the control point
 118          * @param x2 the X coordinate of the end point
 119          * @param y2 the Y coordinate of the end point
 120          * @since 1.2
 121          */
 122         public Float(float x1, float y1,
 123                      float ctrlx, float ctrly,
 124                      float x2, float y2)
 125         {
 126             setCurve(x1, y1, ctrlx, ctrly, x2, y2);
 127         }
 128 
 129         /**
 130          * {@inheritDoc}
 131          * @since 1.2


 296          */
 297         public double ctrly;
 298 
 299         /**
 300          * The X coordinate of the end point of the quadratic curve
 301          * segment.
 302          * @since 1.2
 303          * @serial
 304          */
 305         public double x2;
 306 
 307         /**
 308          * The Y coordinate of the end point of the quadratic curve
 309          * segment.
 310          * @since 1.2
 311          * @serial
 312          */
 313         public double y2;
 314 
 315         /**
 316          * Constructs and initializes a <code>QuadCurve2D</code> with
 317          * coordinates (0, 0, 0, 0, 0, 0).
 318          * @since 1.2
 319          */
 320         public Double() {
 321         }
 322 
 323         /**
 324          * Constructs and initializes a <code>QuadCurve2D</code> from the
 325          * specified {@code double} coordinates.
 326          *
 327          * @param x1 the X coordinate of the start point
 328          * @param y1 the Y coordinate of the start point
 329          * @param ctrlx the X coordinate of the control point
 330          * @param ctrly the Y coordinate of the control point
 331          * @param x2 the X coordinate of the end point
 332          * @param y2 the Y coordinate of the end point
 333          * @since 1.2
 334          */
 335         public Double(double x1, double y1,
 336                       double ctrlx, double ctrly,
 337                       double x2, double y2)
 338         {
 339             setCurve(x1, y1, ctrlx, ctrly, x2, y2);
 340         }
 341 
 342         /**
 343          * {@inheritDoc}
 344          * @since 1.2


 445          */
 446         private static final long serialVersionUID = 4217149928428559721L;
 447     }
 448 
 449     /**
 450      * This is an abstract class that cannot be instantiated directly.
 451      * Type-specific implementation subclasses are available for
 452      * instantiation and provide a number of formats for storing
 453      * the information necessary to satisfy the various accessor
 454      * methods below.
 455      *
 456      * @see java.awt.geom.QuadCurve2D.Float
 457      * @see java.awt.geom.QuadCurve2D.Double
 458      * @since 1.2
 459      */
 460     protected QuadCurve2D() {
 461     }
 462 
 463     /**
 464      * Returns the X coordinate of the start point in
 465      * <code>double</code> in precision.
 466      * @return the X coordinate of the start point.
 467      * @since 1.2
 468      */
 469     public abstract double getX1();
 470 
 471     /**
 472      * Returns the Y coordinate of the start point in
 473      * <code>double</code> precision.
 474      * @return the Y coordinate of the start point.
 475      * @since 1.2
 476      */
 477     public abstract double getY1();
 478 
 479     /**
 480      * Returns the start point.
 481      * @return a <code>Point2D</code> that is the start point of this
 482      *          <code>QuadCurve2D</code>.
 483      * @since 1.2
 484      */
 485     public abstract Point2D getP1();
 486 
 487     /**
 488      * Returns the X coordinate of the control point in
 489      * <code>double</code> precision.
 490      * @return X coordinate the control point
 491      * @since 1.2
 492      */
 493     public abstract double getCtrlX();
 494 
 495     /**
 496      * Returns the Y coordinate of the control point in
 497      * <code>double</code> precision.
 498      * @return the Y coordinate of the control point.
 499      * @since 1.2
 500      */
 501     public abstract double getCtrlY();
 502 
 503     /**
 504      * Returns the control point.
 505      * @return a <code>Point2D</code> that is the control point of this
 506      *          <code>Point2D</code>.
 507      * @since 1.2
 508      */
 509     public abstract Point2D getCtrlPt();
 510 
 511     /**
 512      * Returns the X coordinate of the end point in
 513      * <code>double</code> precision.
 514      * @return the x coordinate of the end point.
 515      * @since 1.2
 516      */
 517     public abstract double getX2();
 518 
 519     /**
 520      * Returns the Y coordinate of the end point in
 521      * <code>double</code> precision.
 522      * @return the Y coordinate of the end point.
 523      * @since 1.2
 524      */
 525     public abstract double getY2();
 526 
 527     /**
 528      * Returns the end point.
 529      * @return a <code>Point</code> object that is the end point
 530      *          of this <code>Point2D</code>.
 531      * @since 1.2
 532      */
 533     public abstract Point2D getP2();
 534 
 535     /**
 536      * Sets the location of the end points and control point of this curve
 537      * to the specified <code>double</code> coordinates.
 538      *
 539      * @param x1 the X coordinate of the start point
 540      * @param y1 the Y coordinate of the start point
 541      * @param ctrlx the X coordinate of the control point
 542      * @param ctrly the Y coordinate of the control point
 543      * @param x2 the X coordinate of the end point
 544      * @param y2 the Y coordinate of the end point
 545      * @since 1.2
 546      */
 547     public abstract void setCurve(double x1, double y1,
 548                                   double ctrlx, double ctrly,
 549                                   double x2, double y2);
 550 
 551     /**
 552      * Sets the location of the end points and control points of this
 553      * <code>QuadCurve2D</code> to the <code>double</code> coordinates at
 554      * the specified offset in the specified array.
 555      * @param coords the array containing coordinate values
 556      * @param offset the index into the array from which to start
 557      *          getting the coordinate values and assigning them to this
 558      *          <code>QuadCurve2D</code>
 559      * @since 1.2
 560      */
 561     public void setCurve(double[] coords, int offset) {
 562         setCurve(coords[offset + 0], coords[offset + 1],
 563                  coords[offset + 2], coords[offset + 3],
 564                  coords[offset + 4], coords[offset + 5]);
 565     }
 566 
 567     /**
 568      * Sets the location of the end points and control point of this
 569      * <code>QuadCurve2D</code> to the specified <code>Point2D</code>
 570      * coordinates.
 571      * @param p1 the start point
 572      * @param cp the control point
 573      * @param p2 the end point
 574      * @since 1.2
 575      */
 576     public void setCurve(Point2D p1, Point2D cp, Point2D p2) {
 577         setCurve(p1.getX(), p1.getY(),
 578                  cp.getX(), cp.getY(),
 579                  p2.getX(), p2.getY());
 580     }
 581 
 582     /**
 583      * Sets the location of the end points and control points of this
 584      * <code>QuadCurve2D</code> to the coordinates of the
 585      * <code>Point2D</code> objects at the specified offset in
 586      * the specified array.
 587      * @param pts an array containing <code>Point2D</code> that define
 588      *          coordinate values
 589      * @param offset the index into <code>pts</code> from which to start
 590      *          getting the coordinate values and assigning them to this
 591      *          <code>QuadCurve2D</code>
 592      * @since 1.2
 593      */
 594     public void setCurve(Point2D[] pts, int offset) {
 595         setCurve(pts[offset + 0].getX(), pts[offset + 0].getY(),
 596                  pts[offset + 1].getX(), pts[offset + 1].getY(),
 597                  pts[offset + 2].getX(), pts[offset + 2].getY());
 598     }
 599 
 600     /**
 601      * Sets the location of the end points and control point of this
 602      * <code>QuadCurve2D</code> to the same as those in the specified
 603      * <code>QuadCurve2D</code>.
 604      * @param c the specified <code>QuadCurve2D</code>
 605      * @since 1.2
 606      */
 607     public void setCurve(QuadCurve2D c) {
 608         setCurve(c.getX1(), c.getY1(),
 609                  c.getCtrlX(), c.getCtrlY(),
 610                  c.getX2(), c.getY2());
 611     }
 612 
 613     /**
 614      * Returns the square of the flatness, or maximum distance of a
 615      * control point from the line connecting the end points, of the
 616      * quadratic curve specified by the indicated control points.
 617      *
 618      * @param x1 the X coordinate of the start point
 619      * @param y1 the Y coordinate of the start point
 620      * @param ctrlx the X coordinate of the control point
 621      * @param ctrly the Y coordinate of the control point
 622      * @param x2 the X coordinate of the end point
 623      * @param y2 the Y coordinate of the end point
 624      * @return the square of the flatness of the quadratic curve


 641      * @param ctrlx the X coordinate of the control point
 642      * @param ctrly the Y coordinate of the control point
 643      * @param x2 the X coordinate of the end point
 644      * @param y2 the Y coordinate of the end point
 645      * @return the flatness of the quadratic curve defined by the
 646      *          specified coordinates.
 647      * @since 1.2
 648      */
 649     public static double getFlatness(double x1, double y1,
 650                                      double ctrlx, double ctrly,
 651                                      double x2, double y2) {
 652         return Line2D.ptSegDist(x1, y1, x2, y2, ctrlx, ctrly);
 653     }
 654 
 655     /**
 656      * Returns the square of the flatness, or maximum distance of a
 657      * control point from the line connecting the end points, of the
 658      * quadratic curve specified by the control points stored in the
 659      * indicated array at the indicated index.
 660      * @param coords an array containing coordinate values
 661      * @param offset the index into <code>coords</code> from which to
 662      *          to start getting the values from the array
 663      * @return the flatness of the quadratic curve that is defined by the
 664      *          values in the specified array at the specified index.
 665      * @since 1.2
 666      */
 667     public static double getFlatnessSq(double coords[], int offset) {
 668         return Line2D.ptSegDistSq(coords[offset + 0], coords[offset + 1],
 669                                   coords[offset + 4], coords[offset + 5],
 670                                   coords[offset + 2], coords[offset + 3]);
 671     }
 672 
 673     /**
 674      * Returns the flatness, or maximum distance of a
 675      * control point from the line connecting the end points, of the
 676      * quadratic curve specified by the control points stored in the
 677      * indicated array at the indicated index.
 678      * @param coords an array containing coordinate values
 679      * @param offset the index into <code>coords</code> from which to
 680      *          start getting the coordinate values
 681      * @return the flatness of a quadratic curve defined by the
 682      *          specified array at the specified offset.
 683      * @since 1.2
 684      */
 685     public static double getFlatness(double coords[], int offset) {
 686         return Line2D.ptSegDist(coords[offset + 0], coords[offset + 1],
 687                                 coords[offset + 4], coords[offset + 5],
 688                                 coords[offset + 2], coords[offset + 3]);
 689     }
 690 
 691     /**
 692      * Returns the square of the flatness, or maximum distance of a
 693      * control point from the line connecting the end points, of this
 694      * <code>QuadCurve2D</code>.
 695      * @return the square of the flatness of this
 696      *          <code>QuadCurve2D</code>.
 697      * @since 1.2
 698      */
 699     public double getFlatnessSq() {
 700         return Line2D.ptSegDistSq(getX1(), getY1(),
 701                                   getX2(), getY2(),
 702                                   getCtrlX(), getCtrlY());
 703     }
 704 
 705     /**
 706      * Returns the flatness, or maximum distance of a
 707      * control point from the line connecting the end points, of this
 708      * <code>QuadCurve2D</code>.
 709      * @return the flatness of this <code>QuadCurve2D</code>.
 710      * @since 1.2
 711      */
 712     public double getFlatness() {
 713         return Line2D.ptSegDist(getX1(), getY1(),
 714                                 getX2(), getY2(),
 715                                 getCtrlX(), getCtrlY());
 716     }
 717 
 718     /**
 719      * Subdivides this <code>QuadCurve2D</code> and stores the resulting
 720      * two subdivided curves into the <code>left</code> and
 721      * <code>right</code> curve parameters.
 722      * Either or both of the <code>left</code> and <code>right</code>
 723      * objects can be the same as this <code>QuadCurve2D</code> or
 724      * <code>null</code>.
 725      * @param left the <code>QuadCurve2D</code> object for storing the
 726      * left or first half of the subdivided curve
 727      * @param right the <code>QuadCurve2D</code> object for storing the
 728      * right or second half of the subdivided curve
 729      * @since 1.2
 730      */
 731     public void subdivide(QuadCurve2D left, QuadCurve2D right) {
 732         subdivide(this, left, right);
 733     }
 734 
 735     /**
 736      * Subdivides the quadratic curve specified by the <code>src</code>
 737      * parameter and stores the resulting two subdivided curves into the
 738      * <code>left</code> and <code>right</code> curve parameters.
 739      * Either or both of the <code>left</code> and <code>right</code>
 740      * objects can be the same as the <code>src</code> object or
 741      * <code>null</code>.
 742      * @param src the quadratic curve to be subdivided
 743      * @param left the <code>QuadCurve2D</code> object for storing the
 744      *          left or first half of the subdivided curve
 745      * @param right the <code>QuadCurve2D</code> object for storing the
 746      *          right or second half of the subdivided curve
 747      * @since 1.2
 748      */
 749     public static void subdivide(QuadCurve2D src,
 750                                  QuadCurve2D left,
 751                                  QuadCurve2D right) {
 752         double x1 = src.getX1();
 753         double y1 = src.getY1();
 754         double ctrlx = src.getCtrlX();
 755         double ctrly = src.getCtrlY();
 756         double x2 = src.getX2();
 757         double y2 = src.getY2();
 758         double ctrlx1 = (x1 + ctrlx) / 2.0;
 759         double ctrly1 = (y1 + ctrly) / 2.0;
 760         double ctrlx2 = (x2 + ctrlx) / 2.0;
 761         double ctrly2 = (y2 + ctrly) / 2.0;
 762         ctrlx = (ctrlx1 + ctrlx2) / 2.0;
 763         ctrly = (ctrly1 + ctrly2) / 2.0;
 764         if (left != null) {
 765             left.setCurve(x1, y1, ctrlx1, ctrly1, ctrlx, ctrly);
 766         }
 767         if (right != null) {
 768             right.setCurve(ctrlx, ctrly, ctrlx2, ctrly2, x2, y2);
 769         }
 770     }
 771 
 772     /**
 773      * Subdivides the quadratic curve specified by the coordinates
 774      * stored in the <code>src</code> array at indices
 775      * <code>srcoff</code> through <code>srcoff</code>&nbsp;+&nbsp;5
 776      * and stores the resulting two subdivided curves into the two
 777      * result arrays at the corresponding indices.
 778      * Either or both of the <code>left</code> and <code>right</code>
 779      * arrays can be <code>null</code> or a reference to the same array
 780      * and offset as the <code>src</code> array.
 781      * Note that the last point in the first subdivided curve is the
 782      * same as the first point in the second subdivided curve.  Thus,
 783      * it is possible to pass the same array for <code>left</code> and
 784      * <code>right</code> and to use offsets such that
 785      * <code>rightoff</code> equals <code>leftoff</code> + 4 in order
 786      * to avoid allocating extra storage for this common point.
 787      * @param src the array holding the coordinates for the source curve
 788      * @param srcoff the offset into the array of the beginning of the
 789      * the 6 source coordinates
 790      * @param left the array for storing the coordinates for the first
 791      * half of the subdivided curve
 792      * @param leftoff the offset into the array of the beginning of the
 793      * the 6 left coordinates
 794      * @param right the array for storing the coordinates for the second
 795      * half of the subdivided curve
 796      * @param rightoff the offset into the array of the beginning of the
 797      * the 6 right coordinates
 798      * @since 1.2
 799      */
 800     public static void subdivide(double src[], int srcoff,
 801                                  double left[], int leftoff,
 802                                  double right[], int rightoff) {
 803         double x1 = src[srcoff + 0];
 804         double y1 = src[srcoff + 1];
 805         double ctrlx = src[srcoff + 2];


 818         y1 = (y1 + ctrly) / 2.0;
 819         x2 = (x2 + ctrlx) / 2.0;
 820         y2 = (y2 + ctrly) / 2.0;
 821         ctrlx = (x1 + x2) / 2.0;
 822         ctrly = (y1 + y2) / 2.0;
 823         if (left != null) {
 824             left[leftoff + 2] = x1;
 825             left[leftoff + 3] = y1;
 826             left[leftoff + 4] = ctrlx;
 827             left[leftoff + 5] = ctrly;
 828         }
 829         if (right != null) {
 830             right[rightoff + 0] = ctrlx;
 831             right[rightoff + 1] = ctrly;
 832             right[rightoff + 2] = x2;
 833             right[rightoff + 3] = y2;
 834         }
 835     }
 836 
 837     /**
 838      * Solves the quadratic whose coefficients are in the <code>eqn</code>
 839      * array and places the non-complex roots back into the same array,
 840      * returning the number of roots.  The quadratic solved is represented
 841      * by the equation:
 842      * <pre>
 843      *     eqn = {C, B, A};
 844      *     ax^2 + bx + c = 0
 845      * </pre>
 846      * A return value of <code>-1</code> is used to distinguish a constant
 847      * equation, which might be always 0 or never 0, from an equation that
 848      * has no zeroes.
 849      * @param eqn the array that contains the quadratic coefficients
 850      * @return the number of roots, or <code>-1</code> if the equation is
 851      *          a constant
 852      * @since 1.2
 853      */
 854     public static int solveQuadratic(double eqn[]) {
 855         return solveQuadratic(eqn, eqn);
 856     }
 857 
 858     /**
 859      * Solves the quadratic whose coefficients are in the <code>eqn</code>
 860      * array and places the non-complex roots into the <code>res</code>
 861      * array, returning the number of roots.
 862      * The quadratic solved is represented by the equation:
 863      * <pre>
 864      *     eqn = {C, B, A};
 865      *     ax^2 + bx + c = 0
 866      * </pre>
 867      * A return value of <code>-1</code> is used to distinguish a constant
 868      * equation, which might be always 0 or never 0, from an equation that
 869      * has no zeroes.
 870      * @param eqn the specified array of coefficients to use to solve
 871      *        the quadratic equation
 872      * @param res the array that contains the non-complex roots
 873      *        resulting from the solution of the quadratic equation
 874      * @return the number of roots, or <code>-1</code> if the equation is
 875      *  a constant.
 876      * @since 1.3
 877      */
 878     public static int solveQuadratic(double eqn[], double res[]) {
 879         double a = eqn[2];
 880         double b = eqn[1];
 881         double c = eqn[0];
 882         int roots = 0;
 883         if (a == 0.0) {
 884             // The quadratic parabola has degenerated to a line.
 885             if (b == 0.0) {
 886                 // The line has degenerated to a constant.
 887                 return -1;
 888             }
 889             res[roots++] = -c / b;
 890         } else {
 891             // From Numerical Recipes, 5.6, Quadratic and Cubic Equations
 892             double d = b * b - 4.0 * a * c;
 893             if (d < 0.0) {
 894                 // If d < 0.0, then there are no roots


1326     }
1327 
1328     /**
1329      * {@inheritDoc}
1330      * @since 1.2
1331      */
1332     public boolean contains(Rectangle2D r) {
1333         return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
1334     }
1335 
1336     /**
1337      * {@inheritDoc}
1338      * @since 1.2
1339      */
1340     public Rectangle getBounds() {
1341         return getBounds2D().getBounds();
1342     }
1343 
1344     /**
1345      * Returns an iteration object that defines the boundary of the
1346      * shape of this <code>QuadCurve2D</code>.
1347      * The iterator for this class is not multi-threaded safe,
1348      * which means that this <code>QuadCurve2D</code> class does not
1349      * guarantee that modifications to the geometry of this
1350      * <code>QuadCurve2D</code> object do not affect any iterations of
1351      * that geometry that are already in process.
1352      * @param at an optional {@link AffineTransform} to apply to the
1353      *          shape boundary
1354      * @return a {@link PathIterator} object that defines the boundary
1355      *          of the shape.
1356      * @since 1.2
1357      */
1358     public PathIterator getPathIterator(AffineTransform at) {
1359         return new QuadIterator(this, at);
1360     }
1361 
1362     /**
1363      * Returns an iteration object that defines the boundary of the
1364      * flattened shape of this <code>QuadCurve2D</code>.
1365      * The iterator for this class is not multi-threaded safe,
1366      * which means that this <code>QuadCurve2D</code> class does not
1367      * guarantee that modifications to the geometry of this
1368      * <code>QuadCurve2D</code> object do not affect any iterations of
1369      * that geometry that are already in process.
1370      * @param at an optional <code>AffineTransform</code> to apply
1371      *          to the boundary of the shape
1372      * @param flatness the maximum distance that the control points for a
1373      *          subdivided curve can be with respect to a line connecting
1374      *          the end points of this curve before this curve is
1375      *          replaced by a straight line connecting the end points.
1376      * @return a <code>PathIterator</code> object that defines the
1377      *          flattened boundary of the shape.
1378      * @since 1.2
1379      */
1380     public PathIterator getPathIterator(AffineTransform at, double flatness) {
1381         return new FlatteningPathIterator(getPathIterator(at), flatness);
1382     }
1383 
1384     /**
1385      * Creates a new object of the same class and with the same contents
1386      * as this object.
1387      *
1388      * @return     a clone of this instance.
1389      * @exception  OutOfMemoryError            if there is not enough memory.
1390      * @see        java.lang.Cloneable
1391      * @since      1.2
1392      */
1393     public Object clone() {
1394         try {
1395             return super.clone();
1396         } catch (CloneNotSupportedException e) {


  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.awt.geom;
  27 
  28 import java.awt.Shape;
  29 import java.awt.Rectangle;
  30 import java.io.Serializable;
  31 import sun.awt.geom.Curve;
  32 
  33 /**
  34  * The {@code QuadCurve2D} class defines a quadratic parametric curve
  35  * segment in {@code (x,y)} coordinate space.
  36  * <p>
  37  * This class is only the abstract superclass for all objects that
  38  * store a 2D quadratic curve segment.
  39  * The actual storage representation of the coordinates is left to
  40  * the subclass.
  41  *
  42  * @author      Jim Graham
  43  * @since 1.2
  44  */
  45 public abstract class QuadCurve2D implements Shape, Cloneable {
  46 
  47     /**
  48      * A quadratic parametric curve segment specified with
  49      * {@code float} coordinates.
  50      *
  51      * @since 1.2
  52      */
  53     public static class Float extends QuadCurve2D implements Serializable {
  54         /**


  83          */
  84         public float ctrly;
  85 
  86         /**
  87          * The X coordinate of the end point of the quadratic curve
  88          * segment.
  89          * @since 1.2
  90          * @serial
  91          */
  92         public float x2;
  93 
  94         /**
  95          * The Y coordinate of the end point of the quadratic curve
  96          * segment.
  97          * @since 1.2
  98          * @serial
  99          */
 100         public float y2;
 101 
 102         /**
 103          * Constructs and initializes a {@code QuadCurve2D} with
 104          * coordinates (0, 0, 0, 0, 0, 0).
 105          * @since 1.2
 106          */
 107         public Float() {
 108         }
 109 
 110         /**
 111          * Constructs and initializes a {@code QuadCurve2D} from the
 112          * specified {@code float} coordinates.
 113          *
 114          * @param x1 the X coordinate of the start point
 115          * @param y1 the Y coordinate of the start point
 116          * @param ctrlx the X coordinate of the control point
 117          * @param ctrly the Y coordinate of the control point
 118          * @param x2 the X coordinate of the end point
 119          * @param y2 the Y coordinate of the end point
 120          * @since 1.2
 121          */
 122         public Float(float x1, float y1,
 123                      float ctrlx, float ctrly,
 124                      float x2, float y2)
 125         {
 126             setCurve(x1, y1, ctrlx, ctrly, x2, y2);
 127         }
 128 
 129         /**
 130          * {@inheritDoc}
 131          * @since 1.2


 296          */
 297         public double ctrly;
 298 
 299         /**
 300          * The X coordinate of the end point of the quadratic curve
 301          * segment.
 302          * @since 1.2
 303          * @serial
 304          */
 305         public double x2;
 306 
 307         /**
 308          * The Y coordinate of the end point of the quadratic curve
 309          * segment.
 310          * @since 1.2
 311          * @serial
 312          */
 313         public double y2;
 314 
 315         /**
 316          * Constructs and initializes a {@code QuadCurve2D} with
 317          * coordinates (0, 0, 0, 0, 0, 0).
 318          * @since 1.2
 319          */
 320         public Double() {
 321         }
 322 
 323         /**
 324          * Constructs and initializes a {@code QuadCurve2D} from the
 325          * specified {@code double} coordinates.
 326          *
 327          * @param x1 the X coordinate of the start point
 328          * @param y1 the Y coordinate of the start point
 329          * @param ctrlx the X coordinate of the control point
 330          * @param ctrly the Y coordinate of the control point
 331          * @param x2 the X coordinate of the end point
 332          * @param y2 the Y coordinate of the end point
 333          * @since 1.2
 334          */
 335         public Double(double x1, double y1,
 336                       double ctrlx, double ctrly,
 337                       double x2, double y2)
 338         {
 339             setCurve(x1, y1, ctrlx, ctrly, x2, y2);
 340         }
 341 
 342         /**
 343          * {@inheritDoc}
 344          * @since 1.2


 445          */
 446         private static final long serialVersionUID = 4217149928428559721L;
 447     }
 448 
 449     /**
 450      * This is an abstract class that cannot be instantiated directly.
 451      * Type-specific implementation subclasses are available for
 452      * instantiation and provide a number of formats for storing
 453      * the information necessary to satisfy the various accessor
 454      * methods below.
 455      *
 456      * @see java.awt.geom.QuadCurve2D.Float
 457      * @see java.awt.geom.QuadCurve2D.Double
 458      * @since 1.2
 459      */
 460     protected QuadCurve2D() {
 461     }
 462 
 463     /**
 464      * Returns the X coordinate of the start point in
 465      * {@code double} in precision.
 466      * @return the X coordinate of the start point.
 467      * @since 1.2
 468      */
 469     public abstract double getX1();
 470 
 471     /**
 472      * Returns the Y coordinate of the start point in
 473      * {@code double} precision.
 474      * @return the Y coordinate of the start point.
 475      * @since 1.2
 476      */
 477     public abstract double getY1();
 478 
 479     /**
 480      * Returns the start point.
 481      * @return a {@code Point2D} that is the start point of this
 482      *          {@code QuadCurve2D}.
 483      * @since 1.2
 484      */
 485     public abstract Point2D getP1();
 486 
 487     /**
 488      * Returns the X coordinate of the control point in
 489      * {@code double} precision.
 490      * @return X coordinate the control point
 491      * @since 1.2
 492      */
 493     public abstract double getCtrlX();
 494 
 495     /**
 496      * Returns the Y coordinate of the control point in
 497      * {@code double} precision.
 498      * @return the Y coordinate of the control point.
 499      * @since 1.2
 500      */
 501     public abstract double getCtrlY();
 502 
 503     /**
 504      * Returns the control point.
 505      * @return a {@code Point2D} that is the control point of this
 506      *          {@code Point2D}.
 507      * @since 1.2
 508      */
 509     public abstract Point2D getCtrlPt();
 510 
 511     /**
 512      * Returns the X coordinate of the end point in
 513      * {@code double} precision.
 514      * @return the x coordinate of the end point.
 515      * @since 1.2
 516      */
 517     public abstract double getX2();
 518 
 519     /**
 520      * Returns the Y coordinate of the end point in
 521      * {@code double} precision.
 522      * @return the Y coordinate of the end point.
 523      * @since 1.2
 524      */
 525     public abstract double getY2();
 526 
 527     /**
 528      * Returns the end point.
 529      * @return a {@code Point} object that is the end point
 530      *          of this {@code Point2D}.
 531      * @since 1.2
 532      */
 533     public abstract Point2D getP2();
 534 
 535     /**
 536      * Sets the location of the end points and control point of this curve
 537      * to the specified {@code double} coordinates.
 538      *
 539      * @param x1 the X coordinate of the start point
 540      * @param y1 the Y coordinate of the start point
 541      * @param ctrlx the X coordinate of the control point
 542      * @param ctrly the Y coordinate of the control point
 543      * @param x2 the X coordinate of the end point
 544      * @param y2 the Y coordinate of the end point
 545      * @since 1.2
 546      */
 547     public abstract void setCurve(double x1, double y1,
 548                                   double ctrlx, double ctrly,
 549                                   double x2, double y2);
 550 
 551     /**
 552      * Sets the location of the end points and control points of this
 553      * {@code QuadCurve2D} to the {@code double} coordinates at
 554      * the specified offset in the specified array.
 555      * @param coords the array containing coordinate values
 556      * @param offset the index into the array from which to start
 557      *          getting the coordinate values and assigning them to this
 558      *          {@code QuadCurve2D}
 559      * @since 1.2
 560      */
 561     public void setCurve(double[] coords, int offset) {
 562         setCurve(coords[offset + 0], coords[offset + 1],
 563                  coords[offset + 2], coords[offset + 3],
 564                  coords[offset + 4], coords[offset + 5]);
 565     }
 566 
 567     /**
 568      * Sets the location of the end points and control point of this
 569      * {@code QuadCurve2D} to the specified {@code Point2D}
 570      * coordinates.
 571      * @param p1 the start point
 572      * @param cp the control point
 573      * @param p2 the end point
 574      * @since 1.2
 575      */
 576     public void setCurve(Point2D p1, Point2D cp, Point2D p2) {
 577         setCurve(p1.getX(), p1.getY(),
 578                  cp.getX(), cp.getY(),
 579                  p2.getX(), p2.getY());
 580     }
 581 
 582     /**
 583      * Sets the location of the end points and control points of this
 584      * {@code QuadCurve2D} to the coordinates of the
 585      * {@code Point2D} objects at the specified offset in
 586      * the specified array.
 587      * @param pts an array containing {@code Point2D} that define
 588      *          coordinate values
 589      * @param offset the index into {@code pts} from which to start
 590      *          getting the coordinate values and assigning them to this
 591      *          {@code QuadCurve2D}
 592      * @since 1.2
 593      */
 594     public void setCurve(Point2D[] pts, int offset) {
 595         setCurve(pts[offset + 0].getX(), pts[offset + 0].getY(),
 596                  pts[offset + 1].getX(), pts[offset + 1].getY(),
 597                  pts[offset + 2].getX(), pts[offset + 2].getY());
 598     }
 599 
 600     /**
 601      * Sets the location of the end points and control point of this
 602      * {@code QuadCurve2D} to the same as those in the specified
 603      * {@code QuadCurve2D}.
 604      * @param c the specified {@code QuadCurve2D}
 605      * @since 1.2
 606      */
 607     public void setCurve(QuadCurve2D c) {
 608         setCurve(c.getX1(), c.getY1(),
 609                  c.getCtrlX(), c.getCtrlY(),
 610                  c.getX2(), c.getY2());
 611     }
 612 
 613     /**
 614      * Returns the square of the flatness, or maximum distance of a
 615      * control point from the line connecting the end points, of the
 616      * quadratic curve specified by the indicated control points.
 617      *
 618      * @param x1 the X coordinate of the start point
 619      * @param y1 the Y coordinate of the start point
 620      * @param ctrlx the X coordinate of the control point
 621      * @param ctrly the Y coordinate of the control point
 622      * @param x2 the X coordinate of the end point
 623      * @param y2 the Y coordinate of the end point
 624      * @return the square of the flatness of the quadratic curve


 641      * @param ctrlx the X coordinate of the control point
 642      * @param ctrly the Y coordinate of the control point
 643      * @param x2 the X coordinate of the end point
 644      * @param y2 the Y coordinate of the end point
 645      * @return the flatness of the quadratic curve defined by the
 646      *          specified coordinates.
 647      * @since 1.2
 648      */
 649     public static double getFlatness(double x1, double y1,
 650                                      double ctrlx, double ctrly,
 651                                      double x2, double y2) {
 652         return Line2D.ptSegDist(x1, y1, x2, y2, ctrlx, ctrly);
 653     }
 654 
 655     /**
 656      * Returns the square of the flatness, or maximum distance of a
 657      * control point from the line connecting the end points, of the
 658      * quadratic curve specified by the control points stored in the
 659      * indicated array at the indicated index.
 660      * @param coords an array containing coordinate values
 661      * @param offset the index into {@code coords} from which to
 662      *          to start getting the values from the array
 663      * @return the flatness of the quadratic curve that is defined by the
 664      *          values in the specified array at the specified index.
 665      * @since 1.2
 666      */
 667     public static double getFlatnessSq(double coords[], int offset) {
 668         return Line2D.ptSegDistSq(coords[offset + 0], coords[offset + 1],
 669                                   coords[offset + 4], coords[offset + 5],
 670                                   coords[offset + 2], coords[offset + 3]);
 671     }
 672 
 673     /**
 674      * Returns the flatness, or maximum distance of a
 675      * control point from the line connecting the end points, of the
 676      * quadratic curve specified by the control points stored in the
 677      * indicated array at the indicated index.
 678      * @param coords an array containing coordinate values
 679      * @param offset the index into {@code coords} from which to
 680      *          start getting the coordinate values
 681      * @return the flatness of a quadratic curve defined by the
 682      *          specified array at the specified offset.
 683      * @since 1.2
 684      */
 685     public static double getFlatness(double coords[], int offset) {
 686         return Line2D.ptSegDist(coords[offset + 0], coords[offset + 1],
 687                                 coords[offset + 4], coords[offset + 5],
 688                                 coords[offset + 2], coords[offset + 3]);
 689     }
 690 
 691     /**
 692      * Returns the square of the flatness, or maximum distance of a
 693      * control point from the line connecting the end points, of this
 694      * {@code QuadCurve2D}.
 695      * @return the square of the flatness of this
 696      *          {@code QuadCurve2D}.
 697      * @since 1.2
 698      */
 699     public double getFlatnessSq() {
 700         return Line2D.ptSegDistSq(getX1(), getY1(),
 701                                   getX2(), getY2(),
 702                                   getCtrlX(), getCtrlY());
 703     }
 704 
 705     /**
 706      * Returns the flatness, or maximum distance of a
 707      * control point from the line connecting the end points, of this
 708      * {@code QuadCurve2D}.
 709      * @return the flatness of this {@code QuadCurve2D}.
 710      * @since 1.2
 711      */
 712     public double getFlatness() {
 713         return Line2D.ptSegDist(getX1(), getY1(),
 714                                 getX2(), getY2(),
 715                                 getCtrlX(), getCtrlY());
 716     }
 717 
 718     /**
 719      * Subdivides this {@code QuadCurve2D} and stores the resulting
 720      * two subdivided curves into the {@code left} and
 721      * {@code right} curve parameters.
 722      * Either or both of the {@code left} and {@code right}
 723      * objects can be the same as this {@code QuadCurve2D} or
 724      * {@code null}.
 725      * @param left the {@code QuadCurve2D} object for storing the
 726      * left or first half of the subdivided curve
 727      * @param right the {@code QuadCurve2D} object for storing the
 728      * right or second half of the subdivided curve
 729      * @since 1.2
 730      */
 731     public void subdivide(QuadCurve2D left, QuadCurve2D right) {
 732         subdivide(this, left, right);
 733     }
 734 
 735     /**
 736      * Subdivides the quadratic curve specified by the {@code src}
 737      * parameter and stores the resulting two subdivided curves into the
 738      * {@code left} and {@code right} curve parameters.
 739      * Either or both of the {@code left} and {@code right}
 740      * objects can be the same as the {@code src} object or
 741      * {@code null}.
 742      * @param src the quadratic curve to be subdivided
 743      * @param left the {@code QuadCurve2D} object for storing the
 744      *          left or first half of the subdivided curve
 745      * @param right the {@code QuadCurve2D} object for storing the
 746      *          right or second half of the subdivided curve
 747      * @since 1.2
 748      */
 749     public static void subdivide(QuadCurve2D src,
 750                                  QuadCurve2D left,
 751                                  QuadCurve2D right) {
 752         double x1 = src.getX1();
 753         double y1 = src.getY1();
 754         double ctrlx = src.getCtrlX();
 755         double ctrly = src.getCtrlY();
 756         double x2 = src.getX2();
 757         double y2 = src.getY2();
 758         double ctrlx1 = (x1 + ctrlx) / 2.0;
 759         double ctrly1 = (y1 + ctrly) / 2.0;
 760         double ctrlx2 = (x2 + ctrlx) / 2.0;
 761         double ctrly2 = (y2 + ctrly) / 2.0;
 762         ctrlx = (ctrlx1 + ctrlx2) / 2.0;
 763         ctrly = (ctrly1 + ctrly2) / 2.0;
 764         if (left != null) {
 765             left.setCurve(x1, y1, ctrlx1, ctrly1, ctrlx, ctrly);
 766         }
 767         if (right != null) {
 768             right.setCurve(ctrlx, ctrly, ctrlx2, ctrly2, x2, y2);
 769         }
 770     }
 771 
 772     /**
 773      * Subdivides the quadratic curve specified by the coordinates
 774      * stored in the {@code src} array at indices
 775      * {@code srcoff} through {@code srcoff}&nbsp;+&nbsp;5
 776      * and stores the resulting two subdivided curves into the two
 777      * result arrays at the corresponding indices.
 778      * Either or both of the {@code left} and {@code right}
 779      * arrays can be {@code null} or a reference to the same array
 780      * and offset as the {@code src} array.
 781      * Note that the last point in the first subdivided curve is the
 782      * same as the first point in the second subdivided curve.  Thus,
 783      * it is possible to pass the same array for {@code left} and
 784      * {@code right} and to use offsets such that
 785      * {@code rightoff} equals {@code leftoff} + 4 in order
 786      * to avoid allocating extra storage for this common point.
 787      * @param src the array holding the coordinates for the source curve
 788      * @param srcoff the offset into the array of the beginning of the
 789      * the 6 source coordinates
 790      * @param left the array for storing the coordinates for the first
 791      * half of the subdivided curve
 792      * @param leftoff the offset into the array of the beginning of the
 793      * the 6 left coordinates
 794      * @param right the array for storing the coordinates for the second
 795      * half of the subdivided curve
 796      * @param rightoff the offset into the array of the beginning of the
 797      * the 6 right coordinates
 798      * @since 1.2
 799      */
 800     public static void subdivide(double src[], int srcoff,
 801                                  double left[], int leftoff,
 802                                  double right[], int rightoff) {
 803         double x1 = src[srcoff + 0];
 804         double y1 = src[srcoff + 1];
 805         double ctrlx = src[srcoff + 2];


 818         y1 = (y1 + ctrly) / 2.0;
 819         x2 = (x2 + ctrlx) / 2.0;
 820         y2 = (y2 + ctrly) / 2.0;
 821         ctrlx = (x1 + x2) / 2.0;
 822         ctrly = (y1 + y2) / 2.0;
 823         if (left != null) {
 824             left[leftoff + 2] = x1;
 825             left[leftoff + 3] = y1;
 826             left[leftoff + 4] = ctrlx;
 827             left[leftoff + 5] = ctrly;
 828         }
 829         if (right != null) {
 830             right[rightoff + 0] = ctrlx;
 831             right[rightoff + 1] = ctrly;
 832             right[rightoff + 2] = x2;
 833             right[rightoff + 3] = y2;
 834         }
 835     }
 836 
 837     /**
 838      * Solves the quadratic whose coefficients are in the {@code eqn}
 839      * array and places the non-complex roots back into the same array,
 840      * returning the number of roots.  The quadratic solved is represented
 841      * by the equation:
 842      * <pre>
 843      *     eqn = {C, B, A};
 844      *     ax^2 + bx + c = 0
 845      * </pre>
 846      * A return value of {@code -1} is used to distinguish a constant
 847      * equation, which might be always 0 or never 0, from an equation that
 848      * has no zeroes.
 849      * @param eqn the array that contains the quadratic coefficients
 850      * @return the number of roots, or {@code -1} if the equation is
 851      *          a constant
 852      * @since 1.2
 853      */
 854     public static int solveQuadratic(double eqn[]) {
 855         return solveQuadratic(eqn, eqn);
 856     }
 857 
 858     /**
 859      * Solves the quadratic whose coefficients are in the {@code eqn}
 860      * array and places the non-complex roots into the {@code res}
 861      * array, returning the number of roots.
 862      * The quadratic solved is represented by the equation:
 863      * <pre>
 864      *     eqn = {C, B, A};
 865      *     ax^2 + bx + c = 0
 866      * </pre>
 867      * A return value of {@code -1} is used to distinguish a constant
 868      * equation, which might be always 0 or never 0, from an equation that
 869      * has no zeroes.
 870      * @param eqn the specified array of coefficients to use to solve
 871      *        the quadratic equation
 872      * @param res the array that contains the non-complex roots
 873      *        resulting from the solution of the quadratic equation
 874      * @return the number of roots, or {@code -1} if the equation is
 875      *  a constant.
 876      * @since 1.3
 877      */
 878     public static int solveQuadratic(double eqn[], double res[]) {
 879         double a = eqn[2];
 880         double b = eqn[1];
 881         double c = eqn[0];
 882         int roots = 0;
 883         if (a == 0.0) {
 884             // The quadratic parabola has degenerated to a line.
 885             if (b == 0.0) {
 886                 // The line has degenerated to a constant.
 887                 return -1;
 888             }
 889             res[roots++] = -c / b;
 890         } else {
 891             // From Numerical Recipes, 5.6, Quadratic and Cubic Equations
 892             double d = b * b - 4.0 * a * c;
 893             if (d < 0.0) {
 894                 // If d < 0.0, then there are no roots


1326     }
1327 
1328     /**
1329      * {@inheritDoc}
1330      * @since 1.2
1331      */
1332     public boolean contains(Rectangle2D r) {
1333         return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
1334     }
1335 
1336     /**
1337      * {@inheritDoc}
1338      * @since 1.2
1339      */
1340     public Rectangle getBounds() {
1341         return getBounds2D().getBounds();
1342     }
1343 
1344     /**
1345      * Returns an iteration object that defines the boundary of the
1346      * shape of this {@code QuadCurve2D}.
1347      * The iterator for this class is not multi-threaded safe,
1348      * which means that this {@code QuadCurve2D} class does not
1349      * guarantee that modifications to the geometry of this
1350      * {@code QuadCurve2D} object do not affect any iterations of
1351      * that geometry that are already in process.
1352      * @param at an optional {@link AffineTransform} to apply to the
1353      *          shape boundary
1354      * @return a {@link PathIterator} object that defines the boundary
1355      *          of the shape.
1356      * @since 1.2
1357      */
1358     public PathIterator getPathIterator(AffineTransform at) {
1359         return new QuadIterator(this, at);
1360     }
1361 
1362     /**
1363      * Returns an iteration object that defines the boundary of the
1364      * flattened shape of this {@code QuadCurve2D}.
1365      * The iterator for this class is not multi-threaded safe,
1366      * which means that this {@code QuadCurve2D} class does not
1367      * guarantee that modifications to the geometry of this
1368      * {@code QuadCurve2D} object do not affect any iterations of
1369      * that geometry that are already in process.
1370      * @param at an optional {@code AffineTransform} to apply
1371      *          to the boundary of the shape
1372      * @param flatness the maximum distance that the control points for a
1373      *          subdivided curve can be with respect to a line connecting
1374      *          the end points of this curve before this curve is
1375      *          replaced by a straight line connecting the end points.
1376      * @return a {@code PathIterator} object that defines the
1377      *          flattened boundary of the shape.
1378      * @since 1.2
1379      */
1380     public PathIterator getPathIterator(AffineTransform at, double flatness) {
1381         return new FlatteningPathIterator(getPathIterator(at), flatness);
1382     }
1383 
1384     /**
1385      * Creates a new object of the same class and with the same contents
1386      * as this object.
1387      *
1388      * @return     a clone of this instance.
1389      * @exception  OutOfMemoryError            if there is not enough memory.
1390      * @see        java.lang.Cloneable
1391      * @since      1.2
1392      */
1393     public Object clone() {
1394         try {
1395             return super.clone();
1396         } catch (CloneNotSupportedException e) {
< prev index next >