< prev index next >

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

Print this page


   1 /*
   2  * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  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


 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     /**


 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];
 806         double ctrly = src[srcoff + 3];
 807         double x2 = src[srcoff + 4];
 808         double y2 = src[srcoff + 5];
 809         if (left != null) {
 810             left[leftoff + 0] = x1;
 811             left[leftoff + 1] = y1;
 812         }
 813         if (right != null) {
 814             right[rightoff + 4] = x2;
 815             right[rightoff + 5] = y2;
 816         }
 817         x1 = (x1 + ctrlx) / 2.0;
 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;


 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
 895                 return 0;
 896             }
 897             d = Math.sqrt(d);
 898             // For accuracy, calculate one root using:


1019      * {@inheritDoc}
1020      * @since 1.2
1021      */
1022     public boolean contains(Point2D p) {
1023         return contains(p.getX(), p.getY());
1024     }
1025 
1026     /**
1027      * Fill an array with the coefficients of the parametric equation
1028      * in t, ready for solving against val with solveQuadratic.
1029      * We currently have:
1030      *     val = Py(t) = C1*(1-t)^2 + 2*CP*t*(1-t) + C2*t^2
1031      *                 = C1 - 2*C1*t + C1*t^2 + 2*CP*t - 2*CP*t^2 + C2*t^2
1032      *                 = C1 + (2*CP - 2*C1)*t + (C1 - 2*CP + C2)*t^2
1033      *               0 = (C1 - val) + (2*CP - 2*C1)*t + (C1 - 2*CP + C2)*t^2
1034      *               0 = C + Bt + At^2
1035      *     C = C1 - val
1036      *     B = 2*CP - 2*C1
1037      *     A = C1 - 2*CP + C2
1038      */
1039     private static void fillEqn(double eqn[], double val,
1040                                 double c1, double cp, double c2) {
1041         eqn[0] = c1 - val;
1042         eqn[1] = cp + cp - c1 - c1;
1043         eqn[2] = c1 - cp - cp + c2;
1044         return;
1045     }
1046 
1047     /**
1048      * Evaluate the t values in the first num slots of the vals[] array
1049      * and place the evaluated values back into the same array.  Only
1050      * evaluate t values that are within the range &lt;0, 1&gt;, including
1051      * the 0 and 1 ends of the range iff the include0 or include1
1052      * booleans are true.  If an "inflection" equation is handed in,
1053      * then any points which represent a point of inflection for that
1054      * quadratic equation are also ignored.
1055      */
1056     private static int evalQuadratic(double vals[], int num,
1057                                      boolean include0,
1058                                      boolean include1,
1059                                      double inflect[],
1060                                      double c1, double ctrl, double c2) {
1061         int j = 0;
1062         for (int i = 0; i < num; i++) {
1063             double t = vals[i];
1064             if ((include0 ? t >= 0 : t > 0) &&
1065                 (include1 ? t <= 1 : t < 1) &&
1066                 (inflect == null ||
1067                  inflect[1] + 2*inflect[2]*t != 0))
1068             {
1069                 double u = 1 - t;
1070                 vals[j++] = c1*u*u + 2*ctrl*t*u + c2*t*t;
1071             }
1072         }
1073         return j;
1074     }
1075 
1076     private static final int BELOW = -2;
1077     private static final int LOWEDGE = -1;
1078     private static final int INSIDE = 0;
1079     private static final int HIGHEDGE = 1;


   1 /*
   2  * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  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


 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     /**


 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];
 806         double ctrly = src[srcoff + 3];
 807         double x2 = src[srcoff + 4];
 808         double y2 = src[srcoff + 5];
 809         if (left != null) {
 810             left[leftoff + 0] = x1;
 811             left[leftoff + 1] = y1;
 812         }
 813         if (right != null) {
 814             right[rightoff + 4] = x2;
 815             right[rightoff + 5] = y2;
 816         }
 817         x1 = (x1 + ctrlx) / 2.0;
 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;


 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
 895                 return 0;
 896             }
 897             d = Math.sqrt(d);
 898             // For accuracy, calculate one root using:


1019      * {@inheritDoc}
1020      * @since 1.2
1021      */
1022     public boolean contains(Point2D p) {
1023         return contains(p.getX(), p.getY());
1024     }
1025 
1026     /**
1027      * Fill an array with the coefficients of the parametric equation
1028      * in t, ready for solving against val with solveQuadratic.
1029      * We currently have:
1030      *     val = Py(t) = C1*(1-t)^2 + 2*CP*t*(1-t) + C2*t^2
1031      *                 = C1 - 2*C1*t + C1*t^2 + 2*CP*t - 2*CP*t^2 + C2*t^2
1032      *                 = C1 + (2*CP - 2*C1)*t + (C1 - 2*CP + C2)*t^2
1033      *               0 = (C1 - val) + (2*CP - 2*C1)*t + (C1 - 2*CP + C2)*t^2
1034      *               0 = C + Bt + At^2
1035      *     C = C1 - val
1036      *     B = 2*CP - 2*C1
1037      *     A = C1 - 2*CP + C2
1038      */
1039     private static void fillEqn(double[] eqn, double val,
1040                                 double c1, double cp, double c2) {
1041         eqn[0] = c1 - val;
1042         eqn[1] = cp + cp - c1 - c1;
1043         eqn[2] = c1 - cp - cp + c2;
1044         return;
1045     }
1046 
1047     /**
1048      * Evaluate the t values in the first num slots of the vals[] array
1049      * and place the evaluated values back into the same array.  Only
1050      * evaluate t values that are within the range &lt;0, 1&gt;, including
1051      * the 0 and 1 ends of the range iff the include0 or include1
1052      * booleans are true.  If an "inflection" equation is handed in,
1053      * then any points which represent a point of inflection for that
1054      * quadratic equation are also ignored.
1055      */
1056     private static int evalQuadratic(double[] vals, int num,
1057                                      boolean include0,
1058                                      boolean include1,
1059                                      double[] inflect,
1060                                      double c1, double ctrl, double c2) {
1061         int j = 0;
1062         for (int i = 0; i < num; i++) {
1063             double t = vals[i];
1064             if ((include0 ? t >= 0 : t > 0) &&
1065                 (include1 ? t <= 1 : t < 1) &&
1066                 (inflect == null ||
1067                  inflect[1] + 2*inflect[2]*t != 0))
1068             {
1069                 double u = 1 - t;
1070                 vals[j++] = c1*u*u + 2*ctrl*t*u + c2*t*t;
1071             }
1072         }
1073         return j;
1074     }
1075 
1076     private static final int BELOW = -2;
1077     private static final int LOWEDGE = -1;
1078     private static final int INSIDE = 0;
1079     private static final int HIGHEDGE = 1;


< prev index next >