Beispiel #1
0
 public CurveLink(Curve curve, double ystart, double yend, int etag)
 {
     _curve = curve;
     _ytop = ystart;
     _ybot = yend;
     _etag = etag;
     if (_ytop < curve.GetYTop() || _ybot > curve.GetYBot())
     {
         throw new SystemException("bad curvelink [" + _ytop + "=>" + _ybot + "] for " + curve);
     }
 }
Beispiel #2
0
 public bool Absorb(Curve curve, double ystart, double yend, int etag)
 {
     if (_curve != curve || _etag != etag ||
             _ybot < ystart || _ytop > yend)
     {
         return false;
     }
     if (ystart < curve.GetYTop() || yend > curve.GetYBot())
     {
         throw new SystemException("bad curvelink [" + ystart + "=>" + yend + "] for " + curve);
     }
     _ytop = Math.Min(_ytop, ystart);
     _ybot = Math.Max(_ybot, yend);
     return true;
 }
Beispiel #3
0
        public bool FindIntersect(Curve that, double[] yrange, double ymin,
                int slevel, int tlevel,
                double s0, double xs0, double ys0,
                double s1, double xs1, double ys1,
                double t0, double xt0, double yt0,
                double t1, double xt1, double yt1)
        {
            /*
            string pad = "        ";
            pad = pad+pad+pad+pad+pad;
            pad = pad+pad;
            System.out.println("----------------------------------------------");
            System.out.println(pad.substring(0, slevel)+ys0);
            System.out.println(pad.substring(0, slevel)+ys1);
            System.out.println(pad.substring(0, slevel)+(s1-s0));
            System.out.println("-------");
            System.out.println(pad.substring(0, tlevel)+yt0);
            System.out.println(pad.substring(0, tlevel)+yt1);
            System.out.println(pad.substring(0, tlevel)+(t1-t0));
             */
            if (ys0 > yt1 || yt0 > ys1)
            {
                return false;
            }
            if (Math.Min(xs0, xs1) > Math.Max(xt0, xt1) ||
                    Math.Max(xs0, xs1) < Math.Min(xt0, xt1))
            {
                return false;
            }
            // Bounding boxes intersect - back off the larger of
            // the two subcurves by half until they stop intersecting
            // (or until they get small enough to switch to a more
            //  intensive algorithm).
            if (s1 - s0 > TMIN)
            {
                double s = (s0 + s1) / 2;
                double xs = XforT(s);
                double ys = YforT(s);
                if (s == s0 || s == s1)
                {

                    throw new SystemException("no s progress!");
                }
                if (t1 - t0 > TMIN)
                {
                    double t = (t0 + t1) / 2;
                    double xt = that.XforT(t);
                    double yt = that.YforT(t);
                    if (t == t0 || t == t1)
                    {

                        throw new SystemException("no t progress!");
                    }
                    if (ys >= yt0 && yt >= ys0)
                    {
                        if (FindIntersect(that, yrange, ymin, slevel + 1, tlevel + 1,
                                s0, xs0, ys0, s, xs, ys,
                                t0, xt0, yt0, t, xt, yt))
                        {
                            return true;
                        }
                    }
                    if (ys >= yt)
                    {
                        if (FindIntersect(that, yrange, ymin, slevel + 1, tlevel + 1,
                                s0, xs0, ys0, s, xs, ys,
                                t, xt, yt, t1, xt1, yt1))
                        {
                            return true;
                        }
                    }
                    if (yt >= ys)
                    {
                        if (FindIntersect(that, yrange, ymin, slevel + 1, tlevel + 1,
                                s, xs, ys, s1, xs1, ys1,
                                t0, xt0, yt0, t, xt, yt))
                        {
                            return true;
                        }
                    }
                    if (ys1 >= yt && yt1 >= ys)
                    {
                        if (FindIntersect(that, yrange, ymin, slevel + 1, tlevel + 1,
                                s, xs, ys, s1, xs1, ys1,
                                t, xt, yt, t1, xt1, yt1))
                        {
                            return true;
                        }
                    }
                }
                else
                {
                    if (ys >= yt0)
                    {
                        if (FindIntersect(that, yrange, ymin, slevel + 1, tlevel,
                                s0, xs0, ys0, s, xs, ys,
                                t0, xt0, yt0, t1, xt1, yt1))
                        {
                            return true;
                        }
                    }
                    if (yt1 >= ys)
                    {
                        if (FindIntersect(that, yrange, ymin, slevel + 1, tlevel,
                                s, xs, ys, s1, xs1, ys1,
                                t0, xt0, yt0, t1, xt1, yt1))
                        {
                            return true;
                        }
                    }
                }
            }
            else if (t1 - t0 > TMIN)
            {
                double t = (t0 + t1) / 2;
                double xt = that.XforT(t);
                double yt = that.YforT(t);
                if (t == t0 || t == t1)
                {

                    throw new SystemException("no t progress!");
                }
                if (yt >= ys0)
                {
                    if (FindIntersect(that, yrange, ymin, slevel, tlevel + 1,
                            s0, xs0, ys0, s1, xs1, ys1,
                            t0, xt0, yt0, t, xt, yt))
                    {
                        return true;
                    }
                }
                if (ys1 >= yt)
                {
                    if (FindIntersect(that, yrange, ymin, slevel, tlevel + 1,
                            s0, xs0, ys0, s1, xs1, ys1,
                            t, xt, yt, t1, xt1, yt1))
                    {
                        return true;
                    }
                }
            }
            else
            {
                // No more subdivisions
                double xlk = xs1 - xs0;
                double ylk = ys1 - ys0;
                double xnm = xt1 - xt0;
                double ynm = yt1 - yt0;
                double xmk = xt0 - xs0;
                double ymk = yt0 - ys0;
                double det = xnm * ylk - ynm * xlk;
                if (det != 0)
                {
                    double detinv = 1 / det;
                    double s = (xnm * ymk - ynm * xmk) * detinv;
                    double t = (xlk * ymk - ylk * xmk) * detinv;
                    if (s >= 0 && s <= 1 && t >= 0 && t <= 1)
                    {
                        s = s0 + s * (s1 - s0);
                        t = t0 + t * (t1 - t0);
                        if (s < 0 || s > 1 || t < 0 || t > 1)
                        {

                        }
                        double y = (YforT(s) + that.YforT(t)) / 2;
                        if (y <= yrange[1] && y > yrange[0])
                        {
                            yrange[1] = y;
                            return true;
                        }
                    }
                }
                //System.out.println("Testing lines!");
            }
            return false;
        }
Beispiel #4
0
        public int CompareTo(Curve that, double[] yrange)
        {
            /*
            System.out.println(this+".compareTo("+that+")");
            System.out.println("target range = "+yrange[0]+"=>"+yrange[1]);
             */
            double y0 = yrange[0];
            double y1 = yrange[1];
            y1 = Math.Min(Math.Min(y1, GetYBot()), that.GetYBot());
            if (y1 <= yrange[0])
            {
                throw new SystemException("backstepping from " + yrange[0] + " to " + y1);
            }
            yrange[1] = y1;
            if (GetXMax() <= that.GetXMin())
            {
                if (GetXMin() == that.GetXMax())
                {
                    return 0;
                }
                return -1;
            }
            if (GetXMin() >= that.GetXMax())
            {
                return 1;
            }
            // Parameter s for thi(s) curve and t for tha(t) curve
            // [st]0 = parameters for top of current section of interest
            // [st]1 = parameters for bottom of valid range
            // [st]h = parameters for hypothesis point
            // [d][xy]s = valuations of thi(s) curve at sh
            // [d][xy]t = valuations of tha(t) curve at th
            double s0 = TforY(y0);
            double ys0 = YforT(s0);
            if (ys0 < y0)
            {
                s0 = RefineTforY(s0, ys0, y0);
                ys0 = YforT(s0);
            }
            double s1 = TforY(y1);
            if (YforT(s1) < y0)
            {
                s1 = RefineTforY(s1, YforT(s1), y0);
                //System.out.println("s1 problem!");
            }
            double t0 = that.TforY(y0);
            double yt0 = that.YforT(t0);
            if (yt0 < y0)
            {
                t0 = that.RefineTforY(t0, yt0, y0);
                yt0 = that.YforT(t0);
            }
            double t1 = that.TforY(y1);
            if (that.YforT(t1) < y0)
            {
                t1 = that.RefineTforY(t1, that.YforT(t1), y0);
                //System.out.println("t1 problem!");
            }
            double xs0 = XforT(s0);
            double xt0 = that.XforT(t0);
            double scale = Math.Max(Math.Abs(y0), Math.Abs(y1));
            double ymin = Math.Max(scale * 1E-14, 1E-300);
            if (FairlyClose(xs0, xt0))
            {
                double bump = ymin;
                double maxbump = Math.Min(ymin * 1E13, (y1 - y0) * .1);
                double y = y0 + bump;
                while (y <= y1)
                {
                    if (FairlyClose(XforY(y), that.XforY(y)))
                    {
                        if ((bump *= 2) > maxbump)
                        {
                            bump = maxbump;
                        }
                    }
                    else
                    {
                        y -= bump;
                        while (true)
                        {
                            bump /= 2;
                            double newy = y + bump;
                            if (newy <= y)
                            {
                                break;
                            }
                            if (FairlyClose(XforY(newy), that.XforY(newy)))
                            {
                                y = newy;
                            }
                        }
                        break;
                    }
                    y += bump;
                }
                if (y > y0)
                {
                    if (y < y1)
                    {
                        yrange[1] = y;
                    }
                    return 0;
                }
            }

            while (s0 < s1 && t0 < t1)
            {
                double sh = NextVertical(s0, s1);
                double xsh = XforT(sh);
                double ysh = YforT(sh);
                double th = that.NextVertical(t0, t1);
                double xth = that.XforT(th);
                double yth = that.YforT(th);
                /*
                System.out.println("sh = "+sh);
                System.out.println("th = "+th);
                 */
                try
                {
                    if (FindIntersect(that, yrange, ymin, 0, 0,
                            s0, xs0, ys0, sh, xsh, ysh,
                            t0, xt0, yt0, th, xth, yth))
                    {
                        break;
                    }
                }
                catch (Exception)
                {
                    return 0;
                }
                if (ysh < yth)
                {
                    if (ysh > yrange[0])
                    {
                        if (ysh < yrange[1])
                        {
                            yrange[1] = ysh;
                        }
                        break;
                    }
                    s0 = sh;
                    xs0 = xsh;
                    ys0 = ysh;
                }
                else
                {
                    if (yth > yrange[0])
                    {
                        if (yth < yrange[1])
                        {
                            yrange[1] = yth;
                        }
                        break;
                    }
                    t0 = th;
                    xt0 = xth;
                    yt0 = yth;
                }
            }
            double ymid = (yrange[0] + yrange[1]) / 2;

            return Orderof(XforY(ymid), that.XforY(ymid));
        }
Beispiel #5
0
 public new int CompareTo(Curve other, double[] yrange)
 {
     if (!(other is Order1))
     {
         return base.CompareTo(other, yrange);
     }
     Order1 c1 = (Order1)other;
     if (yrange[1] <= yrange[0])
     {
         throw new SystemException("yrange already screwed up...");
     }
     yrange[1] = Math.Min(Math.Min(yrange[1], _y1), c1._y1);
     if (yrange[1] <= yrange[0])
     {
         throw new SystemException("backstepping from " + yrange[0] + " to " + yrange[1]);
     }
     if (_xmax <= c1._xmin)
     {
         return (_xmin == c1._xmax) ? 0 : -1;
     }
     if (_xmin >= c1._xmax)
     {
         return 1;
     }
     /*
      * If "this" is curve A and "other" is curve B, then...
      * xA(y) = x0A + (y - y0A) (x1A - x0A) / (y1A - y0A)
      * xB(y) = x0B + (y - y0B) (x1B - x0B) / (y1B - y0B)
      * xA(y) == xB(y)
      * x0A + (y - y0A) (x1A - x0A) / (y1A - y0A)
      *    == x0B + (y - y0B) (x1B - x0B) / (y1B - y0B)
      * 0 == x0A (y1A - y0A) (y1B - y0B) + (y - y0A) (x1A - x0A) (y1B - y0B)
      *    - x0B (y1A - y0A) (y1B - y0B) - (y - y0B) (x1B - x0B) (y1A - y0A)
      * 0 == (x0A - x0B) (y1A - y0A) (y1B - y0B)
      *    + (y - y0A) (x1A - x0A) (y1B - y0B)
      *    - (y - y0B) (x1B - x0B) (y1A - y0A)
      * If (dxA == x1A - x0A), etc...
      * 0 == (x0A - x0B) * dyA * dyB
      *    + (y - y0A) * dxA * dyB
      *    - (y - y0B) * dxB * dyA
      * 0 == (x0A - x0B) * dyA * dyB
      *    + y * dxA * dyB - y0A * dxA * dyB
      *    - y * dxB * dyA + y0B * dxB * dyA
      * 0 == (x0A - x0B) * dyA * dyB
      *    + y * dxA * dyB - y * dxB * dyA
      *    - y0A * dxA * dyB + y0B * dxB * dyA
      * 0 == (x0A - x0B) * dyA * dyB
      *    + y * (dxA * dyB - dxB * dyA)
      *    - y0A * dxA * dyB + y0B * dxB * dyA
      * y == ((x0A - x0B) * dyA * dyB
      *       - y0A * dxA * dyB + y0B * dxB * dyA)
      *    / (-(dxA * dyB - dxB * dyA))
      * y == ((x0A - x0B) * dyA * dyB
      *       - y0A * dxA * dyB + y0B * dxB * dyA)
      *    / (dxB * dyA - dxA * dyB)
      */
     double dxa = _x1 - _x0;
     double dya = _y1 - _y0;
     double dxb = c1._x1 - c1._x0;
     double dyb = c1._y1 - c1._y0;
     double denom = dxb * dya - dxa * dyb;
     double y;
     if (denom != 0)
     {
         double num = ((_x0 - c1._x0) * dya * dyb - _y0 * dxa * dyb + c1._y0 * dxb * dya);
         y = num / denom;
         if (y <= yrange[0])
         {
             // intersection is above us
             // Use bottom-most common y for comparison
             y = Math.Min(_y1, c1._y1);
         }
         else
         {
             // intersection is below the top of our range
             if (y < yrange[1])
             {
                 // If intersection is in our range, adjust valid range
                 yrange[1] = y;
             }
             // Use top-most common y for comparison
             y = Math.Max(_y0, c1._y0);
         }
     }
     else
     {
         // lines are parallel, choose any common y for comparison
         // Note - prefer an endpoint for speed of calculating the X
         // (see shortcuts in Order1.XforY())
         y = Math.Max(_y0, c1._y0);
     }
     return Orderof(XforY(y), c1.XforY(y));
 }
Beispiel #6
0
 public override void Next()
 {
     if (_prevcurve != null)
     {
         _prevcurve = null;
     }
     else
     {
         _prevcurve = _thiscurve;
         _index++;
         if (_index < _curves.Count)
         {
             _thiscurve = (Curve)_curves[_index];
             if (_thiscurve.GetOrder() != 0 &&
                     _prevcurve.GetX1() == _thiscurve.GetX0() &&
                     _prevcurve.GetY1() == _thiscurve.GetY0())
             {
                 _prevcurve = null;
             }
         }
         else
         {
             _thiscurve = null;
         }
     }
 }
Beispiel #7
0
 public AreaIterator(ArrayList curves, AffineTransform at)
 {
     _curves = curves;
     _transform = at;
     if (curves.Count >= 1)
     {
         _thiscurve = (Curve)curves[0];
     }
 }
Beispiel #8
0
 public Edge(Curve c, int ctag, int etag)
 {
     _curve = c;
     _ctag = ctag;
     _etag = etag;
 }
Beispiel #9
0
 public Edge(Curve c, int ctag)
     : this(c, ctag, AreaOp.ETAG_IGNORE)
 {
 }