UNPKG

@turbox3d/design-engine

Version:

Large-scale design application engine library

162 lines (161 loc) 7 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _math = require("@turbox3d/math"); var InferenceEngine = exports["default"] = /*#__PURE__*/function () { function InferenceEngine() { (0, _classCallCheck2["default"])(this, InferenceEngine); } return (0, _createClass2["default"])(InferenceEngine, [{ key: "rotateSnap2d", value: /** * 旋转吸附2d * @param targetDegree 目标角度 * @param baseLine 吸附基准线(默认每90度为一个吸附线) * @param tolerance 吸附的误差范围(默认15度) */ function rotateSnap2d(targetDegree) { var baseLine = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 90; var tolerance = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 10; var snappedDegree = targetDegree % 360; var snapped = false; if (Math.abs(snappedDegree % baseLine) <= tolerance) { snappedDegree = Math.floor(snappedDegree / baseLine) * baseLine; snapped = true; } else if (Math.abs(snappedDegree % baseLine) >= baseLine - tolerance) { snappedDegree = Math.ceil(snappedDegree / baseLine) * baseLine; snapped = true; } return { snappedDegree: snappedDegree, // 吸附计算后的角度 snapped: snapped // 是否应用了吸附效果 }; } }, { key: "findClosestPointSorted", value: function findClosestPointSorted(target, arr) { var xOrY = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; var tolerance = arguments.length > 3 ? arguments[3] : undefined; var targetNumber = xOrY ? target.x : target.y; var left = 0; var right = arr.length - 1; var f = function f(c, t, o) { var minDiff = c - t; if (tolerance && Math.abs(minDiff) > tolerance) { return { minDiff: minDiff, point: undefined }; } return { minDiff: minDiff, point: xOrY ? new _math.Vector2(c, o) : new _math.Vector2(o, c) }; }; var ln = xOrY ? arr[0].x : arr[0].y; var rn = xOrY ? arr[arr.length - 1].x : arr[arr.length - 1].y; if (targetNumber <= ln) return f(ln, targetNumber, xOrY ? arr[0].y : arr[0].x); if (targetNumber >= rn) return f(rn, targetNumber, xOrY ? arr[arr.length - 1].y : arr[arr.length - 1].x); while (left <= right) { var mid = Math.floor((left + right) / 2); var midNumber = xOrY ? arr[mid].x : arr[mid].y; if (targetNumber === midNumber) { return f(midNumber, targetNumber, xOrY ? arr[mid].y : arr[mid].x); } if (targetNumber < midNumber) { right = mid - 1; } else { left = mid + 1; } } var leftNumber = xOrY ? arr[left].x : arr[left].y; var leftOtherNumber = xOrY ? arr[left].y : arr[left].x; var rightNumber = xOrY ? arr[right].x : arr[right].y; var rightOtherNumber = xOrY ? arr[right].y : arr[right].x; var useLeft = Math.abs(leftNumber - targetNumber) < Math.abs(rightNumber - targetNumber); var closestNumber = useLeft ? leftNumber : rightNumber; return f(closestNumber, targetNumber, useLeft ? leftOtherNumber : rightOtherNumber); } /** * 实体吸附2d */ }, { key: "entitySnap2d", value: function entitySnap2d(targetEntity, snappedEntities) { var _this = this; var tolerance = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 10; if (!snappedEntities.length) { return { vertical: undefined, verticalDiff: undefined, horizontal: undefined, horizontalDiff: undefined }; } var f = function f(entity) { var _entity$getBox2AABB = entity.getBox2AABB(undefined, true), _entity$getBox2AABB2 = (0, _slicedToArray2["default"])(_entity$getBox2AABB, 4), p0 = _entity$getBox2AABB2[0], p1 = _entity$getBox2AABB2[1], p2 = _entity$getBox2AABB2[2], p3 = _entity$getBox2AABB2[3]; var midX = (p0.x + p1.x) / 2; var midY = (p0.y + p3.y) / 2; return { snapPointsX: [new _math.Vector2(p0.x, midY), new _math.Vector2(midX, midY), new _math.Vector2(p1.x, midY)], snapPointsY: [new _math.Vector2(midX, p0.y), new _math.Vector2(midX, midY), new _math.Vector2(midX, p3.y)] }; }; var _f = f(targetEntity), targetPointsX = _f.snapPointsX, targetPointsY = _f.snapPointsY; var snappedPointsX = snappedEntities.map(function (entity) { return f(entity).snapPointsX; }).flat().sort(function (a, b) { return a.x - b.x; }); var snappedPointsY = snappedEntities.map(function (entity) { return f(entity).snapPointsY; }).flat().sort(function (a, b) { return a.y - b.y; }); var f2 = function f2(tps, sps) { var xOrY = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; var arr = tps.filter(function (p) { return _this.findClosestPointSorted(p, sps, xOrY, tolerance).point; }); if (!arr.length) { return; } if (arr.length === 1) { return _this.findClosestPointSorted(arr[0], sps, xOrY, tolerance); } var tp = arr.reduce(function (p, c) { var o1 = _this.findClosestPointSorted(p, sps, xOrY, tolerance); var o2 = _this.findClosestPointSorted(c, sps, xOrY, tolerance); if (Math.abs(o1.minDiff) <= Math.abs(o2.minDiff)) { return p; } return c; }); return _this.findClosestPointSorted(tp, sps, xOrY, tolerance); }; var vertical = f2(targetPointsX, snappedPointsX, true); var horizontal = f2(targetPointsY, snappedPointsY, false); return { vertical: (vertical === null || vertical === void 0 ? void 0 : vertical.point) && [new _math.Vector2(vertical.point.x, vertical.point.y), new _math.Vector2(vertical.point.x, targetEntity.position.y)], verticalDiff: vertical === null || vertical === void 0 ? void 0 : vertical.minDiff, horizontal: (horizontal === null || horizontal === void 0 ? void 0 : horizontal.point) && [new _math.Vector2(horizontal.point.x, horizontal.point.y), new _math.Vector2(targetEntity.position.x, horizontal.point.y)], horizontalDiff: horizontal === null || horizontal === void 0 ? void 0 : horizontal.minDiff }; } }]); }();