UNPKG

webcola

Version:
424 lines 13.6 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); var rectangle_1 = require("./rectangle"); var Point = (function () { function Point() { } return Point; }()); exports.Point = Point; var LineSegment = (function () { function LineSegment(x1, y1, x2, y2) { this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; } return LineSegment; }()); exports.LineSegment = LineSegment; var PolyPoint = (function (_super) { __extends(PolyPoint, _super); function PolyPoint() { return _super !== null && _super.apply(this, arguments) || this; } return PolyPoint; }(Point)); exports.PolyPoint = PolyPoint; function isLeft(P0, P1, P2) { return (P1.x - P0.x) * (P2.y - P0.y) - (P2.x - P0.x) * (P1.y - P0.y); } exports.isLeft = isLeft; function above(p, vi, vj) { return isLeft(p, vi, vj) > 0; } function below(p, vi, vj) { return isLeft(p, vi, vj) < 0; } function ConvexHull(S) { var P = S.slice(0).sort(function (a, b) { return a.x !== b.x ? b.x - a.x : b.y - a.y; }); var n = S.length, i; var minmin = 0; var xmin = P[0].x; for (i = 1; i < n; ++i) { if (P[i].x !== xmin) break; } var minmax = i - 1; var H = []; H.push(P[minmin]); if (minmax === n - 1) { if (P[minmax].y !== P[minmin].y) H.push(P[minmax]); } else { var maxmin, maxmax = n - 1; var xmax = P[n - 1].x; for (i = n - 2; i >= 0; i--) if (P[i].x !== xmax) break; maxmin = i + 1; i = minmax; while (++i <= maxmin) { if (isLeft(P[minmin], P[maxmin], P[i]) >= 0 && i < maxmin) continue; while (H.length > 1) { if (isLeft(H[H.length - 2], H[H.length - 1], P[i]) > 0) break; else H.length -= 1; } if (i != minmin) H.push(P[i]); } if (maxmax != maxmin) H.push(P[maxmax]); var bot = H.length; i = maxmin; while (--i >= minmax) { if (isLeft(P[maxmax], P[minmax], P[i]) >= 0 && i > minmax) continue; while (H.length > bot) { if (isLeft(H[H.length - 2], H[H.length - 1], P[i]) > 0) break; else H.length -= 1; } if (i != minmin) H.push(P[i]); } } return H; } exports.ConvexHull = ConvexHull; function clockwiseRadialSweep(p, P, f) { P.slice(0).sort(function (a, b) { return Math.atan2(a.y - p.y, a.x - p.x) - Math.atan2(b.y - p.y, b.x - p.x); }).forEach(f); } exports.clockwiseRadialSweep = clockwiseRadialSweep; function nextPolyPoint(p, ps) { if (p.polyIndex === ps.length - 1) return ps[0]; return ps[p.polyIndex + 1]; } function prevPolyPoint(p, ps) { if (p.polyIndex === 0) return ps[ps.length - 1]; return ps[p.polyIndex - 1]; } function tangent_PointPolyC(P, V) { var Vclosed = V.slice(0); Vclosed.push(V[0]); return { rtan: Rtangent_PointPolyC(P, Vclosed), ltan: Ltangent_PointPolyC(P, Vclosed) }; } function Rtangent_PointPolyC(P, V) { var n = V.length - 1; var a, b, c; var upA, dnC; if (below(P, V[1], V[0]) && !above(P, V[n - 1], V[0])) return 0; for (a = 0, b = n;;) { if (b - a === 1) if (above(P, V[a], V[b])) return a; else return b; c = Math.floor((a + b) / 2); dnC = below(P, V[c + 1], V[c]); if (dnC && !above(P, V[c - 1], V[c])) return c; upA = above(P, V[a + 1], V[a]); if (upA) { if (dnC) b = c; else { if (above(P, V[a], V[c])) b = c; else a = c; } } else { if (!dnC) a = c; else { if (below(P, V[a], V[c])) b = c; else a = c; } } } } function Ltangent_PointPolyC(P, V) { var n = V.length - 1; var a, b, c; var dnA, dnC; if (above(P, V[n - 1], V[0]) && !below(P, V[1], V[0])) return 0; for (a = 0, b = n;;) { if (b - a === 1) if (below(P, V[a], V[b])) return a; else return b; c = Math.floor((a + b) / 2); dnC = below(P, V[c + 1], V[c]); if (above(P, V[c - 1], V[c]) && !dnC) return c; dnA = below(P, V[a + 1], V[a]); if (dnA) { if (!dnC) b = c; else { if (below(P, V[a], V[c])) b = c; else a = c; } } else { if (dnC) a = c; else { if (above(P, V[a], V[c])) b = c; else a = c; } } } } function tangent_PolyPolyC(V, W, t1, t2, cmp1, cmp2) { var ix1, ix2; ix1 = t1(W[0], V); ix2 = t2(V[ix1], W); var done = false; while (!done) { done = true; while (true) { if (ix1 === V.length - 1) ix1 = 0; if (cmp1(W[ix2], V[ix1], V[ix1 + 1])) break; ++ix1; } while (true) { if (ix2 === 0) ix2 = W.length - 1; if (cmp2(V[ix1], W[ix2], W[ix2 - 1])) break; --ix2; done = false; } } return { t1: ix1, t2: ix2 }; } exports.tangent_PolyPolyC = tangent_PolyPolyC; function LRtangent_PolyPolyC(V, W) { var rl = RLtangent_PolyPolyC(W, V); return { t1: rl.t2, t2: rl.t1 }; } exports.LRtangent_PolyPolyC = LRtangent_PolyPolyC; function RLtangent_PolyPolyC(V, W) { return tangent_PolyPolyC(V, W, Rtangent_PointPolyC, Ltangent_PointPolyC, above, below); } exports.RLtangent_PolyPolyC = RLtangent_PolyPolyC; function LLtangent_PolyPolyC(V, W) { return tangent_PolyPolyC(V, W, Ltangent_PointPolyC, Ltangent_PointPolyC, below, below); } exports.LLtangent_PolyPolyC = LLtangent_PolyPolyC; function RRtangent_PolyPolyC(V, W) { return tangent_PolyPolyC(V, W, Rtangent_PointPolyC, Rtangent_PointPolyC, above, above); } exports.RRtangent_PolyPolyC = RRtangent_PolyPolyC; var BiTangent = (function () { function BiTangent(t1, t2) { this.t1 = t1; this.t2 = t2; } return BiTangent; }()); exports.BiTangent = BiTangent; var BiTangents = (function () { function BiTangents() { } return BiTangents; }()); exports.BiTangents = BiTangents; var TVGPoint = (function (_super) { __extends(TVGPoint, _super); function TVGPoint() { return _super !== null && _super.apply(this, arguments) || this; } return TVGPoint; }(Point)); exports.TVGPoint = TVGPoint; var VisibilityVertex = (function () { function VisibilityVertex(id, polyid, polyvertid, p) { this.id = id; this.polyid = polyid; this.polyvertid = polyvertid; this.p = p; p.vv = this; } return VisibilityVertex; }()); exports.VisibilityVertex = VisibilityVertex; var VisibilityEdge = (function () { function VisibilityEdge(source, target) { this.source = source; this.target = target; } VisibilityEdge.prototype.length = function () { var dx = this.source.p.x - this.target.p.x; var dy = this.source.p.y - this.target.p.y; return Math.sqrt(dx * dx + dy * dy); }; return VisibilityEdge; }()); exports.VisibilityEdge = VisibilityEdge; var TangentVisibilityGraph = (function () { function TangentVisibilityGraph(P, g0) { this.P = P; this.V = []; this.E = []; if (!g0) { var n = P.length; for (var i = 0; i < n; i++) { var p = P[i]; for (var j = 0; j < p.length; ++j) { var pj = p[j], vv = new VisibilityVertex(this.V.length, i, j, pj); this.V.push(vv); if (j > 0) this.E.push(new VisibilityEdge(p[j - 1].vv, vv)); } if (p.length > 1) this.E.push(new VisibilityEdge(p[0].vv, p[p.length - 1].vv)); } for (var i = 0; i < n - 1; i++) { var Pi = P[i]; for (var j = i + 1; j < n; j++) { var Pj = P[j], t = tangents(Pi, Pj); for (var q in t) { var c = t[q], source = Pi[c.t1], target = Pj[c.t2]; this.addEdgeIfVisible(source, target, i, j); } } } } else { this.V = g0.V.slice(0); this.E = g0.E.slice(0); } } TangentVisibilityGraph.prototype.addEdgeIfVisible = function (u, v, i1, i2) { if (!this.intersectsPolys(new LineSegment(u.x, u.y, v.x, v.y), i1, i2)) { this.E.push(new VisibilityEdge(u.vv, v.vv)); } }; TangentVisibilityGraph.prototype.addPoint = function (p, i1) { var n = this.P.length; this.V.push(new VisibilityVertex(this.V.length, n, 0, p)); for (var i = 0; i < n; ++i) { if (i === i1) continue; var poly = this.P[i], t = tangent_PointPolyC(p, poly); this.addEdgeIfVisible(p, poly[t.ltan], i1, i); this.addEdgeIfVisible(p, poly[t.rtan], i1, i); } return p.vv; }; TangentVisibilityGraph.prototype.intersectsPolys = function (l, i1, i2) { for (var i = 0, n = this.P.length; i < n; ++i) { if (i != i1 && i != i2 && intersects(l, this.P[i]).length > 0) { return true; } } return false; }; return TangentVisibilityGraph; }()); exports.TangentVisibilityGraph = TangentVisibilityGraph; function intersects(l, P) { var ints = []; for (var i = 1, n = P.length; i < n; ++i) { var int = rectangle_1.Rectangle.lineIntersection(l.x1, l.y1, l.x2, l.y2, P[i - 1].x, P[i - 1].y, P[i].x, P[i].y); if (int) ints.push(int); } return ints; } function tangents(V, W) { var m = V.length - 1, n = W.length - 1; var bt = new BiTangents(); for (var i = 0; i < m; ++i) { for (var j = 0; j < n; ++j) { var v1 = V[i == 0 ? m - 1 : i - 1]; var v2 = V[i]; var v3 = V[i + 1]; var w1 = W[j == 0 ? n - 1 : j - 1]; var w2 = W[j]; var w3 = W[j + 1]; var v1v2w2 = isLeft(v1, v2, w2); var v2w1w2 = isLeft(v2, w1, w2); var v2w2w3 = isLeft(v2, w2, w3); var w1w2v2 = isLeft(w1, w2, v2); var w2v1v2 = isLeft(w2, v1, v2); var w2v2v3 = isLeft(w2, v2, v3); if (v1v2w2 >= 0 && v2w1w2 >= 0 && v2w2w3 < 0 && w1w2v2 >= 0 && w2v1v2 >= 0 && w2v2v3 < 0) { bt.ll = new BiTangent(i, j); } else if (v1v2w2 <= 0 && v2w1w2 <= 0 && v2w2w3 > 0 && w1w2v2 <= 0 && w2v1v2 <= 0 && w2v2v3 > 0) { bt.rr = new BiTangent(i, j); } else if (v1v2w2 <= 0 && v2w1w2 > 0 && v2w2w3 <= 0 && w1w2v2 >= 0 && w2v1v2 < 0 && w2v2v3 >= 0) { bt.rl = new BiTangent(i, j); } else if (v1v2w2 >= 0 && v2w1w2 < 0 && v2w2w3 >= 0 && w1w2v2 <= 0 && w2v1v2 > 0 && w2v2v3 <= 0) { bt.lr = new BiTangent(i, j); } } } return bt; } exports.tangents = tangents; function isPointInsidePoly(p, poly) { for (var i = 1, n = poly.length; i < n; ++i) if (below(poly[i - 1], poly[i], p)) return false; return true; } function isAnyPInQ(p, q) { return !p.every(function (v) { return !isPointInsidePoly(v, q); }); } function polysOverlap(p, q) { if (isAnyPInQ(p, q)) return true; if (isAnyPInQ(q, p)) return true; for (var i = 1, n = p.length; i < n; ++i) { var v = p[i], u = p[i - 1]; if (intersects(new LineSegment(u.x, u.y, v.x, v.y), q).length > 0) return true; } return false; } exports.polysOverlap = polysOverlap; //# sourceMappingURL=geom.js.map