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); } }
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; }
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; }
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)); }
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)); }
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; } } }
public AreaIterator(ArrayList curves, AffineTransform at) { _curves = curves; _transform = at; if (curves.Count >= 1) { _thiscurve = (Curve)curves[0]; } }
public Edge(Curve c, int ctag, int etag) { _curve = c; _ctag = ctag; _etag = etag; }
public Edge(Curve c, int ctag) : this(c, ctag, AreaOp.ETAG_IGNORE) { }