Exemplo n.º 1
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;
        }
Exemplo n.º 2
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));
        }