@turbox3d/design-engine
Version:
Large-scale design application engine library
162 lines (161 loc) • 7 kB
JavaScript
;
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
};
}
}]);
}();