UNPKG

flatten-js

Version:

Javascript library for 2d geometry

1 lines 47 kB
{"dependencies":[{"name":"C:\\Users\\alexbol\\WebstormProjects\\flatten-js\\package.json","includedInParent":true,"mtime":1520238055570},{"name":"flatten-interval-tree","loc":{"line":3,"column":27}}],"generated":{"js":"\"use strict\";\n\nvar _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"]) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); } }; }();\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar IntervalTree = require('flatten-interval-tree');\n\nmodule.exports = function (Flatten) {\n var Polygon = Flatten.Polygon,\n Point = Flatten.Point,\n Segment = Flatten.Segment,\n Arc = Flatten.Arc,\n Circle = Flatten.Circle,\n Line = Flatten.Line,\n Ray = Flatten.Ray,\n Vector = Flatten.Vector;\n var vector = Flatten.vector;\n\n\n Flatten.Distance = function () {\n function Distance() {\n _classCallCheck(this, Distance);\n }\n\n _createClass(Distance, null, [{\n key: \"point2point\",\n\n /**\r\n * Calculate distance and shortest segment between points\r\n * @param pt1\r\n * @param pt2\r\n * @returns {Number | Segment} - distance and shortest segment\r\n */\n value: function point2point(pt1, pt2) {\n return pt1.distanceTo(pt2);\n }\n\n /**\r\n * Calculate distance and shortest segment between point and line\r\n * @param pt\r\n * @param line\r\n * @returns {Number | Segment} - distance and shortest segment\r\n */\n\n }, {\n key: \"point2line\",\n value: function point2line(pt, line) {\n var closest_point = pt.projectionOn(line);\n var vec = vector(pt, closest_point);\n return [vec.length, new Segment(pt, closest_point)];\n }\n\n /**\r\n * Calculate distance and shortest segment between point and circle\r\n * @param pt\r\n * @param circle\r\n * @returns {Number | Segment} - distance and shortest segment\r\n */\n\n }, {\n key: \"point2circle\",\n value: function point2circle(pt, circle) {\n var _pt$distanceTo = pt.distanceTo(circle.center),\n _pt$distanceTo2 = _slicedToArray(_pt$distanceTo, 2),\n dist2center = _pt$distanceTo2[0],\n shortest_dist = _pt$distanceTo2[1];\n\n if (Flatten.Utils.EQ_0(dist2center)) {\n return [circle.r, new Segment(pt, circle.toArc().start)];\n } else {\n var dist = Math.abs(dist2center - circle.r);\n var v = vector(circle.pc, pt).normalize().multiply(circle.r);\n var closest_point = circle.pc.translate(v);\n return [dist, new Segment(pt, closest_point)];\n }\n }\n\n /**\r\n * Calculate distance and shortest segment between point and segment\r\n * @param pt\r\n * @param segment\r\n * @returns {Number | Segment} - distance and shortest segment\r\n */\n\n }, {\n key: \"point2segment\",\n value: function point2segment(pt, segment) {\n /* Degenerated case of zero-length segment */\n if (segment.start.equalTo(segment.end)) {\n return Distance.point2point(pt, segment.start);\n }\n\n var v_seg = new Flatten.Vector(segment.start, segment.end);\n var v_ps2pt = new Flatten.Vector(segment.start, pt);\n var v_pe2pt = new Flatten.Vector(segment.end, pt);\n var start_sp = v_seg.dot(v_ps2pt);\n /* dot product v_seg * v_ps2pt */\n var end_sp = -v_seg.dot(v_pe2pt);\n /* minus dot product v_seg * v_pe2pt */\n\n var dist = void 0;\n var closest_point = void 0;\n if (Flatten.Utils.GE(start_sp, 0) && Flatten.Utils.GE(end_sp, 0)) {\n /* point inside segment scope */\n var v_unit = segment.tangentInStart(); // new Flatten.Vector(v_seg.x / this.length, v_seg.y / this.length);\n /* unit vector ||v_unit|| = 1 */\n dist = Math.abs(v_unit.cross(v_ps2pt));\n /* dist = abs(v_unit x v_ps2pt) */\n closest_point = segment.start.translate(v_unit.multiply(v_unit.dot(v_ps2pt)));\n return [dist, new Segment(pt, closest_point)];\n } else if (start_sp < 0) {\n /* point is out of scope closer to ps */\n return pt.distanceTo(segment.start);\n } else {\n /* point is out of scope closer to pe */\n return pt.distanceTo(segment.end);\n }\n }\n }, {\n key: \"point2arc\",\n\n\n /**\r\n * Calculate distance and shortest segment between point and arc\r\n * @param pt\r\n * @param arc\r\n * @returns {Number | Segment} - distance and shortest segment\r\n */\n value: function point2arc(pt, arc) {\n var circle = new Flatten.Circle(arc.pc, arc.r);\n var dist_and_segments = [];\n var dist = void 0,\n shortest_segment = void 0;\n\n var _Distance$point2circl = Distance.point2circle(pt, circle);\n\n var _Distance$point2circl2 = _slicedToArray(_Distance$point2circl, 2);\n\n dist = _Distance$point2circl2[0];\n shortest_segment = _Distance$point2circl2[1];\n\n if (shortest_segment.end.on(arc)) {\n dist_and_segments.push(Distance.point2circle(pt, circle));\n }\n dist_and_segments.push(Distance.point2point(pt, arc.start));\n dist_and_segments.push(Distance.point2point(pt, arc.end));\n\n Distance.sort(dist_and_segments);\n\n return dist_and_segments[0];\n }\n\n /**\r\n * Calculate distance and shortest segment between segment and line\r\n * @param seg\r\n * @param line\r\n * @returns {Number | Segment}\r\n */\n\n }, {\n key: \"segment2line\",\n value: function segment2line(seg, line) {\n var ip = seg.intersect(line);\n if (ip.length > 0) {\n return [0, new Segment(ip[0], ip[0])]; // distance = 0, closest point is the first point\n }\n\n dist_and_segment.push(Distance.point2line(seg.start, line));\n dist_and_segment.push(Distance.point2line(seg.end, line));\n\n Distance.sort(dist_and_segment);\n return dist_and_segment[0];\n }\n\n /**\r\n * Calculate distance and shortest segment between two segments\r\n * @param seg1\r\n * @param seg2\r\n * @returns {Number | Segment} - distance and shortest segment\r\n */\n\n }, {\n key: \"segment2segment\",\n value: function segment2segment(seg1, seg2) {\n var ip = Segment.intersectSegment2Segment(seg1, seg2);\n if (ip.length > 0) {\n return [0, new Segment(ip[0], ip[0])]; // distance = 0, closest point is the first point\n }\n\n // Seg1 and seg2 not intersected\n var dist_and_segment = [];\n\n dist_and_segment.push(Distance.point2segment(seg2.start, seg1));\n dist_and_segment.push(Distance.point2segment(seg2.end, seg1));\n dist_and_segment.push(Distance.point2segment(seg1.start, seg2));\n dist_and_segment.push(Distance.point2segment(seg1.end, seg2));\n\n Distance.sort(dist_and_segment);\n return dist_and_segment[0];\n }\n\n /**\r\n * Calculate distance and shortest segment between segment and circle\r\n * @param seg\r\n * @param circle\r\n * @returns {Number | Segment} - distance and shortest segment\r\n */\n\n }, {\n key: \"segment2circle\",\n value: function segment2circle(seg, circle) {\n /* Case 1 Segment and circle intersected. Return the first point and zero distance */\n var ip = seg.intersect(circle);\n if (ip.length > 0) {\n return [0, new Segment(ip[0], ip[0])];\n }\n\n // No intersection between segment and circle\n\n /* Case 2. Distance to projection of center point to line bigger than radius\r\n * And projection point belong to segment\r\n * Then measure again distance from projection to circle and return it */\n var line = new Flatten.Line(seg.ps, seg.pe);\n\n var _Distance$point2line = Distance.point2line(circle.center, line),\n _Distance$point2line2 = _slicedToArray(_Distance$point2line, 2),\n dist = _Distance$point2line2[0],\n shortest_segment = _Distance$point2line2[1];\n\n if (Flatten.Utils.GE(dist, circle.r) && shortest_segment.end.on(seg)) {\n return Distance.point2circle(shortest_segment.end, circle);\n }\n /* Case 3. Otherwise closest point is one of the end points of the segment */\n else {\n var _Distance$point2circl3 = Distance.point2circle(seg.start, circle),\n _Distance$point2circl4 = _slicedToArray(_Distance$point2circl3, 2),\n dist_from_start = _Distance$point2circl4[0],\n shortest_segment_from_start = _Distance$point2circl4[1];\n\n var _Distance$point2circl5 = Distance.point2circle(seg.end, circle),\n _Distance$point2circl6 = _slicedToArray(_Distance$point2circl5, 2),\n dist_from_end = _Distance$point2circl6[0],\n shortest_segment_from_end = _Distance$point2circl6[1];\n\n return Flatten.Utils.LT(dist_from_start, dist_from_end) ? [dist_from_start, shortest_segment_from_start] : [dist_from_end, shortest_segment_from_end];\n }\n }\n\n /**\r\n * Calculate distance and shortest segment between segment and arc\r\n * @param seg\r\n * @param arc\r\n * @returns {Number | Segment} - distance and shortest segment\r\n */\n\n }, {\n key: \"segment2arc\",\n value: function segment2arc(seg, arc) {\n /* Case 1 Segment and arc intersected. Return the first point and zero distance */\n var ip = seg.intersect(arc);\n if (ip.length > 0) {\n return [0, new Segment(ip[0], ip[0])];\n }\n\n // No intersection between segment and arc\n var line = new Flatten.Line(seg.ps, seg.pe);\n var circle = new Flatten.Circle(arc.pc, arc.r);\n\n /* Case 2. Distance to projection of center point to line bigger than radius AND\r\n * projection point belongs to segment AND\r\n * distance from projection point to circle belongs to arc =>\r\n * return this distance from projection to circle */\n\n var _Distance$point2line3 = Distance.point2line(circle.center, line),\n _Distance$point2line4 = _slicedToArray(_Distance$point2line3, 2),\n dist_from_center = _Distance$point2line4[0],\n shortest_segment_from_center = _Distance$point2line4[1];\n\n if (Flatten.Utils.GE(dist_from_center, circle.r) && shortest_segment_from_center.end.on(seg)) {\n var _Distance$point2circl7 = Distance.point2circle(shortest_segment_from_center.end, circle),\n _Distance$point2circl8 = _slicedToArray(_Distance$point2circl7, 2),\n dist_from_projection = _Distance$point2circl8[0],\n shortest_segment_from_projection = _Distance$point2circl8[1];\n\n if (shortest_segment_from_projection.end.on(arc)) {\n return [dist_from_projection, shortest_segment_from_projection];\n }\n }\n /* Case 3. Otherwise closest point is one of the end points of the segment */\n var dist_and_segment = [];\n dist_and_segment.push(Distance.point2arc(seg.start, arc));\n dist_and_segment.push(Distance.point2arc(seg.end, arc));\n\n var dist_tmp = void 0,\n segment_tmp = void 0;\n\n var _Distance$point2segme = Distance.point2segment(arc.start, seg);\n\n var _Distance$point2segme2 = _slicedToArray(_Distance$point2segme, 2);\n\n dist_tmp = _Distance$point2segme2[0];\n segment_tmp = _Distance$point2segme2[1];\n\n dist_and_segment.push([dist_tmp, segment_tmp.reverse()]);\n\n var _Distance$point2segme3 = Distance.point2segment(arc.end, seg);\n\n var _Distance$point2segme4 = _slicedToArray(_Distance$point2segme3, 2);\n\n dist_tmp = _Distance$point2segme4[0];\n segment_tmp = _Distance$point2segme4[1];\n\n dist_and_segment.push([dist_tmp, segment_tmp.reverse()]);\n\n Distance.sort(dist_and_segment);\n return dist_and_segment[0];\n }\n\n /**\r\n * Calculate distance and shortest segment between two circles\r\n * @param circle1\r\n * @param circle2\r\n * @returns {Number | Segment} - distance and shortest segment\r\n */\n\n }, {\n key: \"circle2circle\",\n value: function circle2circle(circle1, circle2) {\n var ip = circle1.intersect(circle2);\n if (ip.length > 0) {\n return [0, new Segment(ip[0], ip[0])];\n }\n\n // Case 1. Concentric circles. Convert to arcs and take distance between two arc starts\n if (circle1.center.equalTo(circle2.center)) {\n var arc1 = circle1.toArc();\n var arc2 = circle2.toArc();\n return Distance.point2point(arc1.start, arc2.start);\n } else {\n // Case 2. Not concentric circles\n var line = new Line(circle1.center, circle2.center);\n var ip1 = line.intersect(circle1);\n var ip2 = line.intersect(circle2);\n\n var _dist_and_segment = [];\n\n _dist_and_segment.push(Distance.point2point(ip1[0], ip2[0]));\n _dist_and_segment.push(Distance.point2point(ip1[0], ip2[1]));\n _dist_and_segment.push(Distance.point2point(ip1[1], ip2[0]));\n _dist_and_segment.push(Distance.point2point(ip1[1], ip2[1]));\n\n Distance.sort(_dist_and_segment);\n return _dist_and_segment[0];\n }\n }\n\n /**\r\n * Calculate distance and shortest segment between two circles\r\n * @param circle\r\n * @param line\r\n * @returns {Number | Segment} - distance and shortest segment\r\n */\n\n }, {\n key: \"circle2line\",\n value: function circle2line(circle, line) {\n var ip = circle.intersect(line);\n if (ip.length > 0) {\n return [0, new Segment(ip[0], ip[0])];\n }\n\n var _Distance$point2line5 = Distance.point2line(circle.center, line),\n _Distance$point2line6 = _slicedToArray(_Distance$point2line5, 2),\n dist_from_center = _Distance$point2line6[0],\n shortest_segment_from_center = _Distance$point2line6[1];\n\n var _Distance$point2circl9 = Distance.point2circle(shortest_segment_from_center.end, circle),\n _Distance$point2circl10 = _slicedToArray(_Distance$point2circl9, 2),\n dist = _Distance$point2circl10[0],\n shortest_segment = _Distance$point2circl10[1];\n\n shortest_segment = shortest_segment.reverse();\n return [dist, shortest_segment];\n }\n\n /**\r\n * Calculate distance and shortest segment between arc and line\r\n * @param arc\r\n * @param line\r\n * @returns {Number | Segment} - distance and shortest segment\r\n */\n\n }, {\n key: \"arc2line\",\n value: function arc2line(arc, line) {\n /* Case 1 Line and arc intersected. Return the first point and zero distance */\n var ip = line.intersect(arc);\n if (ip.length > 0) {\n return [0, new Segment(ip[0], ip[0])];\n }\n\n var circle = new Flatten.Circle(arc.center, arc.r);\n\n /* Case 2. Distance to projection of center point to line bigger than radius AND\r\n * projection point belongs to segment AND\r\n * distance from projection point to circle belongs to arc =>\r\n * return this distance from projection to circle */\n\n var _Distance$point2line7 = Distance.point2line(circle.center, line),\n _Distance$point2line8 = _slicedToArray(_Distance$point2line7, 2),\n dist_from_center = _Distance$point2line8[0],\n shortest_segment_from_center = _Distance$point2line8[1];\n\n if (Flatten.Utils.GE(dist_from_center, circle.r)) {\n var _Distance$point2circl11 = Distance.point2circle(shortest_segment_from_center.end, circle),\n _Distance$point2circl12 = _slicedToArray(_Distance$point2circl11, 2),\n dist_from_projection = _Distance$point2circl12[0],\n shortest_segment_from_projection = _Distance$point2circl12[1];\n\n if (shortest_segment_from_projection.end.on(arc)) {\n return [dist_from_projection, shortest_segment_from_projection];\n }\n } else {\n var _dist_and_segment2 = [];\n _dist_and_segment2.push(Distance.point2line(arc.start, line));\n _dist_and_segment2.push(Distance.point2line(arc.end, line));\n\n Distance.sort(_dist_and_segment2);\n return _dist_and_segment2[0];\n }\n }\n\n /**\r\n * Calculate distance and shortest segment between arc and circle\r\n * @param arc\r\n * @param circle2\r\n * @returns {Number | Segment} - distance and shortest segment\r\n */\n\n }, {\n key: \"arc2circle\",\n value: function arc2circle(arc, circle2) {\n var ip = arc.intersect(circle2);\n if (ip.length > 0) {\n return [0, new Segment(ip[0], ip[0])];\n }\n\n var circle1 = new Flatten.Circle(arc.center, arc.r);\n\n var _Distance$circle2circ = Distance.circle2circle(circle1, circle2),\n _Distance$circle2circ2 = _slicedToArray(_Distance$circle2circ, 2),\n dist = _Distance$circle2circ2[0],\n shortest_segment = _Distance$circle2circ2[1];\n\n if (shortest_segment.start.on(arc)) {\n return [dist, shortest_segment];\n } else {\n var _dist_and_segment3 = [];\n\n _dist_and_segment3.push(Distance.point2circle(arc.start, circle2));\n _dist_and_segment3.push(Distance.point2circle(arc.end, circle2));\n\n Distance.sort(_dist_and_segment3);\n\n return _dist_and_segment3[0];\n }\n }\n\n /**\r\n * Calculate distance and shortest segment between two arcs\r\n * @param arc1\r\n * @param arc2\r\n * @returns {Number | Segment} - distance and shortest segment\r\n */\n\n }, {\n key: \"arc2arc\",\n value: function arc2arc(arc1, arc2) {\n var ip = arc1.intersect(arc2);\n if (ip.length > 0) {\n return [0, new Segment(ip[0], ip[0])];\n }\n\n var circle1 = new Flatten.Circle(arc1.center, arc1.r);\n var circle2 = new Flatten.Circle(arc2.center, arc2.r);\n\n var _Distance$circle2circ3 = Distance.circle2circle(circle1, circle2),\n _Distance$circle2circ4 = _slicedToArray(_Distance$circle2circ3, 2),\n dist = _Distance$circle2circ4[0],\n shortest_segment = _Distance$circle2circ4[1];\n\n if (shortest_segment.start.on(arc1) && shortest_segment.end.on(arc2)) {\n return [dist, shortest_segment];\n } else {\n var _dist_and_segment4 = [];\n\n var dist_tmp = void 0,\n segment_tmp = void 0;\n\n var _Distance$point2arc = Distance.point2arc(arc1.start, arc2);\n\n var _Distance$point2arc2 = _slicedToArray(_Distance$point2arc, 2);\n\n dist_tmp = _Distance$point2arc2[0];\n segment_tmp = _Distance$point2arc2[1];\n\n if (segment_tmp.end.on(arc2)) {\n _dist_and_segment4.push([dist_tmp, segment_tmp]);\n }\n\n var _Distance$point2arc3 = Distance.point2arc(arc1.end, arc2);\n\n var _Distance$point2arc4 = _slicedToArray(_Distance$point2arc3, 2);\n\n dist_tmp = _Distance$point2arc4[0];\n segment_tmp = _Distance$point2arc4[1];\n\n if (segment_tmp.end.on(arc2)) {\n _dist_and_segment4.push([dist_tmp, segment_tmp]);\n }\n\n var _Distance$point2arc5 = Distance.point2arc(arc2.start, arc1);\n\n var _Distance$point2arc6 = _slicedToArray(_Distance$point2arc5, 2);\n\n dist_tmp = _Distance$point2arc6[0];\n segment_tmp = _Distance$point2arc6[1];\n\n if (segment_tmp.end.on(arc1)) {\n _dist_and_segment4.push([dist_tmp, segment_tmp.reverse()]);\n }\n\n var _Distance$point2arc7 = Distance.point2arc(arc2.end, arc1);\n\n var _Distance$point2arc8 = _slicedToArray(_Distance$point2arc7, 2);\n\n dist_tmp = _Distance$point2arc8[0];\n segment_tmp = _Distance$point2arc8[1];\n\n if (segment_tmp.end.on(arc1)) {\n _dist_and_segment4.push([dist_tmp, segment_tmp.reverse()]);\n }\n\n var _Distance$point2point = Distance.point2point(arc1.start, arc2.start);\n\n var _Distance$point2point2 = _slicedToArray(_Distance$point2point, 2);\n\n dist_tmp = _Distance$point2point2[0];\n segment_tmp = _Distance$point2point2[1];\n\n _dist_and_segment4.push([dist_tmp, segment_tmp]);\n\n var _Distance$point2point3 = Distance.point2point(arc1.start, arc2.end);\n\n var _Distance$point2point4 = _slicedToArray(_Distance$point2point3, 2);\n\n dist_tmp = _Distance$point2point4[0];\n segment_tmp = _Distance$point2point4[1];\n\n _dist_and_segment4.push([dist_tmp, segment_tmp]);\n\n var _Distance$point2point5 = Distance.point2point(arc1.end, arc2.start);\n\n var _Distance$point2point6 = _slicedToArray(_Distance$point2point5, 2);\n\n dist_tmp = _Distance$point2point6[0];\n segment_tmp = _Distance$point2point6[1];\n\n _dist_and_segment4.push([dist_tmp, segment_tmp]);\n\n var _Distance$point2point7 = Distance.point2point(arc1.end, arc2.end);\n\n var _Distance$point2point8 = _slicedToArray(_Distance$point2point7, 2);\n\n dist_tmp = _Distance$point2point8[0];\n segment_tmp = _Distance$point2point8[1];\n\n _dist_and_segment4.push([dist_tmp, segment_tmp]);\n\n Distance.sort(_dist_and_segment4);\n\n return _dist_and_segment4[0];\n }\n }\n\n /**\r\n * Calculate distance and shortest segment between point and polygon\r\n * @param point\r\n * @param polygon\r\n * @returns {Number | Segment} - distance and shortest segment\r\n */\n\n }, {\n key: \"point2polygon\",\n value: function point2polygon(point, polygon) {\n var min_dist_and_segment = [Number.POSITIVE_INFINITY, new Segment()];\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = polygon.edges[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var edge = _step.value;\n\n var _ref = edge.shape instanceof Segment ? Distance.point2segment(point, edge.shape) : Distance.point2arc(point, edge.shape),\n _ref2 = _slicedToArray(_ref, 2),\n dist = _ref2[0],\n shortest_segment = _ref2[1];\n\n if (Flatten.Utils.LT(dist, min_dist_and_segment[0])) {\n min_dist_and_segment = [dist, shortest_segment];\n }\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n return min_dist_and_segment;\n }\n }, {\n key: \"shape2polygon\",\n value: function shape2polygon(shape, polygon) {\n var min_dist_and_segment = [Number.POSITIVE_INFINITY, new Segment()];\n var _iteratorNormalCompletion2 = true;\n var _didIteratorError2 = false;\n var _iteratorError2 = undefined;\n\n try {\n for (var _iterator2 = polygon.edges[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {\n var edge = _step2.value;\n\n var _shape$distanceTo = shape.distanceTo(edge.shape),\n _shape$distanceTo2 = _slicedToArray(_shape$distanceTo, 2),\n dist = _shape$distanceTo2[0],\n shortest_segment = _shape$distanceTo2[1];\n\n if (Flatten.Utils.LT(dist, min_dist_and_segment[0])) {\n min_dist_and_segment = [dist, shortest_segment];\n }\n }\n } catch (err) {\n _didIteratorError2 = true;\n _iteratorError2 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion2 && _iterator2.return) {\n _iterator2.return();\n }\n } finally {\n if (_didIteratorError2) {\n throw _iteratorError2;\n }\n }\n }\n\n return min_dist_and_segment;\n }\n\n /*\r\n static arc2polygon(arc, polygon) {\r\n let ip = arc.intersect(polygon);\r\n if (ip.length > 0) {\r\n return [0, new Segment(ip[0], ip[0])];\r\n }\r\n \r\n let min_dist_and_segment = [Number.POSITIVE_INFINITY, new Segment()];\r\n for (let edge of polygon.edges) {\r\n let [dist, shortest_segment] = arc.distanceTo(edge.shape);\r\n if (Flatten.Utils.LT(dist, min_dist_and_segment[0])) {\r\n min_dist_and_segment = [dist, shortest_segment];\r\n }\r\n }\r\n return min_dist_and_segment;\r\n }\r\n \r\n static line2polygon(line, polygon) {\r\n let ip = line.intersect(polygon);\r\n if (ip.length > 0) {\r\n return [0, new Segment(ip[0], ip[0])];\r\n }\r\n \r\n let min_dist_and_segment = [Number.POSITIVE_INFINITY, new Segment()];\r\n for (let edge of polygon.edges) {\r\n let [dist, shortest_segment] = line.distanceTo(edge.shape);\r\n if (Flatten.Utils.LT(dist, min_dist_and_segment[0])) {\r\n min_dist_and_segment = [dist, shortest_segment];\r\n }\r\n }\r\n return min_dist_and_segment;\r\n }\r\n \r\n static circle2polygon(circle, polygon) {\r\n let ip = circle.intersect(polygon);\r\n if (ip.length > 0) {\r\n return [0, new Segment(ip[0], ip[0])];\r\n }\r\n \r\n let min_dist_and_segment = [Number.POSITIVE_INFINITY, new Segment()];\r\n for (let edge of polygon.edges) {\r\n let [dist, shortest_segment] = circle.distanceTo(edge.shape);\r\n if (Flatten.Utils.LT(dist, min_dist_and_segment[0])) {\r\n min_dist_and_segment = [dist, shortest_segment];\r\n }\r\n }\r\n return min_dist_and_segment;\r\n }\r\n */\n\n /**\r\n * Calculate distance and shortest segment between two polygons\r\n * @param polygon1\r\n * @param polygon2\r\n * @returns {Number | Segment} - distance and shortest segment\r\n */\n\n }, {\n key: \"polygon2polygon\",\n value: function polygon2polygon(polygon1, polygon2) {\n var min_dist_and_segment = [Number.POSITIVE_INFINITY, new Flatten.Segment()];\n var _iteratorNormalCompletion3 = true;\n var _didIteratorError3 = false;\n var _iteratorError3 = undefined;\n\n try {\n for (var _iterator3 = polygon1.edges[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {\n var edge1 = _step3.value;\n var _iteratorNormalCompletion4 = true;\n var _didIteratorError4 = false;\n var _iteratorError4 = undefined;\n\n try {\n for (var _iterator4 = polygon2.edges[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {\n var edge2 = _step4.value;\n\n var _edge1$shape$distance = edge1.shape.distanceTo(edge2.shape),\n _edge1$shape$distance2 = _slicedToArray(_edge1$shape$distance, 2),\n dist = _edge1$shape$distance2[0],\n shortest_segment = _edge1$shape$distance2[1];\n\n if (Flatten.Utils.LT(dist, min_dist_and_segment[0])) {\n min_dist_and_segment = [dist, shortest_segment];\n }\n }\n } catch (err) {\n _didIteratorError4 = true;\n _iteratorError4 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion4 && _iterator4.return) {\n _iterator4.return();\n }\n } finally {\n if (_didIteratorError4) {\n throw _iteratorError4;\n }\n }\n }\n }\n } catch (err) {\n _didIteratorError3 = true;\n _iteratorError3 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion3 && _iterator3.return) {\n _iterator3.return();\n }\n } finally {\n if (_didIteratorError3) {\n throw _iteratorError3;\n }\n }\n }\n\n return min_dist_and_segment;\n }\n\n /**\r\n * Returns [mindist, maxdist] array of squared minimal and maximal distance between boxes\r\n * Minimal distance by x is\r\n * (box2.xmin - box1.xmax), if box1 is left to box2\r\n * (box1.xmin - box2.xmax), if box2 is left to box1\r\n * 0, if box1 and box2 are intersected by x\r\n * Minimal distance by y is defined in the same way\r\n *\r\n * Maximal distance is estimated as a sum of squared dimensions of the merged box\r\n *\r\n * @param box1\r\n * @param box2\r\n * @returns {Number | Number} - minimal and maximal distance\r\n */\n\n }, {\n key: \"box2box_minmax\",\n value: function box2box_minmax(box1, box2) {\n var mindist_x = Math.max(Math.max(box1.xmin - box2.xmax, 0), Math.max(box2.xmin - box1.xmax, 0));\n var mindist_y = Math.max(Math.max(box1.ymin - box2.ymax, 0), Math.max(box2.ymin - box1.ymax, 0));\n var mindist = mindist_x * mindist_x + mindist_y * mindist_y;\n\n var box = box1.merge(box2);\n var dx = box.xmax - box.xmin;\n var dy = box.ymax - box.ymin;\n var maxdist = dx * dx + dy * dy;\n\n return [mindist, maxdist];\n }\n }, {\n key: \"minmax_tree_process_level\",\n value: function minmax_tree_process_level(shape, level, min_stop, tree) {\n // Calculate minmax distance to each shape in current level\n // Insert result into the interval tree for further processing\n // update min_stop with maxdist, it will be the new stop distance\n var mindist = void 0,\n maxdist = void 0;\n var _iteratorNormalCompletion5 = true;\n var _didIteratorError5 = false;\n var _iteratorError5 = undefined;\n\n try {\n for (var _iterator5 = level[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {\n var node = _step5.value;\n\n // [mindist, maxdist] = Distance.box2box_minmax(shape.box, node.max);\n // if (Flatten.Utils.GT(mindist, min_stop))\n // continue;\n\n // Estimate min-max dist to the shape stored in the node.item, using node.item.key which is shape's box\n\n var _Distance$box2box_min3 = Distance.box2box_minmax(shape.box, node.item.key);\n\n var _Distance$box2box_min4 = _slicedToArray(_Distance$box2box_min3, 2);\n\n mindist = _Distance$box2box_min4[0];\n maxdist = _Distance$box2box_min4[1];\n\n if (node.item.value instanceof Flatten.Edge) {\n tree.insert([mindist, maxdist], node.item.value.shape);\n } else {\n tree.insert([mindist, maxdist], node.item.value);\n }\n if (Flatten.Utils.LT(maxdist, min_stop)) {\n min_stop = maxdist; // this will be the new distance estimation\n }\n }\n } catch (err) {\n _didIteratorError5 = true;\n _iteratorError5 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion5 && _iterator5.return) {\n _iterator5.return();\n }\n } finally {\n if (_didIteratorError5) {\n throw _iteratorError5;\n }\n }\n }\n\n if (level.length === 0) return min_stop;\n\n // Calculate new level from left and right children of the current\n var new_level_left = level.map(function (node) {\n return node.left.isNil() ? undefined : node.left;\n }).filter(function (node) {\n return node !== undefined;\n });\n var new_level_right = level.map(function (node) {\n return node.right.isNil() ? undefined : node.right;\n }).filter(function (node) {\n return node !== undefined;\n });\n // Merge left and right subtrees and leave only relevant subtrees\n var new_level = [].concat(_toConsumableArray(new_level_left), _toConsumableArray(new_level_right)).filter(function (node) {\n // Node subtree quick reject, node.max is a subtree box\n var _Distance$box2box_min = Distance.box2box_minmax(shape.box, node.max),\n _Distance$box2box_min2 = _slicedToArray(_Distance$box2box_min, 2),\n mindist = _Distance$box2box_min2[0],\n maxdist = _Distance$box2box_min2[1];\n\n return Flatten.Utils.LE(mindist, min_stop);\n });\n\n min_stop = Distance.minmax_tree_process_level(shape, new_level, min_stop, tree);\n return min_stop;\n }\n\n /**\r\n * Calculates sorted tree of [mindist, maxdist] intervals between query shape\r\n * and shapes of the planar set.\r\n * @param shape\r\n * @param set\r\n */\n\n }, {\n key: \"minmax_tree\",\n value: function minmax_tree(shape, set, min_stop) {\n var tree = new IntervalTree();\n var level = [set.index.root];\n var squared_min_stop = min_stop < Number.POSITIVE_INFINITY ? min_stop * min_stop : Number.POSITIVE_INFINITY;\n squared_min_stop = Distance.minmax_tree_process_level(shape, level, squared_min_stop, tree);\n return tree;\n }\n }, {\n key: \"minmax_tree_calc_distance\",\n value: function minmax_tree_calc_distance(shape, node, min_dist_and_segment) {\n var min_dist_and_segment_new = void 0,\n stop = void 0;\n if (node != null && !node.isNil()) {\n var _Distance$minmax_tree = Distance.minmax_tree_calc_distance(shape, node.left, min_dist_and_segment);\n\n var _Distance$minmax_tree2 = _slicedToArray(_Distance$minmax_tree, 2);\n\n min_dist_and_segment_new = _Distance$minmax_tree2[0];\n stop = _Distance$minmax_tree2[1];\n\n\n if (stop) {\n return [min_dist_and_segment_new, stop];\n }\n\n if (Flatten.Utils.LT(min_dist_and_segment_new[0], Math.sqrt(node.item.key.low))) {\n return [min_dist_and_segment_new, true]; // stop condition\n }\n\n var _Distance$distance = Distance.distance(shape, node.item.value),\n _Distance$distance2 = _slicedToArray(_Distance$distance, 2),\n dist = _Distance$distance2[0],\n shortest_segment = _Distance$distance2[1];\n // console.log(dist)\n\n\n if (Flatten.Utils.LT(dist, min_dist_and_segment_new[0])) {\n min_dist_and_segment_new = [dist, shortest_segment];\n }\n\n var _Distance$minmax_tree3 = Distance.minmax_tree_calc_distance(shape, node.right, min_dist_and_segment_new);\n\n var _Distance$minmax_tree4 = _slicedToArray(_Distance$minmax_tree3, 2);\n\n min_dist_and_segment_new = _Distance$minmax_tree4[0];\n stop = _Distance$minmax_tree4[1];\n\n\n return [min_dist_and_segment_new, stop];\n }\n\n return [min_dist_and_segment, false];\n }\n\n /**\r\n * Calculates distance between shape and Planar Set of shapes\r\n * @param shape\r\n * @param {PlanarSet} set\r\n * @param {Number} min_stop\r\n * @returns {*}\r\n */\n\n }, {\n key: \"shape2planarSet\",\n value: function shape2planarSet(shape, set) {\n var min_stop = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : Number.POSITIVE_INFINITY;\n\n var min_dist_and_segment = [min_stop, new Flatten.Segment()];\n var stop = false;\n if (set instanceof Flatten.PlanarSet) {\n var tree = Distance.minmax_tree(shape, set, min_stop);\n\n var _Distance$minmax_tree5 = Distance.minmax_tree_calc_distance(shape, tree.root, min_dist_and_segment);\n\n var _Distance$minmax_tree6 = _slicedToArray(_Distance$minmax_tree5, 2);\n\n min_dist_and_segment = _Distance$minmax_tree6[0];\n stop = _Distance$minmax_tree6[1];\n }\n return min_dist_and_segment;\n }\n }, {\n key: \"sort\",\n value: function sort(dist_and_segment) {\n dist_and_segment.sort(function (d1, d2) {\n if (Flatten.Utils.LT(d1[0], d2[0])) {\n return -1;\n }\n if (Flatten.Utils.GT(d1[0], d2[0])) {\n return 1;\n }\n return 0;\n });\n }\n }, {\n key: \"distance\",\n value: function distance(shape1, shape2) {\n return shape1.distanceTo(shape2);\n }\n }]);\n\n return Distance;\n }();\n};"},"hash":"ffca14939e769674bd48c4a099acf6db","cacheData":{"env":{}}}