/[classpath]/classpath/java/awt/geom/QuadCurve2D.java
ViewVC logotype

Diff of /classpath/java/awt/geom/QuadCurve2D.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.10 by brawer, Mon Jan 5 00:27:39 2004 UTC revision 1.11 by smarothy, Sun Aug 1 22:27:36 2004 UTC
# Line 1  Line 1 
1  /* QuadCurve2D.java -- represents a parameterized quadratic curve in 2-D space  /* QuadCurve2D.java -- represents a parameterized quadratic curve in 2-D space
2     Copyright (C) 2002, 2003 Free Software Foundation     Copyright (C) 2002, 2003, 2004 Free Software Foundation
3    
4  This file is part of GNU Classpath.  This file is part of GNU Classpath.
5    
# Line 35  this exception to your version of the li Line 35  this exception to your version of the li
35  obligated to do so.  If you do not wish to do so, delete this  obligated to do so.  If you do not wish to do so, delete this
36  exception statement from your version. */  exception statement from your version. */
37    
   
38  package java.awt.geom;  package java.awt.geom;
39    
40  import java.awt.Rectangle;  import java.awt.Rectangle;
# Line 53  import java.util.NoSuchElementException; Line 52  import java.util.NoSuchElementException;
52   * @author Eric Blake (ebb9@email.byu.edu)   * @author Eric Blake (ebb9@email.byu.edu)
53   * @author Graydon Hoare (graydon@redhat.com)   * @author Graydon Hoare (graydon@redhat.com)
54   * @author Sascha Brawer (brawer@dandelis.ch)   * @author Sascha Brawer (brawer@dandelis.ch)
55     * @author Sven de Marothy (sven@physto.se)
56   *   *
57   * @since 1.2   * @since 1.2
58   */   */
59  public abstract class QuadCurve2D  public abstract class QuadCurve2D implements Shape, Cloneable
   implements Shape, Cloneable  
60  {  {
61      private static final double BIG_VALUE = java.lang.Double.MAX_VALUE / 10.0;
62    
63    /**    /**
64     * Constructs a new QuadCurve2D. Typical users will want to     * Constructs a new QuadCurve2D. Typical users will want to
65     * construct instances of a subclass, such as {@link     * construct instances of a subclass, such as {@link
# Line 68  public abstract class QuadCurve2D Line 69  public abstract class QuadCurve2D
69    {    {
70    }    }
71    
   
72    /**    /**
73     * Returns the <i>x</i> coordinate of the curve&#x2019;s start     * Returns the <i>x</i> coordinate of the curve&#x2019;s start
74     * point.     * point.
75     */     */
76    public abstract double getX1();    public abstract double getX1();
77    
   
78    /**    /**
79     * Returns the <i>y</i> coordinate of the curve&#x2019;s start     * Returns the <i>y</i> coordinate of the curve&#x2019;s start
80     * point.     * point.
81     */     */
82    public abstract double getY1();    public abstract double getY1();
83    
   
84    /**    /**
85     * Returns the curve&#x2019;s start point.     * Returns the curve&#x2019;s start point.
86     */     */
87    public abstract Point2D getP1();    public abstract Point2D getP1();
88    
   
89    /**    /**
90     * Returns the <i>x</i> coordinate of the curve&#x2019;s control     * Returns the <i>x</i> coordinate of the curve&#x2019;s control
91     * point.     * point.
92     */     */
93    public abstract double getCtrlX();    public abstract double getCtrlX();
94    
   
95    /**    /**
96     * Returns the <i>y</i> coordinate of the curve&#x2019;s control     * Returns the <i>y</i> coordinate of the curve&#x2019;s control
97     * point.     * point.
98     */     */
99    public abstract double getCtrlY();    public abstract double getCtrlY();
100    
   
101    /**    /**
102     * Returns the curve&#x2019;s control point.     * Returns the curve&#x2019;s control point.
103     */     */
104    public abstract Point2D getCtrlPt();    public abstract Point2D getCtrlPt();
105    
   
106    /**    /**
107     * Returns the <i>x</i> coordinate of the curve&#x2019;s end     * Returns the <i>x</i> coordinate of the curve&#x2019;s end
108     * point.     * point.
109     */     */
110    public abstract double getX2();    public abstract double getX2();
111    
   
112    /**    /**
113     * Returns the <i>y</i> coordinate of the curve&#x2019;s end     * Returns the <i>y</i> coordinate of the curve&#x2019;s end
114     * point.     * point.
115     */     */
116    public abstract double getY2();    public abstract double getY2();
117    
   
118    /**    /**
119     * Returns the curve&#x2019;s end point.     * Returns the curve&#x2019;s end point.
120     */     */
121    public abstract Point2D getP2();    public abstract Point2D getP2();
122    
   
123    /**    /**
124     * Changes the curve geometry, separately specifying each coordinate     * Changes the curve geometry, separately specifying each coordinate
125     * value.     * value.
# Line 154  public abstract class QuadCurve2D Line 145  public abstract class QuadCurve2D
145    public abstract void setCurve(double x1, double y1, double cx, double cy,    public abstract void setCurve(double x1, double y1, double cx, double cy,
146                                  double x2, double y2);                                  double x2, double y2);
147    
   
148    /**    /**
149     * Changes the curve geometry, passing coordinate values in an     * Changes the curve geometry, passing coordinate values in an
150     * array.     * array.
# Line 174  public abstract class QuadCurve2D Line 164  public abstract class QuadCurve2D
164     */     */
165    public void setCurve(double[] coords, int offset)    public void setCurve(double[] coords, int offset)
166    {    {
167      setCurve(coords[offset++], coords[offset++],      setCurve(coords[offset++], coords[offset++], coords[offset++],
168               coords[offset++], coords[offset++],               coords[offset++], coords[offset++], coords[offset++]);
              coords[offset++], coords[offset++]);  
169    }    }
170    
   
171    /**    /**
172     * Changes the curve geometry, specifying coordinate values in     * Changes the curve geometry, specifying coordinate values in
173     * separate Point objects.     * separate Point objects.
# Line 198  public abstract class QuadCurve2D Line 186  public abstract class QuadCurve2D
186     */     */
187    public void setCurve(Point2D p1, Point2D c, Point2D p2)    public void setCurve(Point2D p1, Point2D c, Point2D p2)
188    {    {
189      setCurve(p1.getX(), p1.getY(), c.getX(), c.getY(),      setCurve(p1.getX(), p1.getY(), c.getX(), c.getY(), p2.getX(), p2.getY());
              p2.getX(), p2.getY());  
190    }    }
191    
   
192    /**    /**
193     * Changes the curve geometry, specifying coordinate values in an     * Changes the curve geometry, specifying coordinate values in an
194     * array of Point objects.     * array of Point objects.
# Line 223  public abstract class QuadCurve2D Line 209  public abstract class QuadCurve2D
209     */     */
210    public void setCurve(Point2D[] pts, int offset)    public void setCurve(Point2D[] pts, int offset)
211    {    {
212      setCurve(pts[offset].getX(), pts[offset].getY(),      setCurve(pts[offset].getX(), pts[offset].getY(), pts[offset + 1].getX(),
213               pts[offset + 1].getX(), pts[offset + 1].getY(),               pts[offset + 1].getY(), pts[offset + 2].getX(),
214               pts[offset + 2].getX(), pts[offset + 2].getY());               pts[offset + 2].getY());
215    }    }
216    
   
217    /**    /**
218     * Changes the geometry of the curve to that of another curve.     * Changes the geometry of the curve to that of another curve.
219     *     *
# Line 236  public abstract class QuadCurve2D Line 221  public abstract class QuadCurve2D
221     */     */
222    public void setCurve(QuadCurve2D c)    public void setCurve(QuadCurve2D c)
223    {    {
224      setCurve(c.getX1(), c.getY1(), c.getCtrlX(), c.getCtrlY(),      setCurve(c.getX1(), c.getY1(), c.getCtrlX(), c.getCtrlY(), c.getX2(),
225               c.getX2(), c.getY2());               c.getY2());
226    }    }
227    
   
228    /**    /**
229     * Calculates the squared flatness of a quadratic curve, directly     * Calculates the squared flatness of a quadratic curve, directly
230     * specifying each coordinate value. The flatness is the distance of     * specifying each coordinate value. The flatness is the distance of
# Line 267  public abstract class QuadCurve2D Line 251  public abstract class QuadCurve2D
251      return Line2D.ptSegDistSq(x1, y1, x2, y2, cx, cy);      return Line2D.ptSegDistSq(x1, y1, x2, y2, cx, cy);
252    }    }
253    
   
254    /**    /**
255     * Calculates the flatness of a quadratic curve, directly specifying     * Calculates the flatness of a quadratic curve, directly specifying
256     * each coordinate value. The flatness is the distance of the     * each coordinate value. The flatness is the distance of the
# Line 294  public abstract class QuadCurve2D Line 277  public abstract class QuadCurve2D
277      return Line2D.ptSegDist(x1, y1, x2, y2, cx, cy);      return Line2D.ptSegDist(x1, y1, x2, y2, cx, cy);
278    }    }
279    
   
280    /**    /**
281     * Calculates the squared flatness of a quadratic curve, specifying     * Calculates the squared flatness of a quadratic curve, specifying
282     * the coordinate values in an array. The flatness is the distance     * the coordinate values in an array. The flatness is the distance
# Line 328  public abstract class QuadCurve2D Line 310  public abstract class QuadCurve2D
310                                coords[offset + 2], coords[offset + 3]);                                coords[offset + 2], coords[offset + 3]);
311    }    }
312    
   
313    /**    /**
314     * Calculates the flatness of a quadratic curve, specifying the     * Calculates the flatness of a quadratic curve, specifying the
315     * coordinate values in an array. The flatness is the distance of     * coordinate values in an array. The flatness is the distance of
# Line 362  public abstract class QuadCurve2D Line 343  public abstract class QuadCurve2D
343                              coords[offset + 2], coords[offset + 3]);                              coords[offset + 2], coords[offset + 3]);
344    }    }
345    
   
346    /**    /**
347     * Calculates the squared flatness of this curve. The flatness is     * Calculates the squared flatness of this curve. The flatness is
348     * the distance of the control point to the line between start and     * the distance of the control point to the line between start and
# Line 378  public abstract class QuadCurve2D Line 358  public abstract class QuadCurve2D
358     */     */
359    public double getFlatnessSq()    public double getFlatnessSq()
360    {    {
361      return Line2D.ptSegDistSq(getX1(), getY1(),      return Line2D.ptSegDistSq(getX1(), getY1(), getX2(), getY2(), getCtrlX(),
362                                getX2(), getY2(),                                getCtrlY());
                               getCtrlX(), getCtrlY());  
363    }    }
364    
   
365    /**    /**
366     * Calculates the flatness of this curve. The flatness is the     * Calculates the flatness of this curve. The flatness is the
367     * distance of the control point to the line between start and end     * distance of the control point to the line between start and end
# Line 399  public abstract class QuadCurve2D Line 377  public abstract class QuadCurve2D
377     */     */
378    public double getFlatness()    public double getFlatness()
379    {    {
380      return Line2D.ptSegDist(getX1(), getY1(),      return Line2D.ptSegDist(getX1(), getY1(), getX2(), getY2(), getCtrlX(),
381                              getX2(), getY2(),                              getCtrlY());
                             getCtrlX(), getCtrlY());  
382    }    }
383    
   
384    /**    /**
385     * Subdivides this curve into two halves.     * Subdivides this curve into two halves.
386     *     *
# Line 423  public abstract class QuadCurve2D Line 399  public abstract class QuadCurve2D
399    public void subdivide(QuadCurve2D left, QuadCurve2D right)    public void subdivide(QuadCurve2D left, QuadCurve2D right)
400    {    {
401      // Use empty slots at end to share single array.      // Use empty slots at end to share single array.
402      double[] d = new double[] { getX1(), getY1(), getCtrlX(), getCtrlY(),      double[] d = new double[]
403                                  getX2(), getY2(), 0, 0, 0, 0 };                   {
404                       getX1(), getY1(), getCtrlX(), getCtrlY(), getX2(), getY2(),
405                       0, 0, 0, 0
406                     };
407      subdivide(d, 0, d, 0, d, 4);      subdivide(d, 0, d, 0, d, 4);
408      if (left != null)      if (left != null)
409        left.setCurve(d, 0);        left.setCurve(d, 0);
# Line 432  public abstract class QuadCurve2D Line 411  public abstract class QuadCurve2D
411        right.setCurve(d, 4);        right.setCurve(d, 4);
412    }    }
413    
   
414    /**    /**
415     * Subdivides a quadratic curve into two halves.     * Subdivides a quadratic curve into two halves.
416     *     *
# Line 456  public abstract class QuadCurve2D Line 434  public abstract class QuadCurve2D
434      src.subdivide(left, right);      src.subdivide(left, right);
435    }    }
436    
   
437    /**    /**
438     * Subdivides a quadratic curve into two halves, passing all     * Subdivides a quadratic curve into two halves, passing all
439     * coordinates in an array.     * coordinates in an array.
# Line 500  public abstract class QuadCurve2D Line 477  public abstract class QuadCurve2D
477     * index where the start point&#x2019;s <i>x</i> coordinate will be     * index where the start point&#x2019;s <i>x</i> coordinate will be
478     * stored.     * stored.
479     */     */
480    public static void subdivide(double[] src, int srcOff,    public static void subdivide(double[] src, int srcOff, double[] left,
481                                 double[] left, int leftOff,                                 int leftOff, double[] right, int rightOff)
                                double[] right, int rightOff)  
482    {    {
483      double x1, y1, xc, yc, x2, y2;      double x1;
484        double y1;
485        double xc;
486        double yc;
487        double x2;
488        double y2;
489    
490      x1 = src[srcOff];      x1 = src[srcOff];
491      y1 = src[srcOff + 1];      y1 = src[srcOff + 1];
# Line 514  public abstract class QuadCurve2D Line 495  public abstract class QuadCurve2D
495      y2 = src[srcOff + 5];      y2 = src[srcOff + 5];
496    
497      if (left != null)      if (left != null)
498      {        {
499        left[leftOff] = x1;          left[leftOff] = x1;
500        left[leftOff + 1] = y1;          left[leftOff + 1] = y1;
501      }        }
502    
503      if (right != null)      if (right != null)
504      {        {
505        right[rightOff + 4] = x2;          right[rightOff + 4] = x2;
506        right[rightOff + 5] = y2;          right[rightOff + 5] = y2;
507      }        }
508    
509      x1 = (x1 + xc) / 2;      x1 = (x1 + xc) / 2;
510      x2 = (xc + x2) / 2;      x2 = (xc + x2) / 2;
# Line 533  public abstract class QuadCurve2D Line 514  public abstract class QuadCurve2D
514      yc = (y1 + y2) / 2;      yc = (y1 + y2) / 2;
515    
516      if (left != null)      if (left != null)
517      {        {
518        left[leftOff + 2] = x1;          left[leftOff + 2] = x1;
519        left[leftOff + 3] = y1;          left[leftOff + 3] = y1;
520        left[leftOff + 4] = xc;          left[leftOff + 4] = xc;
521        left[leftOff + 5] = yc;          left[leftOff + 5] = yc;
522      }        }
523    
524      if (right != null)      if (right != null)
525      {        {
526        right[rightOff] = xc;          right[rightOff] = xc;
527        right[rightOff + 1] = yc;          right[rightOff + 1] = yc;
528        right[rightOff + 2] = x2;          right[rightOff + 2] = x2;
529        right[rightOff + 3] = y2;          right[rightOff + 3] = y2;
530      }        }
531    }    }
532    
   
533    /**    /**
534     * Finds the non-complex roots of a quadratic equation, placing the     * Finds the non-complex roots of a quadratic equation, placing the
535     * results into the same array as the equation coefficients. The     * results into the same array as the equation coefficients. The
# Line 594  public abstract class QuadCurve2D Line 574  public abstract class QuadCurve2D
574      return solveQuadratic(eqn, eqn);      return solveQuadratic(eqn, eqn);
575    }    }
576    
   
577    /**    /**
578     * Finds the non-complex roots of a quadratic equation. The     * Finds the non-complex roots of a quadratic equation. The
579     * following equation is being solved:     * following equation is being solved:
# Line 649  public abstract class QuadCurve2D Line 628  public abstract class QuadCurve2D
628      // The Java implementation is very similar to the GSL code, but      // The Java implementation is very similar to the GSL code, but
629      // not a strict one-to-one copy. For example, GSL would sort the      // not a strict one-to-one copy. For example, GSL would sort the
630      // result.      // result.
631        double a;
632      double a, b, c, disc;      double b;
633        double c;
634        double disc;
635    
636      c = eqn[0];      c = eqn[0];
637      b = eqn[1];      b = eqn[1];
# Line 661  public abstract class QuadCurve2D Line 642  public abstract class QuadCurve2D
642      // wouldn't return -1 for constant functions, and 2 instead of 1      // wouldn't return -1 for constant functions, and 2 instead of 1
643      // for linear functions.      // for linear functions.
644      if (a == 0)      if (a == 0)
645      {        {
646        if (b == 0)          if (b == 0)
647          return -1;            return -1;
648          
649        res[0] = -c / b;          res[0] = -c / b;
650        return 1;          return 1;
651      }        }
652    
653      disc = b * b - 4 * a * c;      disc = b * b - 4 * a * c;
654    
# Line 675  public abstract class QuadCurve2D Line 656  public abstract class QuadCurve2D
656        return 0;        return 0;
657    
658      if (disc == 0)      if (disc == 0)
659      {        {
660        // The GNU Scientific Library returns two identical results here.          // The GNU Scientific Library returns two identical results here.
661        // We just return one.          // We just return one.
662        res[0] = -0.5 * b / a ;          res[0] = -0.5 * b / a;
663        return 1;          return 1;
664      }        }
665    
666      // disc > 0      // disc > 0
667      if (b == 0)      if (b == 0)
668      {        {
669        double r;          double r;
670    
671        r = Math.abs(0.5 * Math.sqrt(disc) / a);          r = Math.abs(0.5 * Math.sqrt(disc) / a);
672        res[0] = -r;          res[0] = -r;
673        res[1] = r;          res[1] = r;
674      }        }
675      else      else
676      {        {
677        double sgnb, temp;          double sgnb;
678                  double temp;
679        sgnb = (b > 0 ? 1 : -1);  
680        temp = -0.5 * (b + sgnb * Math.sqrt(disc));          sgnb = (b > 0 ? 1 : -1);
681            temp = -0.5 * (b + sgnb * Math.sqrt(disc));
682        // The GNU Scientific Library sorts the result here. We don't.  
683        res[0] = temp / a;          // The GNU Scientific Library sorts the result here. We don't.
684        res[1] = c / temp;          res[0] = temp / a;
685      }          res[1] = c / temp;
686          }
687      return 2;      return 2;
688    }    }
689    
   
690    /**    /**
691     * Determines whether a point lies inside the area that is bounded     * Determines whether a point is inside the area bounded
692     * by the curve and the straight line connecting its end points.     * by the curve and the straight line connecting its end points.
693     *     *
694     * <p><img src="doc-files/QuadCurve2D-5.png" width="350" height="180"     * <p><img src="doc-files/QuadCurve2D-5.png" width="350" height="180"
695     * alt="A drawing of the area spanned by the curve" />     * alt="A drawing of the area spanned by the curve" />
696     *     *
697     * <p>The above drawing illustrates in which area points are     * <p>The above drawing illustrates in which area points are
698     * considered &#x201c;contained&#x201d; in a QuadCurve2D.     * considered &#x201c;inside&#x201d; a QuadCurve2D.
699     */     */
700    public boolean contains(double x, double y)    public boolean contains(double x, double y)
701    {    {
702      // XXX Implement.      if (! getBounds2D().contains(x, y))
703      throw new Error("not implemented");        return false;
   }  
704    
705        return ((getAxisIntersections(x, y, true, BIG_VALUE) & 1) != 0);
706      }
707    
708    /**    /**
709     * Determines whether a point lies inside the area that is bounded     * Determines whether a point is inside the area bounded
710     * by the curve and the straight line connecting its end points.     * by the curve and the straight line connecting its end points.
711     *     *
712     * <p><img src="doc-files/QuadCurve2D-5.png" width="350" height="180"     * <p><img src="doc-files/QuadCurve2D-5.png" width="350" height="180"
713     * alt="A drawing of the area spanned by the curve" />     * alt="A drawing of the area spanned by the curve" />
714     *     *
715     * <p>The above drawing illustrates in which area points are     * <p>The above drawing illustrates in which area points are
716     * considered &#x201c;contained&#x201d; in a QuadCurve2D.     * considered &#x201c;inside&#x201d; a QuadCurve2D.
717     */     */
718    public boolean contains(Point2D p)    public boolean contains(Point2D p)
719    {    {
720      return contains(p.getX(), p.getY());      return contains(p.getX(), p.getY());
721    }    }
722    
723      /**
724       * Determines whether any part of a rectangle is inside the area bounded
725       * by the curve and the straight line connecting its end points.
726       *
727       * <p><img src="doc-files/QuadCurve2D-5.png" width="350" height="180"
728       * alt="A drawing of the area spanned by the curve" />
729       *
730       * <p>The above drawing illustrates in which area points are
731       * considered &#x201c;inside&#x201d; in a CubicCurve2D.
732       */
733    public boolean intersects(double x, double y, double w, double h)    public boolean intersects(double x, double y, double w, double h)
734    {    {
735      // XXX Implement.      if (! getBounds2D().contains(x, y, w, h))
736      throw new Error("not implemented");        return false;
737    }  
738        /* Does any edge intersect? */
739        if (getAxisIntersections(x, y, true, w) != 0 /* top */
740            || getAxisIntersections(x, y + h, true, w) != 0 /* bottom */
741            || getAxisIntersections(x + w, y, false, h) != 0 /* right */
742            || getAxisIntersections(x, y, false, h) != 0) /* left */
743          return true;
744    
745        /* No intersections, is any point inside? */
746        if ((getAxisIntersections(x, y, true, BIG_VALUE) & 1) != 0)
747          return true;
748    
749        return false;
750      }
751    
752      /**
753       * Determines whether any part of a Rectangle2D is inside the area bounded
754       * by the curve and the straight line connecting its end points.
755       * @see #intersects(double, double, double, double)
756       */
757    public boolean intersects(Rectangle2D r)    public boolean intersects(Rectangle2D r)
758    {    {
759      return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());      return intersects(r.getX(), r.getY(), r.getWidth(), r.getHeight());
760    }    }
761    
762      /**
763       * Determines whether a rectangle is entirely inside the area bounded
764       * by the curve and the straight line connecting its end points.
765       *
766       * <p><img src="doc-files/QuadCurve2D-5.png" width="350" height="180"
767       * alt="A drawing of the area spanned by the curve" />
768       *
769       * <p>The above drawing illustrates in which area points are
770       * considered &#x201c;inside&#x201d; a QuadCurve2D.
771       * @see #contains(double, double)
772       */
773    public boolean contains(double x, double y, double w, double h)    public boolean contains(double x, double y, double w, double h)
774    {    {
775      // XXX Implement.      if (! getBounds2D().intersects(x, y, w, h))
776      throw new Error("not implemented");        return false;
777    }  
778        /* Does any edge intersect? */
779        if (getAxisIntersections(x, y, true, w) != 0 /* top */
780            || getAxisIntersections(x, y + h, true, w) != 0 /* bottom */
781            || getAxisIntersections(x + w, y, false, h) != 0 /* right */
782            || getAxisIntersections(x, y, false, h) != 0) /* left */
783          return false;
784    
785        /* No intersections, is any point inside? */
786        if ((getAxisIntersections(x, y, true, BIG_VALUE) & 1) != 0)
787          return true;
788    
789        return false;
790      }
791    
792      /**
793       * Determines whether a Rectangle2D is entirely inside the area that is
794       * bounded by the curve and the straight line connecting its end points.
795       * @see #contains(double, double, double, double)
796       */
797    public boolean contains(Rectangle2D r)    public boolean contains(Rectangle2D r)
798    {    {
799      return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());      return contains(r.getX(), r.getY(), r.getWidth(), r.getHeight());
800    }    }
801    
   
802    /**    /**
803     * Determines the smallest rectangle that encloses the     * Determines the smallest rectangle that encloses the
804     * curve&#x2019;s start, end and control point. As the illustration     * curve&#x2019;s start, end and control point. As the illustration
# Line 780  public abstract class QuadCurve2D Line 814  public abstract class QuadCurve2D
814      return getBounds2D().getBounds();      return getBounds2D().getBounds();
815    }    }
816    
   
817    public PathIterator getPathIterator(final AffineTransform at)    public PathIterator getPathIterator(final AffineTransform at)
818    {    {
819      return new PathIterator()      return new PathIterator()
     {  
       /** Current coordinate. */  
       private int current = 0;  
   
   
       public int getWindingRule()  
       {  
         return WIND_NON_ZERO;  
       }  
   
   
       public boolean isDone()  
       {  
         return current >= 2;  
       }  
   
   
       public void next()  
       {  
         current++;  
       }  
   
   
       public int currentSegment(float[] coords)  
820        {        {
821          int result;          /** Current coordinate. */
822          switch (current)          private int current = 0;
         {  
         case 0:  
           coords[0] = (float) getX1();  
           coords[1] = (float) getY1();  
           result = SEG_MOVETO;  
           break;  
   
         case 1:  
           coords[0] = (float) getCtrlX();  
           coords[1] = (float) getCtrlY();  
           coords[2] = (float) getX2();  
           coords[3] = (float) getY2();  
           result = SEG_QUADTO;  
           break;  
   
         default:  
           throw new NoSuchElementException("quad iterator out of bounds");  
         }  
         if (at != null)  
           at.transform(coords, 0, coords, 0, 2);  
         return result;  
       }  
   
823    
824        public int currentSegment(double[] coords)          public int getWindingRule()
825        {          {
826          int result;            return WIND_NON_ZERO;
827          switch (current)          }
828          {  
829          case 0:          public boolean isDone()
830            coords[0] = getX1();          {
831            coords[1] = getY1();            return current >= 2;
832            result = SEG_MOVETO;          }
833            break;  
834            public void next()
835          case 1:          {
836            coords[0] = getCtrlX();            current++;
837            coords[1] = getCtrlY();          }
838            coords[2] = getX2();  
839            coords[3] = getY2();          public int currentSegment(float[] coords)
840            result = SEG_QUADTO;          {
841            break;            int result;
842              switch (current)
843          default:              {
844            throw new NoSuchElementException("quad iterator out of bounds");              case 0:
845          }                coords[0] = (float) getX1();
846          if (at != null)                coords[1] = (float) getY1();
847            at.transform(coords, 0, coords, 0, 2);                result = SEG_MOVETO;
848          return result;                break;
849        }              case 1:
850      };                coords[0] = (float) getCtrlX();
851                  coords[1] = (float) getCtrlY();
852                  coords[2] = (float) getX2();
853                  coords[3] = (float) getY2();
854                  result = SEG_QUADTO;
855                  break;
856                default:
857                  throw new NoSuchElementException("quad iterator out of bounds");
858                }
859              if (at != null)
860                at.transform(coords, 0, coords, 0, 2);
861              return result;
862            }
863    
864            public int currentSegment(double[] coords)
865            {
866              int result;
867              switch (current)
868                {
869                case 0:
870                  coords[0] = getX1();
871                  coords[1] = getY1();
872                  result = SEG_MOVETO;
873                  break;
874                case 1:
875                  coords[0] = getCtrlX();
876                  coords[1] = getCtrlY();
877                  coords[2] = getX2();
878                  coords[3] = getY2();
879                  result = SEG_QUADTO;
880                  break;
881                default:
882                  throw new NoSuchElementException("quad iterator out of bounds");
883                }
884              if (at != null)
885                at.transform(coords, 0, coords, 0, 2);
886              return result;
887            }
888          };
889    }    }
890    
   
891    public PathIterator getPathIterator(AffineTransform at, double flatness)    public PathIterator getPathIterator(AffineTransform at, double flatness)
892    {    {
893      return new FlatteningPathIterator(getPathIterator(at), flatness);      return new FlatteningPathIterator(getPathIterator(at), flatness);
894    }    }
895    
   
896    /**    /**
897     * Creates a new curve with the same contents as this one.     * Creates a new curve with the same contents as this one.
898     *     *
# Line 879  public abstract class QuadCurve2D Line 901  public abstract class QuadCurve2D
901    public Object clone()    public Object clone()
902    {    {
903      try      try
904      {        {
905        return super.clone();          return super.clone();
906      }        }
907      catch (CloneNotSupportedException e)      catch (CloneNotSupportedException e)
908      {        {
909        throw (Error) new InternalError().initCause(e); // Impossible          throw (Error) new InternalError().initCause(e); // Impossible
910      }        }
911    }    }
912    
913      /**
914       * Helper method used by contains() and intersects() methods
915       * Return the number of curve/line intersections on a given axis
916       * extending from a certain point. useYaxis is true for using the Y axis,
917       * @param x x coordinate of the origin point
918       * @param y y coordinate of the origin point
919       * @param useYaxis axis to follow, if true the positive Y axis is used,
920       * false uses the positive X axis.
921       *
922       * This is an implementation of the line-crossings algorithm,
923       * Detailed in an article on Eric Haines' page:
924       * http://www.acm.org/tog/editors/erich/ptinpoly/
925       */
926      private int getAxisIntersections(double x, double y, boolean useYaxis,
927                                       double distance)
928      {
929        int nCrossings = 0;
930        double a0;
931        double a1;
932        double a2;
933        double b0;
934        double b1;
935        double b2;
936        double[] r = new double[3];
937        int nRoots;
938    
939        a0 = a2 = 0.0;
940    
941        if (useYaxis)
942          {
943            a0 = getY1() - y;
944            a1 = getCtrlY() - y;
945            a2 = getY2() - y;
946            b0 = getX1() - x;
947            b1 = getCtrlX() - x;
948            b2 = getX2() - x;
949          }
950        else
951          {
952            a0 = getX1() - x;
953            a1 = getCtrlX() - x;
954            a2 = getX2() - x;
955            b0 = getY1() - y;
956            b1 = getCtrlY() - y;
957            b2 = getY2() - y;
958          }
959    
960        /* If the axis intersects a start/endpoint, shift it up by some small
961           amount to guarantee the line is 'inside'
962           If this is not done,bad behaviour may result for points on that axis. */
963        if (a0 == 0.0 || a2 == 0.0)
964          {
965            double small = getFlatness() * (1E-10);
966            if (a0 == 0.0)
967              a0 += small;
968    
969            if (a2 == 0.0)
970              a2 += small;
971          }
972    
973        r[0] = a0;
974        r[1] = 2 * (a1 - a0);
975        r[2] = (a2 - 2 * a1 + a0);
976    
977        nRoots = solveQuadratic(r);
978        for (int i = 0; i < nRoots; i++)
979          {
980            double t = r[i];
981            if (t >= 0.0 && t <= 1.0)
982              {
983                double crossing = t * t * (b2 - 2 * b1 + b0) + 2 * t * (b1 - b0)
984                                  + b0;
985                /* single root is always doubly degenerate in quads */
986                if (crossing > 0 && crossing < distance)
987                  nCrossings += (nRoots == 1) ? 2 : 1;
988              }
989          }
990    
991        if (useYaxis)
992          {
993            if (Line2D.linesIntersect(b0, a0, b2, a2, 0.0, 0.0, distance, 0.0))
994              nCrossings++;
995          }
996        else
997          {
998            if (Line2D.linesIntersect(a0, b0, a2, b2, 0.0, 0.0, 0.0, distance))
999              nCrossings++;
1000          }
1001    
1002        return (nCrossings);
1003      }
1004    
1005    /**    /**
1006     * A two-dimensional curve that is parameterized with a quadratic     * A two-dimensional curve that is parameterized with a quadratic
# Line 899  public abstract class QuadCurve2D Line 1012  public abstract class QuadCurve2D
1012     * @author Eric Blake (ebb9@email.byu.edu)     * @author Eric Blake (ebb9@email.byu.edu)
1013     * @author Sascha Brawer (brawer@dandelis.ch)     * @author Sascha Brawer (brawer@dandelis.ch)
1014     */     */
1015    public static class Double    public static class Double extends QuadCurve2D
     extends QuadCurve2D  
1016    {    {
1017      /**      /**
1018       * The <i>x</i> coordinate of the curve&#x2019;s start point.       * The <i>x</i> coordinate of the curve&#x2019;s start point.
1019       */       */
1020      public double x1;      public double x1;
1021    
   
1022      /**      /**
1023       * The <i>y</i> coordinate of the curve&#x2019;s start point.       * The <i>y</i> coordinate of the curve&#x2019;s start point.
1024       */       */
1025      public double y1;      public double y1;
1026    
   
1027      /**      /**
1028       * The <i>x</i> coordinate of the curve&#x2019;s control point.       * The <i>x</i> coordinate of the curve&#x2019;s control point.
1029       */       */
1030      public double ctrlx;      public double ctrlx;
1031    
   
1032      /**      /**
1033       * The <i>y</i> coordinate of the curve&#x2019;s control point.       * The <i>y</i> coordinate of the curve&#x2019;s control point.
1034       */       */
1035      public double ctrly;      public double ctrly;
1036    
   
1037      /**      /**
1038       * The <i>x</i> coordinate of the curve&#x2019;s end point.       * The <i>x</i> coordinate of the curve&#x2019;s end point.
1039       */       */
1040      public double x2;      public double x2;
1041    
   
1042      /**      /**
1043       * The <i>y</i> coordinate of the curve&#x2019;s end point.       * The <i>y</i> coordinate of the curve&#x2019;s end point.
1044       */       */
1045      public double y2;      public double y2;
1046    
   
1047      /**      /**
1048       * Constructs a new QuadCurve2D that stores its coordinate values       * Constructs a new QuadCurve2D that stores its coordinate values
1049       * in double-precision floating-point format. All points are       * in double-precision floating-point format. All points are
# Line 947  public abstract class QuadCurve2D Line 1053  public abstract class QuadCurve2D
1053      {      {
1054      }      }
1055    
   
1056      /**      /**
1057       * Constructs a new QuadCurve2D that stores its coordinate values       * Constructs a new QuadCurve2D that stores its coordinate values
1058       * in double-precision floating-point format, specifying the       * in double-precision floating-point format, specifying the
# Line 971  public abstract class QuadCurve2D Line 1076  public abstract class QuadCurve2D
1076       * @param y2 the <i>y</i> coordinate of the curve&#x2019;s end       * @param y2 the <i>y</i> coordinate of the curve&#x2019;s end
1077       * point.       * point.
1078       */       */
1079      public Double(double x1, double y1, double cx, double cy,      public Double(double x1, double y1, double cx, double cy, double x2,
1080                    double x2, double y2)                    double y2)
1081      {      {
1082        this.x1 = x1;        this.x1 = x1;
1083        this.y1 = y1;        this.y1 = y1;
# Line 982  public abstract class QuadCurve2D Line 1087  public abstract class QuadCurve2D
1087        this.y2 = y2;        this.y2 = y2;
1088      }      }
1089    
   
1090      /**      /**
1091       * Returns the <i>x</i> coordinate of the curve&#x2019;s start       * Returns the <i>x</i> coordinate of the curve&#x2019;s start
1092       * point.       * point.
# Line 992  public abstract class QuadCurve2D Line 1096  public abstract class QuadCurve2D
1096        return x1;        return x1;
1097      }      }
1098    
   
1099      /**      /**
1100       * Returns the <i>y</i> coordinate of the curve&#x2019;s start       * Returns the <i>y</i> coordinate of the curve&#x2019;s start
1101       * point.       * point.
# Line 1002  public abstract class QuadCurve2D Line 1105  public abstract class QuadCurve2D
1105        return y1;        return y1;
1106      }      }
1107    
   
1108      /**      /**
1109       * Returns the curve&#x2019;s start point.       * Returns the curve&#x2019;s start point.
1110       */       */
# Line 1011  public abstract class QuadCurve2D Line 1113  public abstract class QuadCurve2D
1113        return new Point2D.Double(x1, y1);        return new Point2D.Double(x1, y1);
1114      }      }
1115    
   
1116      /**      /**
1117       * Returns the <i>x</i> coordinate of the curve&#x2019;s control       * Returns the <i>x</i> coordinate of the curve&#x2019;s control
1118       * point.       * point.
# Line 1021  public abstract class QuadCurve2D Line 1122  public abstract class QuadCurve2D
1122        return ctrlx;        return ctrlx;
1123      }      }
1124    
   
1125      /**      /**
1126       * Returns the <i>y</i> coordinate of the curve&#x2019;s control       * Returns the <i>y</i> coordinate of the curve&#x2019;s control
1127       * point.       * point.
# Line 1031  public abstract class QuadCurve2D Line 1131  public abstract class QuadCurve2D
1131        return ctrly;        return ctrly;
1132      }      }
1133    
   
1134      /**      /**
1135       * Returns the curve&#x2019;s control point.       * Returns the curve&#x2019;s control point.
1136       */       */
# Line 1040  public abstract class QuadCurve2D Line 1139  public abstract class QuadCurve2D
1139        return new Point2D.Double(ctrlx, ctrly);        return new Point2D.Double(ctrlx, ctrly);
1140      }      }
1141    
   
1142      /**      /**
1143       * Returns the <i>x</i> coordinate of the curve&#x2019;s end       * Returns the <i>x</i> coordinate of the curve&#x2019;s end
1144       * point.       * point.
# Line 1050  public abstract class QuadCurve2D Line 1148  public abstract class QuadCurve2D
1148        return x2;        return x2;
1149      }      }
1150    
   
1151      /**      /**
1152       * Returns the <i>y</i> coordinate of the curve&#x2019;s end       * Returns the <i>y</i> coordinate of the curve&#x2019;s end
1153       * point.       * point.
# Line 1060  public abstract class QuadCurve2D Line 1157  public abstract class QuadCurve2D
1157        return y2;        return y2;
1158      }      }
1159    
   
1160      /**      /**
1161       * Returns the curve&#x2019;s end point.       * Returns the curve&#x2019;s end point.
1162       */       */
# Line 1069  public abstract class QuadCurve2D Line 1165  public abstract class QuadCurve2D
1165        return new Point2D.Double(x2, y2);        return new Point2D.Double(x2, y2);
1166      }      }
1167    
   
1168      /**      /**
1169       * Changes the geometry of the curve.       * Changes the geometry of the curve.
1170       *       *
# Line 1102  public abstract class QuadCurve2D Line 1197  public abstract class QuadCurve2D
1197        this.y2 = y2;        this.y2 = y2;
1198      }      }
1199    
   
1200      /**      /**
1201       * Determines the smallest rectangle that encloses the       * Determines the smallest rectangle that encloses the
1202       * curve&#x2019;s start, end and control point. As the       * curve&#x2019;s start, end and control point. As the
# Line 1123  public abstract class QuadCurve2D Line 1217  public abstract class QuadCurve2D
1217      }      }
1218    }    }
1219    
   
1220    /**    /**
1221     * A two-dimensional curve that is parameterized with a quadratic     * A two-dimensional curve that is parameterized with a quadratic
1222     * function and stores coordinate values in single-precision     * function and stores coordinate values in single-precision
# Line 1134  public abstract class QuadCurve2D Line 1227  public abstract class QuadCurve2D
1227     * @author Eric Blake (ebb9@email.byu.edu)     * @author Eric Blake (ebb9@email.byu.edu)
1228     * @author Sascha Brawer (brawer@dandelis.ch)     * @author Sascha Brawer (brawer@dandelis.ch)
1229     */     */
1230    public static class Float    public static class Float extends QuadCurve2D
     extends QuadCurve2D  
1231    {    {
1232      /**      /**
1233       * The <i>x</i> coordinate of the curve&#x2019;s start point.       * The <i>x</i> coordinate of the curve&#x2019;s start point.
1234       */       */
1235      public float x1;      public float x1;
1236    
   
1237      /**      /**
1238       * The <i>y</i> coordinate of the curve&#x2019;s start point.       * The <i>y</i> coordinate of the curve&#x2019;s start point.
1239       */       */
1240      public float y1;      public float y1;
1241    
   
1242      /**      /**
1243       * The <i>x</i> coordinate of the curve&#x2019;s control point.       * The <i>x</i> coordinate of the curve&#x2019;s control point.
1244       */       */
1245      public float ctrlx;      public float ctrlx;
1246    
   
1247      /**      /**
1248       * The <i>y</i> coordinate of the curve&#x2019;s control point.       * The <i>y</i> coordinate of the curve&#x2019;s control point.
1249       */       */
1250      public float ctrly;      public float ctrly;
1251    
   
1252      /**      /**
1253       * The <i>x</i> coordinate of the curve&#x2019;s end point.       * The <i>x</i> coordinate of the curve&#x2019;s end point.
1254       */       */
1255      public float x2;      public float x2;
1256    
   
1257      /**      /**
1258       * The <i>y</i> coordinate of the curve&#x2019;s end point.       * The <i>y</i> coordinate of the curve&#x2019;s end point.
1259       */       */
1260      public float y2;      public float y2;
1261    
   
1262      /**      /**
1263       * Constructs a new QuadCurve2D that stores its coordinate values       * Constructs a new QuadCurve2D that stores its coordinate values
1264       * in single-precision floating-point format. All points are       * in single-precision floating-point format. All points are
# Line 1182  public abstract class QuadCurve2D Line 1268  public abstract class QuadCurve2D
1268      {      {
1269      }      }
1270    
   
1271      /**      /**
1272       * Constructs a new QuadCurve2D that stores its coordinate values       * Constructs a new QuadCurve2D that stores its coordinate values
1273       * in single-precision floating-point format, specifying the       * in single-precision floating-point format, specifying the
# Line 1206  public abstract class QuadCurve2D Line 1291  public abstract class QuadCurve2D
1291       * @param y2 the <i>y</i> coordinate of the curve&#x2019;s end       * @param y2 the <i>y</i> coordinate of the curve&#x2019;s end
1292       * point.       * point.
1293       */       */
1294      public Float(float x1, float y1, float cx, float cy,      public Float(float x1, float y1, float cx, float cy, float x2, float y2)
                  float x2, float y2)  
1295      {      {
1296        this.x1 = x1;        this.x1 = x1;
1297        this.y1 = y1;        this.y1 = y1;
# Line 1217  public abstract class QuadCurve2D Line 1301  public abstract class QuadCurve2D
1301        this.y2 = y2;        this.y2 = y2;
1302      }      }
1303    
   
1304      /**      /**
1305       * Returns the <i>x</i> coordinate of the curve&#x2019;s start       * Returns the <i>x</i> coordinate of the curve&#x2019;s start
1306       * point.       * point.
# Line 1227  public abstract class QuadCurve2D Line 1310  public abstract class QuadCurve2D
1310        return x1;        return x1;
1311      }      }
1312    
   
1313      /**      /**
1314       * Returns the <i>y</i> coordinate of the curve&#x2019;s start       * Returns the <i>y</i> coordinate of the curve&#x2019;s start
1315       * point.       * point.
# Line 1237  public abstract class QuadCurve2D Line 1319  public abstract class QuadCurve2D
1319        return y1;        return y1;
1320      }      }
1321    
   
1322      /**      /**
1323       * Returns the curve&#x2019;s start point.       * Returns the curve&#x2019;s start point.
1324       */       */
# Line 1246  public abstract class QuadCurve2D Line 1327  public abstract class QuadCurve2D
1327        return new Point2D.Float(x1, y1);        return new Point2D.Float(x1, y1);
1328      }      }
1329    
   
1330      /**      /**
1331       * Returns the <i>x</i> coordinate of the curve&#x2019;s control       * Returns the <i>x</i> coordinate of the curve&#x2019;s control
1332       * point.       * point.
# Line 1256  public abstract class QuadCurve2D Line 1336  public abstract class QuadCurve2D
1336        return ctrlx;        return ctrlx;
1337      }      }
1338    
   
1339      /**      /**
1340       * Returns the <i>y</i> coordinate of the curve&#x2019;s control       * Returns the <i>y</i> coordinate of the curve&#x2019;s control
1341       * point.       * point.
# Line 1266  public abstract class QuadCurve2D Line 1345  public abstract class QuadCurve2D
1345        return ctrly;        return ctrly;
1346      }      }
1347    
   
1348      /**      /**
1349       * Returns the curve&#x2019;s control point.       * Returns the curve&#x2019;s control point.
1350       */       */
# Line 1275  public abstract class QuadCurve2D Line 1353  public abstract class QuadCurve2D
1353        return new Point2D.Float(ctrlx, ctrly);        return new Point2D.Float(ctrlx, ctrly);
1354      }      }
1355    
   
1356      /**      /**
1357       * Returns the <i>x</i> coordinate of the curve&#x2019;s end       * Returns the <i>x</i> coordinate of the curve&#x2019;s end
1358       * point.       * point.
# Line 1285  public abstract class QuadCurve2D Line 1362  public abstract class QuadCurve2D
1362        return x2;        return x2;
1363      }      }
1364    
   
1365      /**      /**
1366       * Returns the <i>y</i> coordinate of the curve&#x2019;s end       * Returns the <i>y</i> coordinate of the curve&#x2019;s end
1367       * point.       * point.
# Line 1295  public abstract class QuadCurve2D Line 1371  public abstract class QuadCurve2D
1371        return y2;        return y2;
1372      }      }
1373    
   
1374      /**      /**
1375       * Returns the curve&#x2019;s end point.       * Returns the curve&#x2019;s end point.
1376       */       */
# Line 1304  public abstract class QuadCurve2D Line 1379  public abstract class QuadCurve2D
1379        return new Point2D.Float(x2, y2);        return new Point2D.Float(x2, y2);
1380      }      }
1381    
   
1382      /**      /**
1383       * Changes the geometry of the curve, specifying coordinate values       * Changes the geometry of the curve, specifying coordinate values
1384       * as double-precision floating-point numbers.       * as double-precision floating-point numbers.
# Line 1338  public abstract class QuadCurve2D Line 1412  public abstract class QuadCurve2D
1412        this.y2 = (float) y2;        this.y2 = (float) y2;
1413      }      }
1414    
   
1415      /**      /**
1416       * Changes the geometry of the curve, specifying coordinate values       * Changes the geometry of the curve, specifying coordinate values
1417       * as single-precision floating-point numbers.       * as single-precision floating-point numbers.
# Line 1361  public abstract class QuadCurve2D Line 1434  public abstract class QuadCurve2D
1434       * @param y2 the <i>y</i> coordinate of the curve&#x2019;s new       * @param y2 the <i>y</i> coordinate of the curve&#x2019;s new
1435       * end point.       * end point.
1436       */       */
1437      public void setCurve(float x1, float y1, float cx, float cy,      public void setCurve(float x1, float y1, float cx, float cy, float x2,
1438                           float x2, float y2)                           float y2)
1439      {      {
1440        this.x1 = x1;        this.x1 = x1;
1441        this.y1 = y1;        this.y1 = y1;
# Line 1372  public abstract class QuadCurve2D Line 1445  public abstract class QuadCurve2D
1445        this.y2 = y2;        this.y2 = y2;
1446      }      }
1447    
   
1448      /**      /**
1449       * Determines the smallest rectangle that encloses the       * Determines the smallest rectangle that encloses the
1450       * curve&#x2019;s start, end and control point. As the       * curve&#x2019;s start, end and control point. As the

Legend:
Removed from v.1.10  
changed lines
  Added in v.1.11

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26