kitchen-simulator
Version:
It is a kitchen simulator (self-contained micro-frontend).
1,435 lines (1,408 loc) • 88.4 kB
JavaScript
"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