UNPKG

kitchen-simulator

Version:

It is a kitchen simulator (self-contained micro-frontend).

1,435 lines (1,408 loc) 88.4 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.ContainsPoint = ContainsPoint; exports._twoLineSegmentsIntersection = _twoLineSegmentsIntersection; exports.absAngleBetweenTwoPoints = absAngleBetweenTwoPoints; exports.almostEqual = void 0; exports.angleBetweenTwoLines = angleBetweenTwoLines; exports.angleBetweenTwoPoints = angleBetweenTwoPoints; exports.angleBetweenTwoPointsAndOrigin = angleBetweenTwoPointsAndOrigin; exports.buildRectFromLines = buildRectFromLines; exports.calcCreateSnap = calcCreateSnap; exports.calcSnap = calcSnap; exports.calcSnap1 = calcSnap1; exports.calcSnap2 = calcSnap2; exports.calcSnap3 = calcSnap3; exports.clone_point = clone_point; exports.closestPointFromLine = closestPointFromLine; exports.closestPointFromLineSegment = closestPointFromLineSegment; exports.compareVertices = compareVertices; exports.containLine = containLine; exports.containPointInRect = containPointInRect; exports.cosWithThreshold = cosWithThreshold; exports.crossprod = crossprod; exports.diff = diff; exports.distancePointFromLine = distancePointFromLine; exports.distancePointFromLineSegment = distancePointFromLineSegment; exports.dotprod = dotprod; exports.downcrossLine = downcrossLine; exports.extendLine = extendLine; exports.findCatalogElement = findCatalogElement; exports.getAllArea = getAllArea; exports.getAllAreaLines = getAllAreaLines; exports.getAllCurSnap = getAllCurSnap; exports.getAllHoleRect = getAllHoleRect; exports.getAllItemSnap = getAllItemSnap; exports.getAllItemSpecified = getAllItemSpecified; exports.getAllItems = getAllItems; exports.getAllLineSnap = getAllLineSnap; exports.getAllLines = getAllLines; exports.getCalcRectFromItem = getCalcRectFromItem; exports.getCalcRectFromItem3D = getCalcRectFromItem3D; exports.getCalcRectFromLine = getCalcRectFromLine; exports.getCentroidOfPolygon = getCentroidOfPolygon; exports.getHoleItems = getHoleItems; exports.getInterSect = getInterSect; exports.getLineInterSect = getLineInterSect; exports.getNormaline = getNormaline; exports.getPoylgonPoints = getPoylgonPoints; exports.getRelatedLines = void 0; exports.getRelatedVertices = getRelatedVertices; exports.horizontalLine = horizontalLine; exports.intersectRect = intersectRect; exports.isBackWall = isBackWall; exports.isFrontWall = isFrontWall; exports.isLeftWall = isLeftWall; exports.isPointInArea = isPointInArea; exports.isPointInRect = isPointInRect; exports.isPointOnLineSegment = isPointOnLineSegment; exports.isRightWall = isRightWall; exports.isSnappedLine = isSnappedLine; exports.isSnappedSideLine = isSnappedSideLine; exports.itemInfo = itemInfo; exports.linePassingThroughTwoPoints = linePassingThroughTwoPoints; exports.mapRange = mapRange; exports.maxVertex = maxVertex; exports.midPoint = midPoint; exports.minVertex = minVertex; exports.needSnap = needSnap; exports.orderVertices = orderVertices; exports.pointPositionOnLineSegment = pointPositionOnLineSegment; exports.pointsDistance = pointsDistance; exports.relationshipOfTwoOverlappedLines = relationshipOfTwoOverlappedLines; exports.relationshipOfTwoOverlappedLines1 = relationshipOfTwoOverlappedLines1; exports.relationshipOfTwoOverlappedLines2 = relationshipOfTwoOverlappedLines2; exports.rotatePointAroundPoint = rotatePointAroundPoint; exports.roundVertex = roundVertex; exports.sameDistances = sameDistances; exports.sameMDistances = sameMDistances; exports.sameMPoints = sameMPoints; exports.samePoints = samePoints; exports.shrinkRect = shrinkRect; exports.sinWithThreshold = sinWithThreshold; exports.snapAngleByUnit = snapAngleByUnit; exports.twoLineSegmentsIntersection = twoLineSegmentsIntersection; exports.twoLinesIntersection = twoLinesIntersection; exports.upcrossLine = upcrossLine; exports.validInterSect = validInterSect; exports.validRect = validRect; exports.validSnap = validSnap; exports.validateLineSnaps = validateLineSnaps; exports.validateSnaps = validateSnaps; exports.verticalLine = verticalLine; exports.verticesDistance = verticesDistance; exports.verticesMidPoint = verticesMidPoint; var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _math = require("./math.js"); var _constants = require("../constants"); var _convertUnitsLite = require("./convert-units-lite"); var Three = _interopRequireWildcard(require("three")); var _utils = require("../components/viewer2d/utils.js"); var _helper = require("./helper.js"); var _export = require("./export.js"); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } /** @description Determines the distance between two points * @param {number} x0 Vertex 0 x * @param {number} y0 Vertex 0 y * @param {number} x1 Vertex 1 x * @param {number} y1 Vertex 1 y * @return {number} */ function compareVertices(v0, v1) { return v0.x === v1.x ? v0.y - v1.y : v0.x - v1.x; } function minVertex(v0, v1) { return compareVertices(v0, v1) > 0 ? v1 : v0; } function maxVertex(v0, v1) { return compareVertices(v0, v1) > 0 ? v0 : v1; } function orderVertices(vertices) { return vertices.sort(compareVertices); } function pointsDistance(x0, y0, x1, y1) { var diff_x = x0 - x1; var diff_y = y0 - y1; return Math.sqrt(diff_x * diff_x + diff_y * diff_y); } function verticesDistance(v1, v2) { var x0 = v1.x, y0 = v1.y; var x1 = v2.x, y1 = v2.y; return pointsDistance(x0, y0, x1, y1); } function horizontalLine(y) { return { a: 0, b: 1, c: -y }; } var almostEqual = exports.almostEqual = function almostEqual(x, y) { return Math.abs(x - y) < _constants.EPSILON; }; function verticalLine(x) { return { a: 1, b: 0, c: -x }; } function upcrossLine(x, y) { return { a: 1, b: 1, c: -x - y }; } function downcrossLine(x, y) { return { a: 1, b: -1, c: -x + y }; } function linePassingThroughTwoPoints(x1, y1, x2, y2) { if (x1 === x2 && y1 == y2) throw new Error('Geometry error'); //if (x1 === x2) return verticalLine(x1); //if (y1 === y2) return horizontalLine(y1); return { a: y1 - y2, b: x2 - x1, c: y2 * x1 - x2 * y1 }; } function getNormaline(x1, y1, x2, y2) { var lineFunction = linePassingThroughTwoPoints(x1, y1, x2, y2); return { x: lineFunction.a / Math.sqrt(lineFunction.a * lineFunction.a + lineFunction.b * lineFunction.b), y: lineFunction.b / Math.sqrt(lineFunction.a * lineFunction.a + lineFunction.b * lineFunction.b) }; } function distancePointFromLine(a, b, c, x, y) { //https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line return (0, _math.fAbs)(a * x + b * y + c) / Math.sqrt(a * a + b * b); } function closestPointFromLine(a, b, c, x, y) { //https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line var denom = a * a + b * b; return { x: (b * (b * x - a * y) - a * c) / denom, y: (a * -b * x + a * y - b * c) / denom }; } /** @description Get point of intersection between two lines using ax+by+c line's equation * @param {number} a x coefficent of first line * @param {number} b y coefficent of first line * @param {number} c costant of first line * @param {number} j x coefficent of second line * @param {number} k y coefficent of second line * @param {number} l costant of second line * @return {object} {x,y} point's coordinates */ function twoLinesIntersection(a, b, c, j, k, l) { var angularCoefficientsDiff = b * j - a * k; if (angularCoefficientsDiff === 0) return undefined; //no intersection var y = (a * l - c * j) / angularCoefficientsDiff; var x = (c * k - b * l) / angularCoefficientsDiff; return { x: x, y: y }; } function twoLineSegmentsIntersection(p1, p2, p3, p4) { return _twoLineSegmentsIntersection(p1, p2, p3.toJS(), p4.toJS()); } function _twoLineSegmentsIntersection(p1, p2, p3, p4) { //https://github.com/psalaets/line-intersect/blob/master/lib/check-intersection.js var x1 = p1.x, y1 = p1.y; var x2 = p2.x, y2 = p2.y; var x3 = p3.x, y3 = p3.y; var x4 = p4.x, y4 = p4.y; var denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1); var numA = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3); var numB = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3); if ((0, _math.fAbs)(denom) <= _constants.EPSILON) { if ((0, _math.fAbs)(numA) <= _constants.EPSILON && (0, _math.fAbs)(numB) <= _constants.EPSILON) { var comparator = function comparator(pa, pb) { return pa.x === pb.x ? pa.y - pb.y : pa.x - pb.x; }; var line0 = [p1, p2].sort(comparator); var line1 = [p3, p4].sort(comparator); var _sort = [line0, line1].sort(function (lineA, lineB) { return comparator(lineA[0], lineB[0]); }), _sort2 = (0, _slicedToArray2["default"])(_sort, 2), lineSX = _sort2[0], lineDX = _sort2[1]; comparator(lineSX[1], lineDX[0]) < 0 ? 'colinear' : 'none'; if (lineSX[1].x === lineDX[0].x) { return { type: lineDX[0].y <= lineSX[1].y ? 'colinear' : 'none' }; } else { return { type: lineDX[0].x <= lineSX[1].x ? 'colinear' : 'none' }; } } return { type: 'parallel' }; } var uA = numA / denom; var uB = numB / denom; if (uA >= 0 - _constants.EPSILON && uA <= 1 + _constants.EPSILON && uB >= 0 - _constants.EPSILON && uB <= 1 + _constants.EPSILON) { var _point = { x: x1 + uA * (x2 - x1), y: y1 + uA * (y2 - y1) }; return { type: 'intersecting', point: _point }; } return { type: 'none' }; } function distancePointFromLineSegment(v1, v2, xp, yp) { //http://stackoverflow.com/a/6853926/1398836 var x1 = v1.x, y1 = v1.y; var x2 = v2.x, y2 = v2.y; var A = xp - x1; var B = yp - y1; var C = x2 - x1; var D = y2 - y1; var dot = A * C + B * D; var len_sq = C * C + D * D; var param = -1; if (len_sq != 0) //in case of 0 length line param = dot / len_sq; var xx, yy; if (param < 0) { xx = x1; yy = y1; } else if (param > 1) { xx = x2; yy = y2; } else { xx = x1 + param * C; yy = y1 + param * D; } var dx = xp - xx; var dy = yp - yy; return Math.sqrt(dx * dx + dy * dy); } /** * * @param x1 {number} x for first vertex of the segment * @param y1 {number} y for first vertex of the segment * @param x2 {number} x for second vertex of the segment * @param y2 {number} y for second vertex of the segment * @param xp {number} x for point we want to verify * @param yp {number} y for point we want to verify * @param maxDistance {number} the epsilon value used for comparisons * @returns {boolean} true if the point lies on the line segment false otherwise */ function isPointOnLineSegment(x1, y1, x2, y2, xp, yp) { var maxDistance = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : _constants.EPSILON; return distancePointFromLineSegment({ x: x1, y: y1 }, { x: x2, y: y2 }, xp, yp) <= maxDistance; } function closestPointFromLineSegment(x1, y1, x2, y2, xp, yp) { if (x1 === x2) return { x: x1, y: yp }; if (y1 === y2) return { x: xp, y: y1 }; var m = (y2 - y1) / (x2 - x1); var q = y1 - m * x1; var mi = -1 / m; var qi = yp - mi * xp; var x = (qi - q) / (m - mi); var y = m * x + q; return { x: x, y: y }; } function pointPositionOnLineSegment(x1, y1, x2, y2, xp, yp) { var length = pointsDistance(x1, y1, x2, y2); var distance = pointsDistance(x1, y1, xp, yp); var offset = distance / length; /* if (x1 > x2) offset = 1 - offset; if (y1 > y2) offset = 1 - offset; */ return offset; } function mapRange(value, low1, high1, low2, high2) { return low2 + (high2 - low2) * (value - low1) / (high1 - low1); } function angleBetweenTwoPointsAndOrigin(x1, y1, x2, y2) { return -Math.atan2(y1 - y2, x2 - x1) * 180 / Math.PI; } function angleBetweenTwoPoints(x1, y1, x2, y2) { return Math.atan2(y2 - y1, x2 - x1); } function angleBetweenTwoLines(line, drawingLine, vertices) { var points = []; // safety guards var lv = Array.isArray(line === null || line === void 0 ? void 0 : line.vertices) ? line.vertices : []; var dv = Array.isArray(drawingLine === null || drawingLine === void 0 ? void 0 : drawingLine.vertices) ? drawingLine.vertices : []; // 1) push common vertices (in order of line.vertices) var _iterator = _createForOfIteratorHelper(lv), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var vt = _step.value; if (dv.includes(vt) && !points.includes(vt)) points.push(vt); } // 2) push remaining vertices from line.vertices } catch (err) { _iterator.e(err); } finally { _iterator.f(); } var _iterator2 = _createForOfIteratorHelper(lv), _step2; try { for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) { var _vt = _step2.value; if (!points.includes(_vt)) points.push(_vt); } // 3) push remaining vertices from drawingLine.vertices } catch (err) { _iterator2.e(err); } finally { _iterator2.f(); } var _iterator3 = _createForOfIteratorHelper(dv), _step3; try { for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) { var _vt2 = _step3.value; if (!points.includes(_vt2)) points.push(_vt2); } // If no points at all, nothing to compute — return 0 (safe fallback) } catch (err) { _iterator3.e(err); } finally { _iterator3.f(); } if (points.length === 0) return 0; // Ensure we have at least 3 entries (same behaviour as original) while (points.length < 3) points.push(points[points.length - 1]); var _points$slice$map = points.slice(0, 3).map(function (idx) { var v = vertices === null || vertices === void 0 ? void 0 : vertices[idx]; return v ? new Three.Vector2(v.x, v.y) : new Three.Vector2(0, 0); }), _points$slice$map2 = (0, _slicedToArray2["default"])(_points$slice$map, 3), c = _points$slice$map2[0], p1 = _points$slice$map2[1], p2 = _points$slice$map2[2]; var vec1 = p1.clone().sub(c).normalize(); var vec2 = p2.clone().sub(c).normalize(); return Math.floor(vec1.angle() * 180 / Math.PI - vec2.angle() * 180 / Math.PI + 0.5); } var getRelatedLines = exports.getRelatedLines = function getRelatedLines(tlines, drawingLine, vertices, lines) { var exceptLineId = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null; if (!(drawingLine !== null && drawingLine !== void 0 && drawingLine.vertices) || !Array.isArray(drawingLine.vertices)) return; var seen = new Set(); var _iterator4 = _createForOfIteratorHelper(drawingLine.vertices), _step4; try { for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) { var vIdx = _step4.value; var vertex = vertices === null || vertices === void 0 ? void 0 : vertices[vIdx]; if (!(vertex !== null && vertex !== void 0 && vertex.lines)) continue; var _iterator5 = _createForOfIteratorHelper(vertex.lines), _step5; try { for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) { var lineId = _step5.value; if (lineId !== drawingLine.id && lineId !== exceptLineId && !(0, _helper.isEmpty)(lines === null || lines === void 0 ? void 0 : lines[lineId]) && !seen.has(lineId)) { seen.add(lineId); tlines.push(lines[lineId]); } } } catch (err) { _iterator5.e(err); } finally { _iterator5.f(); } } } catch (err) { _iterator4.e(err); } finally { _iterator4.f(); } }; function snapAngleByUnit(lineAngle, vertices, drawingLine, x, y, dragVertexId) { var tx, ty; var absAngle = Math.abs(lineAngle); // angle snapping as a value of UNIT_ANGLE var rest = absAngle % _constants.UNIT_ANGLE; var missAngle = _constants.UNIT_ANGLE - rest; var isSingleLine = !drawingLine.vertices.some(function (vetID) { return vertices[vetID].lines.some(function (lineID) { return lineID !== drawingLine.id; }); }); // the origin point of rotation(snapping) var originVerIndex = drawingLine.vertices.findIndex(function (vertice) { return vertice !== dragVertexId; }); var originVerId = originVerIndex < 0 ? drawingLine.vertices[0] : drawingLine.vertices[originVerIndex]; var ox = vertices[originVerId].x; var oy = vertices[originVerId].y; // check whether the line is snapped to before point. if (rest <= _constants.UNIT_ANGLE / 2) { // determine the direction of rotation. rest = lineAngle > 0 ? rest : -rest; rest = isSingleLine ? -rest : rest; // rotate the current point to last point around the first point of drawing line. tx = rotatePointAroundPoint(x, y, ox, oy, rest).x; ty = rotatePointAroundPoint(x, y, ox, oy, rest).y; } // check whether the line is snapped to next new point. else if (rest > _constants.UNIT_ANGLE / 2) { // determine the direction of rotation. missAngle = lineAngle > 0 ? -missAngle : missAngle; missAngle = isSingleLine ? -missAngle : missAngle; // rotate the current point to last point around the first point of drawing line. tx = rotatePointAroundPoint(x, y, ox, oy, missAngle).x; ty = rotatePointAroundPoint(x, y, ox, oy, missAngle).y; } var resPoint = { x: tx, y: ty }; return resPoint; } function absAngleBetweenTwoPoints(x1, y1, x2, y2) { return Math.atan2(y2 - y1, Math.abs(x2 - x1)); } function samePoints(_ref, _ref2) { var x1 = _ref.x, y1 = _ref.y; var x2 = _ref2.x, y2 = _ref2.y; return (0, _math.fAbs)(x1 - x2) <= _constants.EPSILON && (0, _math.fAbs)(y1 - y2) <= _constants.EPSILON; } function sameDistances(dis1, dis2) { return (0, _math.fAbs)(dis1 - dis2) <= _constants.EPSILON; } function sameMPoints(_ref3, _ref4) { var x1 = _ref3.x, y1 = _ref3.y; var x2 = _ref4.x, y2 = _ref4.y; return (0, _math.fAbs)(x1 - x2) <= _constants.MEPSILON && (0, _math.fAbs)(y1 - y2) <= _constants.MEPSILON; } function sameMDistances(dis1, dis2) { return (0, _math.fAbs)(dis1 - dis2) <= _constants.MEPSILON; } function isPointInRect(rect, point) { var result = true; for (var i = 0; i < rect.length; i++) { var pos1 = rect[i]; var pos2 = rect[(i + 1) % rect.length]; if (isPointOnLineSegment(pos1.x, pos1.y, pos2.x, pos2.y, point.x, point.y)) { result = false; } } return result; } /** @description Extend line based on coordinates and new line length * @param {number} x1 Vertex 1 x * @param {number} y1 Vertex 1 y * @param {number} x2 Vertex 2 x * @param {number} y2 Vertex 2 y * @param {number} newDistance New line length * @return {object} */ function extendLine(x1, y1, x2, y2, newDistance) { var precision = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 6; var rad = angleBetweenTwoPoints(x1, y1, x2, y2); return { x: (0, _math.toFixedFloat)(x1 + Math.cos(rad) * newDistance, precision), y: (0, _math.toFixedFloat)(y1 + Math.sin(rad) * newDistance, precision) }; } function roundVertex(vertex) { var precision = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 6; vertex.set('x', (0, _math.toFixedFloat)(vertex.get('x'), precision)); vertex.set('y', (0, _math.toFixedFloat)(vertex.get('y'), precision)); return vertex; } //https://github.com/MartyWallace/PolyK function ContainsPoint(polygon, pointX, pointY) { var n = polygon.length >> 1; var ax, lup; var ay = polygon[2 * n - 3] - pointY; var bx = polygon[2 * n - 2] - pointX; var by = polygon[2 * n - 1] - pointY; if (bx === 0 && by === 0) return false; // point on edge // let lup = by > ay; for (var ii = 0; ii < n; ii++) { ax = bx; ay = by; bx = polygon[2 * ii] - pointX; by = polygon[2 * ii + 1] - pointY; if (bx === 0 && by === 0) return false; // point on edge if (ay === by) continue; lup = by > ay; } var depth = 0; for (var i = 0; i < n; i++) { ax = bx; ay = by; bx = polygon[2 * i] - pointX; by = polygon[2 * i + 1] - pointY; if (ay < 0 && by < 0) continue; // both 'up' or both 'down' if (ay > 0 && by > 0) continue; // both 'up' or both 'down' if (ax < 0 && bx < 0) continue; // both points on the left if (ay === by && Math.min(ax, bx) < 0) return true; if (ay === by) continue; var lx = ax + (bx - ax) * -ay / (by - ay); if (lx === 0) return false; // point on edge if (lx > 0) depth++; if (ay === 0 && lup && by > ay) depth--; // hit vertex, both up if (ay === 0 && !lup && by < ay) depth--; // hit vertex, both down lup = by > ay; } return (depth & 1) === 1; } function cosWithThreshold(alpha, threshold) { var cos = Math.cos(alpha); return cos < threshold ? 0 : cos; } function sinWithThreshold(alpha, threshold) { var sin = Math.sin(alpha); return sin < threshold ? 0 : sin; } function midPoint(x1, y1, x2, y2) { return { x: (x1 + x2) / 2, y: (y1 + y2) / 2 }; } function verticesMidPoint(verticesArray) { var res = verticesArray.reduce(function (incr, vertex) { return { x: incr.x + vertex.x, y: incr.y + vertex.y }; }, { x: 0, y: 0 }); return { x: res.x / verticesArray.length, y: res.y / verticesArray.length }; } function rotatePointAroundPoint(px, py, ox, oy, theta) { var thetaRad = theta * Math.PI / 180; var cos = Math.cos(thetaRad); var sin = Math.sin(thetaRad); var deltaX = px - ox; var deltaY = py - oy; return { x: cos * deltaX - sin * deltaY + ox, y: sin * deltaX + cos * deltaY + oy }; } // point: x,y // itemrectInfo: pos(x,y),rotRad,size,layoutpos,is_corner // calcRect: rect(point[4]),pos(x,y),rotRad,size,layoutpos,is_corner function point(x, y) { return { x: x, y: y }; } function itemrectInfo(x, y, rotRad, size, layoutpos, is_corner) { return { pos: { x: x, y: y }, rotRad: rotRad, size: size, layoutpos: layoutpos, is_corner: is_corner }; } function getCalcRectFromItem(item) { var itemInfo; if (item === undefined) itemInfo = [];else itemInfo = item.item; var x = item.pos.x; var y = item.pos.y; var rotRad = item.rotRad; var w = item.size && item.size.width / 2; var h = item.size && item.size.height / 2; var mx = x - w * Math.cos(rotRad); var my = y - w * Math.sin(rotRad); var x0 = mx + h * Math.sin(rotRad); var y0 = my - h * Math.cos(rotRad); var x3 = mx * 2 - x0; var y3 = my * 2 - y0; var x1 = x * 2 - x3; var y1 = y * 2 - y3; var x2 = x * 2 - x0; var y2 = y * 2 - y0; return { rect: [point(x0, y0), point(x1, y1), point(x2, y2), point(x3, y3)], pos: point(x, y), rotRad: rotRad, size: item.size, layoutpos: item.layoutpos, is_corner: item.is_corner, itemInfo: itemInfo }; } function getCalcRectFromItem3D(item) { var itemInfo; if (item === undefined) itemInfo = [];else itemInfo = item.item; var x = item.pos.x; var y = item.pos.y; var rotRad = item.rotRad; var w = item.size.width / 2; var h = item.size.depth / 2; var mx = x - w * Math.cos(rotRad); var my = y - w * Math.sin(rotRad); var x0 = mx + h * Math.sin(rotRad); var y0 = my - h * Math.cos(rotRad); var x3 = mx * 2 - x0; var y3 = my * 2 - y0; var x1 = x * 2 - x3; var y1 = y * 2 - y3; var x2 = x * 2 - x0; var y2 = y * 2 - y0; return { rect: [point(x0, y0), point(x1, y1), point(x2, y2), point(x3, y3)], pos: point(x, y), rotRad: rotRad, size: item.size, layoutpos: item.layoutpos, is_corner: item.is_corner, itemInfo: itemInfo }; } function getAllItems(scene, catalog, allLineRects) { var layerID = scene.selectedLayer; var layer = scene.layers.get(layerID); var curiteminfo; var iteminfo = []; var otherItems = []; var selectedItem; var currentItem; if (layer.selected.items.size > 0) { selectedItem = layer.getIn(['items', layer.selected.items.get(0)]); var catid = selectedItem.type; var cat = catalog.elements[catid]; if (!cat) cat = catalog.elements[(0, _utils.returnReplaceableDeepSearchType)(catid)]; currentItem = { selectedItem: selectedItem, cat: cat }; } layer.items.forEach(function (item) { var val = { pos: { x: item.x, y: item.y }, rotRad: item.rotation / 180 * Math.PI }; var catid = item.type; var cat = catalog.elements[catid]; if (!cat) { cat = catalog.elements[(0, _utils.returnReplaceableDeepSearchType)(catid)]; } var sizeinfo = []; var width, height, depth; sizeinfo = { width: item.properties.get('width').get('_length'), height: item.properties.get('height').get('_length'), depth: item.properties.get('depth').get('_length'), widthUnit: item.properties.get('width').get('_unit'), heightUnit: item.properties.get('height').get('_unit'), depthUnit: item.properties.get('depth').get('_unit') }; sizeinfo = _objectSpread(_objectSpread({}, sizeinfo), {}, { layoutpos: cat && cat.info.layoutpos, is_corner: cat && cat.info.is_corner }); width = (0, _convertUnitsLite.convert)(sizeinfo.width).from(sizeinfo.widthUnit).to(scene.unit); height = (0, _convertUnitsLite.convert)(sizeinfo.depth).from(sizeinfo.depthUnit).to(scene.unit); depth = (0, _convertUnitsLite.convert)(sizeinfo.height).from(sizeinfo.heightUnit).to(scene.unit); val.size = { width: width, height: height, depth: depth }; val.layoutpos = sizeinfo.layoutpos; val.is_corner = sizeinfo.is_corner; val.doorStyle = item.doorStyle; val.item = item; var otherItem = { item: item, cat: cat }; if (!needSnap(currentItem, otherItem)) { return; } if (item.selected) { curiteminfo = getCalcRectFromItem(val); } else { var calcrect = getCalcRectFromItem(val); calcrect.isSnappedLine = isSnappedLine(calcrect, allLineRects); iteminfo.push(calcrect); otherItems.push(otherItem); } }); return { cur: curiteminfo, others: iteminfo, currentItem: currentItem, otherItems: otherItems }; } function getAllItemSpecified(scene, catalog, filter) { var _scene$layers, _scene$layers$get; var layerID = scene === null || scene === void 0 ? void 0 : scene.selectedLayer; var layer = scene === null || scene === void 0 || (_scene$layers = scene.layers) === null || _scene$layers === void 0 || (_scene$layers$get = _scene$layers.get) === null || _scene$layers$get === void 0 ? void 0 : _scene$layers$get.call(_scene$layers, layerID); if (!layer || !layer.items) return { cur: null, others: [] }; var curiteminfo; var iteminfo = []; layer.items.forEach(function (item) { var _cat$obj; if (!item) return; var val = { pos: { x: item.x, y: item.y }, rotRad: item.rotation / 180 * Math.PI }; var cat = item.type ? findCatalogElement(catalog, item.type) : null; var info = cat === null || cat === void 0 ? void 0 : cat.info; var props = item.properties; var getSize = function getSize(key) { var _props$getIn; var length = props === null || props === void 0 || (_props$getIn = props.getIn) === null || _props$getIn === void 0 ? void 0 : _props$getIn.call(props, [key, '_length']); return length != null ? (0, _convertUnitsLite.convert)(length).from('in').to(scene.unit) : 0; }; val.size = { width: getSize('width'), height: getSize('height'), depth: getSize('depth') }; val.item = item; if (info) { val.layoutpos = info.layoutpos; val.is_corner = info.is_corner; } // Filter check if (Array.isArray(filter)) { if (info && !filter.includes(info.layoutpos)) return; } else if (info && (info.layoutpos !== filter || (cat === null || cat === void 0 ? void 0 : cat.type) === 'appliance' && ['Cook Top', 'Microwave'].includes(cat === null || cat === void 0 || (_cat$obj = cat.obj) === null || _cat$obj === void 0 ? void 0 : _cat$obj.category))) { return; } // Current vs others var rect = getCalcRectFromItem3D(val); if (item.selected) { curiteminfo = rect; } else { iteminfo.push(rect); } }); return { cur: curiteminfo, others: iteminfo }; } function findCatalogElement(catalog, elementName) { if (!elementName || !catalog) return null; var variants = [elementName, elementName.toLowerCase()]; var deepVariants = variants.map(function (v) { return (0, _utils.returnReplaceableDeepSearchType)(v); }).filter(Boolean); var allCandidates = [].concat(variants, (0, _toConsumableArray2["default"])(deepVariants)); var getElement = function getElement(catid) { if (!catid) return null; // Immutable.js Map if (typeof catalog.getIn === 'function') { return catalog.getIn(['elements', catid]); } // Plain JS object if (catalog.elements && catalog.elements[catid]) { return catalog.elements[catid]; } return null; }; var _iterator6 = _createForOfIteratorHelper(allCandidates), _step6; try { for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) { var name = _step6.value; var cat = getElement(name); if (cat) return cat; } } catch (err) { _iterator6.e(err); } finally { _iterator6.f(); } return null; } function isSnappedLine(calcrect, allLineRects) { if (allLineRects === undefined) return false; var r2 = calcrect.rect[2]; var r3 = calcrect.rect[3]; var result = allLineRects.some(function (linerect) { var l2 = linerect.rect[2]; var l3 = linerect.rect[3]; var delta = verticesDistance(l2, r3) + verticesDistance(r3, r2) + verticesDistance(r2, l3) - verticesDistance(l3, l2); if (delta < _constants.EPSILON) { return true; } else { l2 = linerect.rect[3]; l3 = linerect.rect[2]; delta = verticesDistance(l2, r3) + verticesDistance(r3, r2) + verticesDistance(r2, l3) - verticesDistance(l3, l2); return delta < _constants.EPSILON; } }); return result; } function isSnappedSideLine(calcrect, allLineRects) { if (allLineRects === undefined) return 0; var r2 = calcrect.rect[1]; var r3 = calcrect.rect[2]; var result = allLineRects.some(function (linerect) { var l2 = linerect.rect[2]; var l3 = linerect.rect[3]; var delta = verticesDistance(l2, r3) + verticesDistance(r3, r2) + verticesDistance(r2, l3) - verticesDistance(l3, l2); return delta < _constants.EPSILON; }); return result; } /** Calculate candidate positions */ function getAllItemSnap(allItemRects) { var allItemSnap = []; var cur = allItemRects.cur; // For development var otherItems = allItemRects.otherItems, currentItem = allItemRects.currentItem; allItemRects.others.forEach(function (rect, index) { var cw = cur && cur.size.width / 2; var ch = cur && cur.size.height / 2; var cos = Math.cos(rect.rotRad); var sin = Math.sin(rect.rotRad); var ox0 = cw * cos - ch * sin; // (cw, ch) rot var oy0 = cw * sin + ch * cos; var ox1 = -cw * cos - ch * sin; // (-cw, ch) rot var oy1 = -cw * sin + ch * cos; var ox2 = ch * sin - cw * cos; var oy2 = -ch * cos - cw * sin; var ox3 = ch * sin + cw * cos; var oy3 = -ch * cos + cw * sin; var nrot = rect.rotRad + Math.PI; if (nrot >= Math.PI) nrot -= Math.PI * 2; var snap1 = itemrectInfo(rect.rect[2].x + ox3, rect.rect[2].y + oy3, rect.rotRad, cur && cur.size, rect.layoutpos, rect.is_corner); var snap2 = itemrectInfo(rect.rect[3].x + ox2, rect.rect[3].y + oy2, rect.rotRad, cur && cur.size, rect.layoutpos, rect.is_corner); var snap3 = itemrectInfo(rect.rect[2].x + ox1, rect.rect[2].y + oy1, nrot, cur && cur.size, rect.layoutpos, rect.is_corner); var snap4 = itemrectInfo(rect.rect[3].x + ox0, rect.rect[3].y + oy0, nrot, cur && cur.size, rect.layoutpos, rect.is_corner); var sizeinfo = otherItems[index].cat && otherItems[index].cat.info.sizeinfo; if (sizeinfo) { var left_blind_length = sizeinfo.left_blind_length, right_blind_length = sizeinfo.right_blind_length; if (left_blind_length > 0) { var vx = left_blind_length - ch; var vy = cw; var dx = vx * cos + vy * sin; var dy = vx * sin - vy * cos; var snap6 = itemrectInfo(rect.rect[0].x + dx, rect.rect[0].y + dy, rect.rotRad + Math.PI / 2, cur && cur.size, rect.layoutpos, rect.is_corner); allItemSnap.push(snap6); } if (right_blind_length > 0) { var _vx = ch - right_blind_length; var _vy = cw; var _dx = _vx * cos + _vy * sin; var _dy = _vx * sin - _vy * cos; var snap7 = itemrectInfo(rect.rect[1].x + _dx, rect.rect[1].y + _dy, rect.rotRad - Math.PI / 2, cur && cur.size, rect.layoutpos, rect.is_corner); allItemSnap.push(snap7); } } if (rect.isSnappedLine) { snap1.isSnappedLine = true; snap2.isSnappedLine = true; } if (rect.is_corner) { var _nrot = rect.rotRad + Math.PI * 3 / 2; if (_nrot >= Math.PI) _nrot -= Math.PI * 2; var snap5 = itemrectInfo(rect.rect[1].x - oy1, rect.rect[1].y + ox1, _nrot, cur && cur.size, rect.layoutpos, rect.is_corner); allItemSnap.push(snap2); allItemSnap.push(snap5); } else { allItemSnap.push(snap1); allItemSnap.push(snap2); allItemSnap.push(snap3); allItemSnap.push(snap4); } }); return allItemSnap; } function getAllArea(layer) { var allAreaLines = []; var allLines = []; var verticesArray = []; var vertexID_to_verticesArrayIndex = {}; layer.vertices.forEach(function (vertex) { var verticesCount = verticesArray.push([vertex.x, vertex.y]); var latestVertexIndex = verticesCount - 1; vertexID_to_verticesArrayIndex[vertex.id] = latestVertexIndex; }); layer.areas.forEach(function (area) { allAreaLines.push(area.vertices); }); allAreaLines.forEach(function (area) { var pt = []; area.forEach(function (element) { pt.push({ x: verticesArray[vertexID_to_verticesArrayIndex[element]][0], y: verticesArray[vertexID_to_verticesArrayIndex[element]][1] }); }); allLines.push(pt); }); return allLines; } /** Get all lines of the scene */ function getAllLines(layer) { var allArea = getAllArea(layer); var allAreaLines = []; var allVertices = layer.get('vertices').toJS(); layer.lines.forEach(function (tline) { var line = tline.toJS(); if (isPointInArea(allArea, allVertices[line.vertices[0]]) || isPointInArea(allArea, allVertices[line.vertices[1]])) { allAreaLines.push(line.vertices.reverse()); } }); var allLines = []; //let allNonAreaLines = []; var thick = _constants.LINE_THICKNESS / 2; layer.lines.forEach(function (line) { var i = containLine(allAreaLines, line); // let thick = line.properties.getIn(['thickness', 'length']); if (i < 0) { var vertices = line.vertices.toJS(); var tmp_vertices = { x1: layer.vertices.get(vertices[0]).x, y1: layer.vertices.get(vertices[0]).y, x2: layer.vertices.get(vertices[1]).x, y2: layer.vertices.get(vertices[1]).y }; if (tmp_vertices.x1 == tmp_vertices.x2 && tmp_vertices.y1 == tmp_vertices.y2) return; var addIdx = allLines.length; var flag = 0; allLines.forEach(function (element, idx) { if (flag == 0) { var el = element[0]; var tmp_el = { x1: layer.vertices.get(el[0]).x, y1: layer.vertices.get(el[0]).y, x2: layer.vertices.get(el[1]).x, y2: layer.vertices.get(el[1]).y }; if (tmp_el.x1 == tmp_vertices.x1 && tmp_el.y1 == tmp_vertices.y1) { var tmp = vertices[0]; vertices[0] = vertices[1]; vertices[1] = tmp; addIdx = idx == 0 ? 0 : idx - 1; flag = 1; } else if (tmp_el.x2 == tmp_vertices.x1 && tmp_el.y2 == tmp_vertices.y1) { addIdx = idx; flag = 1; } else if (tmp_el.x1 == tmp_vertices.x2 && tmp_el.y1 == tmp_vertices.y2) { addIdx = idx == 0 ? 0 : idx - 1; flag = 1; } else if (tmp_el.x2 == tmp_vertices.x2 && tmp_el.y2 == tmp_vertices.y2) { var _tmp = vertices[0]; vertices[0] = vertices[1]; vertices[1] = _tmp; addIdx = idx; flag = 1; } } }); allLines.splice(addIdx, 0, [vertices, thick]); } else { allLines.push([allAreaLines[i], thick]); } }); return allLines; } /** Get lines that wraps the area */ function getAllAreaLines(layer) { var areainfo = []; layer.areas.forEach(function (area) { var sz = area.vertices.size; for (var i = 0; i < sz; i++) { areainfo.push([area.vertices.get(i), area.vertices.get((i + 1) % sz)]); } }); return areainfo; } function containLine(lines, line) { // lines: [array] var sz = lines.length; for (var i = 0; i < sz; i++) { var l = lines[i]; if (line.vertices.get(0) == l[0] && line.vertices.get(1) == l[1] || line.vertices.get(1) == l[0] && line.vertices.get(0) == l[1]) { return i; } } return -1; } function buildRectFromLines(layer, lines) { var rect = []; lines.forEach(function (line) { var vxys = []; // 0: x0, 1: y0, 2: x1, 3: y1 line[0].forEach(function (vertex) { var vert = layer.vertices.get(vertex); vxys.push(vert.x); vxys.push(vert.y); }); var thick = line[1]; var x0 = vxys[0]; var y0 = vxys[1]; var x1 = vxys[2]; var y1 = vxys[3]; rect.push(getCalcRectFromLine(x0, y0, x1, y1, thick, layer)); }); return rect; } function getRelatedVertices(x0, y0, x1, y1, layer) { var verticesArray = []; var mapVertIDtoIndex = {}; layer.vertices.forEach(function (vertex) { var verticesCount = verticesArray.push([vertex.x, vertex.y]); var latestVertexIndex = verticesCount - 1; mapVertIDtoIndex[vertex.id] = latestVertexIndex; }); var relVerts = []; layer.lines.some(function (line) { var vertID0 = line.vertices.get(0); var vertID1 = line.vertices.get(1); var pt0 = { x: verticesArray[mapVertIDtoIndex[vertID0]][0], y: verticesArray[mapVertIDtoIndex[vertID0]][1] }; var pt1 = { x: verticesArray[mapVertIDtoIndex[vertID1]][0], y: verticesArray[mapVertIDtoIndex[vertID1]][1] }; if (Math.abs(pt0.x - x0) < _constants.EPSILON && Math.abs(pt0.y - y0) < _constants.EPSILON && Math.abs(pt1.x - x1) < _constants.EPSILON && Math.abs(pt1.y - y1) < _constants.EPSILON || Math.abs(pt0.x - x1) < _constants.EPSILON && Math.abs(pt0.y - y1) < _constants.EPSILON && Math.abs(pt1.x - x0) < _constants.EPSILON && Math.abs(pt1.y - y0) < _constants.EPSILON) { if (line.relatedVertices.size == 2) { var relPt0 = point(x0, y0); var relPt1 = point(x1, y1); line.relatedVertices.forEach(function (relatedVertice, index) { if (relatedVertice.index == undefined) relatedVertice = relatedVertice.toJSON(); if (relatedVertice.index == 0) relPt0 = point(relatedVertice.point.x, relatedVertice.point.y);else relPt1 = point(relatedVertice.point.x, relatedVertice.point.y); }); relVerts.push(relPt0); relVerts.push(relPt1); } return true; } }); return relVerts; } function getCalcRectFromLine(x0, y0, x1, y1, thick, layer) { // get line from vertex coordinate var relVerts = getRelatedVertices(x0, y0, x1, y1, layer); var dx = x1 - x0; var dy = y1 - y0; var dl = Math.sqrt(dx * dx + dy * dy); var ox = -dy / dl * thick; var oy = dx / dl * thick; var rot = Math.atan2(dy, dx); if (relVerts.length == 2) { var vN = point(ox, oy); var vR = point(relVerts[0].x - x0, relVerts[0].y - y0); if (dotprod(vN, vR) < 0) { ox = -ox; oy = -oy; } else { rot += Math.PI; } } else { ox = -ox; oy = -oy; } return { rectEnd: [point(x0 + ox / 2, y0 + oy / 2), point(x1 + ox / 2, y1 + oy / 2)], rect: [point(x0 + ox, y0 + oy), point(x1 + ox, y1 + oy), point(x1, y1), point(x0, y0)], pos: point((x0 + x1 + ox) / 2, (y0 + y1 + ox) / 2), rotRad: rot, size: { width: dl, height: thick / 2 } }; } function getAllLineSnap(allLineRects, curItemRect) { var allLineSnap = []; var cur = curItemRect; if (cur === undefined || cur === null) return;else allLineRects.forEach(function (rect) { var cw = cur.size.width / 2; var ch = cur.size.height / 2; var cos = Math.cos(rect.rotRad); var sin = Math.sin(rect.rotRad); var ox0 = cw * cos - ch * sin; // (cw, ch) rot var oy0 = cw * sin + ch * cos; var ox1 = -cw * cos - ch * sin; // (-cw, ch) rot var oy1 = -cw * sin + ch * cos; var nrot = rect.rotRad + Math.PI; if (nrot >= Math.PI) nrot -= Math.PI * 2; var thick = rect.size.height; var snap3 = itemInfo(rect.rect[2].x + ox1, rect.rect[2].y + oy1, nrot, cur.size); var snap4 = itemInfo(rect.rect[3].x + ox0, rect.rect[3].y + oy0, nrot, cur.size); if (!cur.is_corner) { allLineSnap.push(snap3); } allLineSnap.push(snap4); }); return allLineSnap; } function validateSnaps(allSnaps, allRects) { var validSnaps = []; if (allSnaps !== undefined && allSnaps !== null && allSnaps.length > 0) allSnaps.forEach(function (snap) { if (validSnap(snap, allRects)) { validSnaps.push(snap); } }); return validSnaps; } function validateLineSnaps(allSnaps, allItemSnap, allLineSnap, allItemRects, allLineRects, allRects) { var validSnaps = []; var addFlag = true; allSnaps.forEach(function (snap) { if (validSnap(snap, allRects)) { validSnaps.push(snap); } else if (addFlag) { allItemSnap.forEach(function (snap) { validSnaps.push(snap); }); allLineSnap.forEach(function (snap) { validSnaps.push(snap); }); addFlag = false; } }); return validSnaps; } function validSnap(snap, rects) { var snaprect = getCalcRectFromItem(snap); return rects.every(function (rect) { return !intersectRect(rect.rect, snaprect.rect); }); } function itemInfo(x, y, rotRad, size) { return { pos: { x: x, y: y }, rotRad: rotRad, size: size }; } function intersectRect(rect1, rect2) { var ret = false; rect1 = shrinkRect(rect1); rect2 = shrinkRect(rect2); ret = ret || getInterSect(rect1, rect2); ret = ret || rect1.some(function (pt) { return containPointInRect(pt, rect2); }); ret = ret || rect2.some(function (pt) { return containPointInRect(pt, rect1); }); return ret; } function containPointInRect(point, rect) { // true: contain, false: not contain for (var i = 0; i < rect.length; i++) { var ni = (i + 1) % rect.length; if (crossprod(diff(point, rect[i]), diff(rect[i], rect[ni])) < 0) { return false; } } return true; } function diff(v0, v1) { return { x: v0.x - v1.x, y: v0.y - v1.y }; } function crossprod(v0, v1) { return v0.x * v1.y - v0.y * v1.x; } function shrinkRect(rect) { var v02x = rect[2].x - rect[0].x; var v02y = rect[2].y - rect[0].y; var d02 = Math.sqrt(v02x * v02x + v02y * v02y); var o02x = v02x / d02 * 0.1; var o02y = v02y / d02 * 0.1; var v13x = rect[3].x - rect[1].x; var v13y = rect[3].y - rect[1].y; var d13 = Math.sqrt(v02x * v02x + v02y * v02y); var o13x = v13x / d13 * 0.1; var o13y = v13y / d13 * 0.1; return [point(rect[0].x + o02x, rect[0].y + o02y), point(rect[1].x + o13x, rect[1].y + o13y), point(rect[2].x - o02x, rect[2].y - o02y), point(rect[3].x - o13x, rect[3].y - o13y)]; } function getInterSect(shape1, shape2) { // return result of intersect of two shape var count = 0; for (var i = 0; i < shape1.length; i++) { var sl1 = { x: shape1[i].x, y: shape1[i].y }; var sl2 = { x: shape1[(i + 1) % shape1.length].x, y: shape1[(i + 1) % shape1.length].y }; for (var j = 0; j < shape2.length; j++) { var el1 = { x: shape2[j].x, y: shape2[j].y }; var el2 = { x: shape2[(j + 1) % shape2.length].x, y: shape2[(j + 1) % shape2.length].y }; var flag = getLineInterSect(sl1.x, sl1.y, sl2.x, sl2.y, el1.x, el1.y, el2.x, el2.y); if (flag) { count++; if (count > 1) return true; } } } return false; } function getLineInterSect(s1x, s1y, e1x, e1y, s2x, s2y, e2x, e2y) { var ax = s1x; var ay = s1y; var bx = e1x - s1x; var by = e1y - s1y; var cx = s2x; var cy = s2y; var dx = e2x - s2x; var dy = e2y - s2y; if (Math.abs(bx * dy - by * dx) < 0.00000001) { if (Math.abs((cx - ax) * by - (cy - ay) * bx) < 0.00000001) { var maxX = ax; var minX = ax; var maxY = ay; var minY = ay; if (maxX < e1x) maxX = e1x; if (maxX < cx) maxX = cx; if (maxX < e2x) maxX = e2x; if (minX > e1x) minX = e1x; if (minX > cx) minX = cx; if (minX > e2x) minX = e2x; if (maxY < e1y) maxY = e1y; if (maxY < cy) maxY = cy; if (maxY < e2y) maxY = e2y; if (minY > e1y) minY = e1y; if (minY > cy) minY = cy; if (minY > e2y) minX = e2y; var len = Math.sqrt((maxX - minX) * (maxX - minX) + (maxY - minY) * (maxY - minY)); var len1 = Math.sqrt(bx * bx + by * by); var len2 = Math.sqrt(dx * dx + dy * dy); if (len < len1 + len2) { return true; } else { return false; } } else { return false; } } else { var t = (dx * (ay - cy) + dy * (cx - ax)) / (bx * dy - by * dx); var u = (bx * (cy - ay) + by * (ax - cx)) / (dx * by - dy * bx); var ret = u < 1 && u > 0 && t > 0 && t < 1; return ret; } } function isPointInArea(allArea, pt) { var x = pt.x; var y = pt.y; var result = false; result = allArea.some(function (area) { var sum = 0, alpha = 0; for (var i = 0; i < area.length; i++) { var x0 = area[i].x; var y0 = area[i].y; var x1 = area[(i + 1) % area.length].x; var y1 = area[(i + 1) % area.length].y; var v0 = { x: x0 - x, y: y0 - y }; var v1 = { x: x1 - x, y: y1 - y }; if (Math.abs(v0.x) < _constants.EPSILON && Math.abs(v0.y) < _constants.EPSILON) // check if pt is area point return true; // check if pt is in area line var lineLen = Math.sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0)); var v0Len = Math.sqrt(v0.x * v0.x + v0.y * v0.y); var vPt = { x: -v0.x / v0Len, y: -v0.y / v0Len }; var xE = x0 + vPt.x * lineLen; var yE = y0 + vPt.y * lineLen; if (v0Len <= lineLen && Math.abs(xE - x1) < _constants.EPSILON && Math.abs(yE - y1) < _constants.EPSILON) return true; alpha = Math.atan2(v0.x * v1.y