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> + 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} + 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) {
|