rm-graphical-computing-node 1.0.57 → 1.0.59
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +343 -338
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -711,10 +711,10 @@ var require_concaveman = __commonJS({
|
|
|
711
711
|
}
|
|
712
712
|
module.exports = concaveman2;
|
|
713
713
|
module.exports.default = concaveman2;
|
|
714
|
-
function concaveman2(
|
|
714
|
+
function concaveman2(points, concavity, lengthThreshold) {
|
|
715
715
|
concavity = Math.max(0, concavity === void 0 ? 2 : concavity);
|
|
716
716
|
lengthThreshold = lengthThreshold || 0;
|
|
717
|
-
var hull = fastConvexHull(
|
|
717
|
+
var hull = fastConvexHull(points);
|
|
718
718
|
var tree = new RBush(16);
|
|
719
719
|
tree.toBBox = function(a2) {
|
|
720
720
|
return {
|
|
@@ -730,7 +730,7 @@ var require_concaveman = __commonJS({
|
|
|
730
730
|
tree.compareMinY = function(a2, b2) {
|
|
731
731
|
return a2[1] - b2[1];
|
|
732
732
|
};
|
|
733
|
-
tree.load(
|
|
733
|
+
tree.load(points);
|
|
734
734
|
var queue = [];
|
|
735
735
|
for (var i = 0, last; i < hull.length; i++) {
|
|
736
736
|
var p = hull[i];
|
|
@@ -837,13 +837,13 @@ var require_concaveman = __commonJS({
|
|
|
837
837
|
node.maxY = Math.max(p1[1], p2[1]);
|
|
838
838
|
return node;
|
|
839
839
|
}
|
|
840
|
-
function fastConvexHull(
|
|
841
|
-
var left =
|
|
842
|
-
var top =
|
|
843
|
-
var right =
|
|
844
|
-
var bottom =
|
|
845
|
-
for (var i = 0; i <
|
|
846
|
-
var p =
|
|
840
|
+
function fastConvexHull(points) {
|
|
841
|
+
var left = points[0];
|
|
842
|
+
var top = points[0];
|
|
843
|
+
var right = points[0];
|
|
844
|
+
var bottom = points[0];
|
|
845
|
+
for (var i = 0; i < points.length; i++) {
|
|
846
|
+
var p = points[i];
|
|
847
847
|
if (p[0] < left[0]) left = p;
|
|
848
848
|
if (p[0] > right[0]) right = p;
|
|
849
849
|
if (p[1] < top[1]) top = p;
|
|
@@ -851,8 +851,8 @@ var require_concaveman = __commonJS({
|
|
|
851
851
|
}
|
|
852
852
|
var cull = [left, top, right, bottom];
|
|
853
853
|
var filtered = cull.slice();
|
|
854
|
-
for (i = 0; i <
|
|
855
|
-
if (!pointInPolygon2(
|
|
854
|
+
for (i = 0; i < points.length; i++) {
|
|
855
|
+
if (!pointInPolygon2(points[i], cull)) filtered.push(points[i]);
|
|
856
856
|
}
|
|
857
857
|
return convexHull(filtered);
|
|
858
858
|
}
|
|
@@ -961,21 +961,21 @@ var require_concaveman = __commonJS({
|
|
|
961
961
|
function compareByX(a, b) {
|
|
962
962
|
return a[0] === b[0] ? a[1] - b[1] : a[0] - b[0];
|
|
963
963
|
}
|
|
964
|
-
function convexHull(
|
|
965
|
-
|
|
964
|
+
function convexHull(points) {
|
|
965
|
+
points.sort(compareByX);
|
|
966
966
|
var lower = [];
|
|
967
|
-
for (var i = 0; i <
|
|
968
|
-
while (lower.length >= 2 && cross3(lower[lower.length - 2], lower[lower.length - 1],
|
|
967
|
+
for (var i = 0; i < points.length; i++) {
|
|
968
|
+
while (lower.length >= 2 && cross3(lower[lower.length - 2], lower[lower.length - 1], points[i]) <= 0) {
|
|
969
969
|
lower.pop();
|
|
970
970
|
}
|
|
971
|
-
lower.push(
|
|
971
|
+
lower.push(points[i]);
|
|
972
972
|
}
|
|
973
973
|
var upper = [];
|
|
974
|
-
for (var ii =
|
|
975
|
-
while (upper.length >= 2 && cross3(upper[upper.length - 2], upper[upper.length - 1],
|
|
974
|
+
for (var ii = points.length - 1; ii >= 0; ii--) {
|
|
975
|
+
while (upper.length >= 2 && cross3(upper[upper.length - 2], upper[upper.length - 1], points[ii]) <= 0) {
|
|
976
976
|
upper.pop();
|
|
977
977
|
}
|
|
978
|
-
upper.push(
|
|
978
|
+
upper.push(points[ii]);
|
|
979
979
|
}
|
|
980
980
|
upper.pop();
|
|
981
981
|
lower.pop();
|
|
@@ -1322,7 +1322,7 @@ var WallSubdivisionAnalyzer = class {
|
|
|
1322
1322
|
* { projectPlane: plane }
|
|
1323
1323
|
* );
|
|
1324
1324
|
*/
|
|
1325
|
-
analyzePointDistribution(wallGroup,
|
|
1325
|
+
analyzePointDistribution(wallGroup, points, tolerance = 0.01, options = {}) {
|
|
1326
1326
|
const projectPlane = options.projectPlane || null;
|
|
1327
1327
|
this.results = {
|
|
1328
1328
|
totalSegments: 0,
|
|
@@ -1388,8 +1388,8 @@ var WallSubdivisionAnalyzer = class {
|
|
|
1388
1388
|
plane.setFromCoplanarPoints(p0, p1, p3);
|
|
1389
1389
|
const temp = new Vector33();
|
|
1390
1390
|
const tempProjectedPoint = new Vector33();
|
|
1391
|
-
for (let pointIndex = 0; pointIndex <
|
|
1392
|
-
const rawPoint = new Vector33(
|
|
1391
|
+
for (let pointIndex = 0; pointIndex < points.length; pointIndex += 3) {
|
|
1392
|
+
const rawPoint = new Vector33(points[pointIndex], points[pointIndex + 1], points[pointIndex + 2]);
|
|
1393
1393
|
const point2 = projectPlane ? projectPlane.projectPoint(rawPoint, tempProjectedPoint) : rawPoint;
|
|
1394
1394
|
const distanceToPlane = Math.abs(plane.distanceToPoint(point2));
|
|
1395
1395
|
if (distanceToPlane > tolerance) {
|
|
@@ -2063,7 +2063,7 @@ var WallSubdivisionAnalyzer2 = class {
|
|
|
2063
2063
|
* { projectPlane: plane }
|
|
2064
2064
|
* );
|
|
2065
2065
|
*/
|
|
2066
|
-
analyzePointDistribution(wallGroup,
|
|
2066
|
+
analyzePointDistribution(wallGroup, points, tolerance = 0.01, options = {}) {
|
|
2067
2067
|
const projectPlane = options.projectPlane || null;
|
|
2068
2068
|
this.results = {
|
|
2069
2069
|
totalSegments: 0,
|
|
@@ -2129,8 +2129,8 @@ var WallSubdivisionAnalyzer2 = class {
|
|
|
2129
2129
|
plane.setFromCoplanarPoints(p0, p1, p3);
|
|
2130
2130
|
const temp = new Vector35();
|
|
2131
2131
|
const tempProjectedPoint = new Vector35();
|
|
2132
|
-
for (let pointIndex = 0; pointIndex <
|
|
2133
|
-
const rawPoint =
|
|
2132
|
+
for (let pointIndex = 0; pointIndex < points.length; pointIndex++) {
|
|
2133
|
+
const rawPoint = points[pointIndex];
|
|
2134
2134
|
const point2 = projectPlane ? projectPlane.projectPoint(rawPoint, tempProjectedPoint) : rawPoint;
|
|
2135
2135
|
const distanceToPlane = Math.abs(plane.distanceToPoint(point2));
|
|
2136
2136
|
if (distanceToPlane > tolerance) {
|
|
@@ -2558,10 +2558,10 @@ import { Vector3 as Vector37 } from "three";
|
|
|
2558
2558
|
var PointsUtils = class {
|
|
2559
2559
|
points = [];
|
|
2560
2560
|
_tempArr = [0, 0, 0];
|
|
2561
|
-
constructor(
|
|
2561
|
+
constructor(points) {
|
|
2562
2562
|
}
|
|
2563
|
-
initPoints(
|
|
2564
|
-
this.points =
|
|
2563
|
+
initPoints(points) {
|
|
2564
|
+
this.points = points;
|
|
2565
2565
|
}
|
|
2566
2566
|
getPointByIndex(index, target) {
|
|
2567
2567
|
const i = index * 3;
|
|
@@ -2584,17 +2584,17 @@ var PointsUtils = class {
|
|
|
2584
2584
|
arr.push(index * 3 + 1);
|
|
2585
2585
|
arr.push(index * 3 + 2);
|
|
2586
2586
|
}
|
|
2587
|
-
pointsToVector3Arr(
|
|
2587
|
+
pointsToVector3Arr(points) {
|
|
2588
2588
|
const vecArr = [];
|
|
2589
|
-
for (let i = 0; i <
|
|
2590
|
-
vecArr.push(new Vector37(
|
|
2589
|
+
for (let i = 0; i < points.length / 3; i++) {
|
|
2590
|
+
vecArr.push(new Vector37(points[i * 3], points[i * 3 + 1], points[i * 3 + 2]));
|
|
2591
2591
|
}
|
|
2592
2592
|
return vecArr;
|
|
2593
2593
|
}
|
|
2594
|
-
vector3ArrToPoints(
|
|
2594
|
+
vector3ArrToPoints(points) {
|
|
2595
2595
|
const arr = [];
|
|
2596
|
-
for (let i = 0; i <
|
|
2597
|
-
arr.push(
|
|
2596
|
+
for (let i = 0; i < points.length; i++) {
|
|
2597
|
+
arr.push(points[i].x, points[i].y, points[i].z);
|
|
2598
2598
|
}
|
|
2599
2599
|
return arr;
|
|
2600
2600
|
}
|
|
@@ -2717,10 +2717,10 @@ var isParallel = (v1, v2, tolerance = 0.01) => {
|
|
|
2717
2717
|
angle
|
|
2718
2718
|
};
|
|
2719
2719
|
};
|
|
2720
|
-
var getPointCloudData = (
|
|
2720
|
+
var getPointCloudData = (points, gridWidth, gridHeight, centerPts) => {
|
|
2721
2721
|
if (gridWidth < 1e-4 || gridHeight < 1e-4)
|
|
2722
2722
|
return {};
|
|
2723
|
-
const pts =
|
|
2723
|
+
const pts = points;
|
|
2724
2724
|
let clonedCenterPts = [];
|
|
2725
2725
|
if (centerPts && centerPts.length) {
|
|
2726
2726
|
clonedCenterPts = centerPts.map((p) => p.clone());
|
|
@@ -3011,27 +3011,27 @@ function closestDistanceBetweenSegments(A, B2, C, D2) {
|
|
|
3011
3011
|
const closest2 = C.clone().add(CD.clone().multiplyScalar(t));
|
|
3012
3012
|
return closest1.distanceTo(closest2);
|
|
3013
3013
|
}
|
|
3014
|
-
var getPointsMinAndMax = (
|
|
3014
|
+
var getPointsMinAndMax = (points) => {
|
|
3015
3015
|
let minZ = 999999;
|
|
3016
3016
|
let maxZ = -999999;
|
|
3017
3017
|
let minZPt = new THREE3.Vector3();
|
|
3018
3018
|
let maxZPt = new THREE3.Vector3();
|
|
3019
3019
|
let averagePz2 = 0;
|
|
3020
|
-
for (let i = 0; i <
|
|
3021
|
-
if (
|
|
3022
|
-
maxZ =
|
|
3023
|
-
maxZPt.set(
|
|
3020
|
+
for (let i = 0; i < points.length; i++) {
|
|
3021
|
+
if (points[i].z > maxZ) {
|
|
3022
|
+
maxZ = points[i].z;
|
|
3023
|
+
maxZPt.set(points[i].x, points[i].y, points[i].z);
|
|
3024
3024
|
}
|
|
3025
|
-
if (
|
|
3026
|
-
minZ =
|
|
3027
|
-
minZPt.set(
|
|
3025
|
+
if (points[i].z < minZ) {
|
|
3026
|
+
minZ = points[i].z;
|
|
3027
|
+
minZPt.set(points[i].x, points[i].y, points[i].z);
|
|
3028
3028
|
}
|
|
3029
|
-
averagePz2 +=
|
|
3029
|
+
averagePz2 += points[i].z;
|
|
3030
3030
|
}
|
|
3031
|
-
averagePz2 = averagePz2 /
|
|
3031
|
+
averagePz2 = averagePz2 / points.length;
|
|
3032
3032
|
return { minZ, maxZ, averagePz: averagePz2, minZPt, maxZPt };
|
|
3033
3033
|
};
|
|
3034
|
-
var getProjectedPointOnLine = (lineSt, lineEd,
|
|
3034
|
+
var getProjectedPointOnLine = (lineSt, lineEd, points) => {
|
|
3035
3035
|
let plane = new THREE3.Plane();
|
|
3036
3036
|
const regionPt1 = new THREE3.Vector3(lineSt.x, lineSt.y, lineSt.z);
|
|
3037
3037
|
const regionPt2 = new THREE3.Vector3(lineEd.x, lineEd.y, lineEd.z);
|
|
@@ -3039,7 +3039,7 @@ var getProjectedPointOnLine = (lineSt, lineEd, points2) => {
|
|
|
3039
3039
|
plane.setFromCoplanarPoints(regionPt1, regionPt2, regionPt3);
|
|
3040
3040
|
const projectPoints = [];
|
|
3041
3041
|
const origionProjectPoints = [];
|
|
3042
|
-
|
|
3042
|
+
points.forEach((point2) => {
|
|
3043
3043
|
const target = new THREE3.Vector3();
|
|
3044
3044
|
plane.projectPoint(point2, target);
|
|
3045
3045
|
origionProjectPoints.push(target.clone());
|
|
@@ -3058,7 +3058,7 @@ var getProjectedPointOnLine = (lineSt, lineEd, points2) => {
|
|
|
3058
3058
|
projectPoints.forEach((point2, i) => {
|
|
3059
3059
|
let ptClose = line3Tmp.closestPointToPoint(point2, true, ptTarget);
|
|
3060
3060
|
if (ptClose.distanceTo(point2) < 1e-3) {
|
|
3061
|
-
newOriginalPoints.push(
|
|
3061
|
+
newOriginalPoints.push(points[i]);
|
|
3062
3062
|
newOnLinePoints.push(origionProjectPoints[i]);
|
|
3063
3063
|
} else {
|
|
3064
3064
|
newProjectPoints.push(point2);
|
|
@@ -3229,15 +3229,15 @@ var isPointOnLine2 = (lineStart, lineEnd, point2, tolerance = 1e-6) => {
|
|
|
3229
3229
|
line2.closestPointToPoint(new THREE3.Vector3(point2.x, point2.y, point2.z), true, closestPoint);
|
|
3230
3230
|
return closestPoint.distanceTo(new THREE3.Vector3(point2.x, point2.y, point2.z)) < tolerance;
|
|
3231
3231
|
};
|
|
3232
|
-
var getFarthestPoints = (
|
|
3232
|
+
var getFarthestPoints = (points) => {
|
|
3233
3233
|
let maxDist = 0;
|
|
3234
3234
|
let result = [];
|
|
3235
|
-
for (let i = 0; i <
|
|
3236
|
-
for (let j = i + 1; j <
|
|
3237
|
-
const dist3 =
|
|
3235
|
+
for (let i = 0; i < points.length; i++) {
|
|
3236
|
+
for (let j = i + 1; j < points.length; j++) {
|
|
3237
|
+
const dist3 = points[i].distanceTo(points[j]);
|
|
3238
3238
|
if (dist3 > maxDist) {
|
|
3239
3239
|
maxDist = dist3;
|
|
3240
|
-
result = [
|
|
3240
|
+
result = [points[i], points[j]];
|
|
3241
3241
|
}
|
|
3242
3242
|
}
|
|
3243
3243
|
}
|
|
@@ -3252,10 +3252,10 @@ var randomLightHex = () => {
|
|
|
3252
3252
|
const b = Math.floor(Math.random() * 75 + 180).toString(16).padStart(2, "0");
|
|
3253
3253
|
return `#${r}${g}${b}`;
|
|
3254
3254
|
};
|
|
3255
|
-
var uniqueVector3ByTolerance = (
|
|
3255
|
+
var uniqueVector3ByTolerance = (points, tolerance = 1e-3) => {
|
|
3256
3256
|
const map = /* @__PURE__ */ new Map();
|
|
3257
3257
|
const result = [];
|
|
3258
|
-
for (const p of
|
|
3258
|
+
for (const p of points) {
|
|
3259
3259
|
const ix = Math.round(p.x / tolerance);
|
|
3260
3260
|
const iy = Math.round(p.y / tolerance);
|
|
3261
3261
|
const iz = Math.round(p.z / tolerance);
|
|
@@ -3278,7 +3278,7 @@ var getOBBPoints = (obb) => {
|
|
|
3278
3278
|
function makePoint(sx, sy, sz) {
|
|
3279
3279
|
return center.clone().addScaledVector(xAxis, sx).addScaledVector(yAxis, sy).addScaledVector(zAxis, sz);
|
|
3280
3280
|
}
|
|
3281
|
-
const
|
|
3281
|
+
const points = [
|
|
3282
3282
|
// 下方一圈,局部 Z = -1
|
|
3283
3283
|
makePoint(-1, -1, -1),
|
|
3284
3284
|
makePoint(1, -1, -1),
|
|
@@ -3290,7 +3290,7 @@ var getOBBPoints = (obb) => {
|
|
|
3290
3290
|
makePoint(1, 1, 1),
|
|
3291
3291
|
makePoint(-1, 1, 1)
|
|
3292
3292
|
];
|
|
3293
|
-
return
|
|
3293
|
+
return points;
|
|
3294
3294
|
};
|
|
3295
3295
|
var createBoxGeometryFromRectPoints = (rectPoints, height) => {
|
|
3296
3296
|
const p0 = rectPoints[0];
|
|
@@ -3318,12 +3318,12 @@ var createBoxGeometryFromRectPoints = (rectPoints, height) => {
|
|
|
3318
3318
|
geometry.computeVertexNormals();
|
|
3319
3319
|
return geometry;
|
|
3320
3320
|
};
|
|
3321
|
-
var getPointSetCentroid = (
|
|
3322
|
-
if (!
|
|
3321
|
+
var getPointSetCentroid = (points) => {
|
|
3322
|
+
if (!points || points.length === 0) {
|
|
3323
3323
|
return null;
|
|
3324
3324
|
}
|
|
3325
3325
|
const center = new THREE3.Vector3(0, 0, 0);
|
|
3326
|
-
for (const p of
|
|
3326
|
+
for (const p of points) {
|
|
3327
3327
|
if (Array.isArray(p)) {
|
|
3328
3328
|
center.x += p[0];
|
|
3329
3329
|
center.y += p[1];
|
|
@@ -3334,18 +3334,18 @@ var getPointSetCentroid = (points2) => {
|
|
|
3334
3334
|
center.z += p.z;
|
|
3335
3335
|
}
|
|
3336
3336
|
}
|
|
3337
|
-
center.divideScalar(
|
|
3337
|
+
center.divideScalar(points.length);
|
|
3338
3338
|
return center;
|
|
3339
3339
|
};
|
|
3340
|
-
var calculatePolygonArea = (
|
|
3341
|
-
if (!
|
|
3340
|
+
var calculatePolygonArea = (points) => {
|
|
3341
|
+
if (!points || points.length < 3) {
|
|
3342
3342
|
return 0;
|
|
3343
3343
|
}
|
|
3344
|
-
let isArray = Array.isArray(
|
|
3344
|
+
let isArray = Array.isArray(points[0]);
|
|
3345
3345
|
let area2 = 0;
|
|
3346
|
-
for (let i = 0; i <
|
|
3347
|
-
const p1 =
|
|
3348
|
-
const p2 =
|
|
3346
|
+
for (let i = 0; i < points.length; i++) {
|
|
3347
|
+
const p1 = points[i];
|
|
3348
|
+
const p2 = points[(i + 1) % points.length];
|
|
3349
3349
|
if (isArray) {
|
|
3350
3350
|
area2 += p1[0] * p2[1] - p2[0] * p1[1];
|
|
3351
3351
|
} else {
|
|
@@ -3447,11 +3447,11 @@ function pointToSegmentDistance(p, a, b) {
|
|
|
3447
3447
|
p.y - y
|
|
3448
3448
|
);
|
|
3449
3449
|
}
|
|
3450
|
-
var voxelDownsample2DForContour = (
|
|
3451
|
-
if (!
|
|
3450
|
+
var voxelDownsample2DForContour = (points, cellSize) => {
|
|
3451
|
+
if (!points || points.length === 0) return [];
|
|
3452
3452
|
const map = /* @__PURE__ */ new Map();
|
|
3453
|
-
for (let i = 0; i <
|
|
3454
|
-
const p =
|
|
3453
|
+
for (let i = 0; i < points.length; i++) {
|
|
3454
|
+
const p = points[i];
|
|
3455
3455
|
const x = p[0];
|
|
3456
3456
|
const y = p[1];
|
|
3457
3457
|
const gx = Math.floor(x / cellSize);
|
|
@@ -3506,10 +3506,10 @@ var voxelDownsample2DForContour = (points2, cellSize) => {
|
|
|
3506
3506
|
}
|
|
3507
3507
|
return result;
|
|
3508
3508
|
};
|
|
3509
|
-
var setPointsSameZ = (
|
|
3510
|
-
for (let i = 0; i <
|
|
3511
|
-
|
|
3512
|
-
return
|
|
3509
|
+
var setPointsSameZ = (points, z) => {
|
|
3510
|
+
for (let i = 0; i < points.length; i++)
|
|
3511
|
+
points[i].z = z;
|
|
3512
|
+
return points;
|
|
3513
3513
|
};
|
|
3514
3514
|
|
|
3515
3515
|
// src/utils/updateLine.mjs
|
|
@@ -3618,12 +3618,12 @@ function isPointInRect2D(point2, rectPoints, plane = "xy") {
|
|
|
3618
3618
|
}
|
|
3619
3619
|
return true;
|
|
3620
3620
|
}
|
|
3621
|
-
function getPointSetCentroid2(
|
|
3622
|
-
if (!
|
|
3621
|
+
function getPointSetCentroid2(points) {
|
|
3622
|
+
if (!points || points.length === 0) {
|
|
3623
3623
|
return null;
|
|
3624
3624
|
}
|
|
3625
3625
|
const center = new THREE4.Vector3(0, 0, 0);
|
|
3626
|
-
for (const p of
|
|
3626
|
+
for (const p of points) {
|
|
3627
3627
|
if (Array.isArray(p)) {
|
|
3628
3628
|
center.x += p[0];
|
|
3629
3629
|
center.y += p[1];
|
|
@@ -3634,7 +3634,7 @@ function getPointSetCentroid2(points2) {
|
|
|
3634
3634
|
center.z += p.z;
|
|
3635
3635
|
}
|
|
3636
3636
|
}
|
|
3637
|
-
center.divideScalar(
|
|
3637
|
+
center.divideScalar(points.length);
|
|
3638
3638
|
return center;
|
|
3639
3639
|
}
|
|
3640
3640
|
function toVector3(p) {
|
|
@@ -3701,17 +3701,17 @@ function eigenVector2x2(a, b, c) {
|
|
|
3701
3701
|
y: y / len
|
|
3702
3702
|
};
|
|
3703
3703
|
}
|
|
3704
|
-
function getTrendLineEndpoints(
|
|
3704
|
+
function getTrendLineEndpoints(points, options = {}) {
|
|
3705
3705
|
const {
|
|
3706
3706
|
plane = "xy",
|
|
3707
3707
|
// 0 表示完全取最远两端
|
|
3708
3708
|
// 0.05 表示两端各去掉 5% 离群点
|
|
3709
3709
|
trimRatio = 0
|
|
3710
3710
|
} = options;
|
|
3711
|
-
if (!
|
|
3711
|
+
if (!points || points.length < 2) {
|
|
3712
3712
|
return null;
|
|
3713
3713
|
}
|
|
3714
|
-
const pts =
|
|
3714
|
+
const pts = points.map((p) => get2D1(p, plane));
|
|
3715
3715
|
let meanX = 0;
|
|
3716
3716
|
let meanY = 0;
|
|
3717
3717
|
let meanUp = 0;
|
|
@@ -4093,7 +4093,8 @@ var getBeamLine = async (lines, runDataList, pcdData, lineReader, lineEditor, on
|
|
|
4093
4093
|
let doorTmpEd = tmpRegion.facePoints[1].clone();
|
|
4094
4094
|
let isExtendBeam = false;
|
|
4095
4095
|
let findDoorDataIndex = -1;
|
|
4096
|
-
|
|
4096
|
+
let doorSill = 0.3;
|
|
4097
|
+
if (Math.abs(tmpRegion.facePoints[0].z - line2.start.z) < doorSill) {
|
|
4097
4098
|
let isInsert = false;
|
|
4098
4099
|
for (let k = 0; k < runDataList.length; k++) {
|
|
4099
4100
|
let next = k + 1;
|
|
@@ -4469,7 +4470,10 @@ var getBeamLine = async (lines, runDataList, pcdData, lineReader, lineEditor, on
|
|
|
4469
4470
|
}
|
|
4470
4471
|
}
|
|
4471
4472
|
}
|
|
4472
|
-
if (
|
|
4473
|
+
if (
|
|
4474
|
+
/**!isPullOutDoor && */
|
|
4475
|
+
length2 < 1.5
|
|
4476
|
+
) {
|
|
4473
4477
|
for (let n = 0; n < doorDatas.length; n++) {
|
|
4474
4478
|
if (doorDatas[n].inWall) continue;
|
|
4475
4479
|
let doorSt = new THREE5.Vector3(doorDatas[n].doorStartPt.x, doorDatas[n].doorStartPt.y, 0);
|
|
@@ -5510,7 +5514,7 @@ function splitSegmentsAtIntersections(inputSegments, project, EPS = 1e-6) {
|
|
|
5510
5514
|
const segA = inputSegments[i];
|
|
5511
5515
|
const a1 = project(segA.start);
|
|
5512
5516
|
const a2 = project(segA.end);
|
|
5513
|
-
const
|
|
5517
|
+
const points = [
|
|
5514
5518
|
{
|
|
5515
5519
|
t: 0,
|
|
5516
5520
|
point: clonePoint(segA.start)
|
|
@@ -5528,15 +5532,15 @@ function splitSegmentsAtIntersections(inputSegments, project, EPS = 1e-6) {
|
|
|
5528
5532
|
const hit = segmentIntersection(a1, a2, b1, b2, EPS);
|
|
5529
5533
|
if (!hit) continue;
|
|
5530
5534
|
if (hit.t > EPS && hit.t < 1 - EPS) {
|
|
5531
|
-
|
|
5535
|
+
points.push({
|
|
5532
5536
|
t: hit.t,
|
|
5533
5537
|
point: lerpPoint(segA.start, segA.end, hit.t)
|
|
5534
5538
|
});
|
|
5535
5539
|
}
|
|
5536
5540
|
}
|
|
5537
|
-
|
|
5541
|
+
points.sort((p1, p2) => p1.t - p2.t);
|
|
5538
5542
|
const uniquePoints = [];
|
|
5539
|
-
for (const p of
|
|
5543
|
+
for (const p of points) {
|
|
5540
5544
|
if (uniquePoints.length === 0 || Math.abs(p.t - uniquePoints[uniquePoints.length - 1].t) > EPS) {
|
|
5541
5545
|
uniquePoints.push(p);
|
|
5542
5546
|
}
|
|
@@ -5597,11 +5601,11 @@ function dist2(a, b) {
|
|
|
5597
5601
|
const dy = a.y - b.y;
|
|
5598
5602
|
return dx * dx + dy * dy;
|
|
5599
5603
|
}
|
|
5600
|
-
function signedArea(
|
|
5604
|
+
function signedArea(points) {
|
|
5601
5605
|
let area2 = 0;
|
|
5602
|
-
for (let i = 0; i <
|
|
5603
|
-
const p =
|
|
5604
|
-
const q =
|
|
5606
|
+
for (let i = 0; i < points.length; i++) {
|
|
5607
|
+
const p = points[i];
|
|
5608
|
+
const q = points[(i + 1) % points.length];
|
|
5605
5609
|
area2 += p.x * q.y - q.x * p.y;
|
|
5606
5610
|
}
|
|
5607
5611
|
return area2 / 2;
|
|
@@ -5629,6 +5633,7 @@ function clonePoint(p) {
|
|
|
5629
5633
|
|
|
5630
5634
|
// src/geometry/colLine.mjs
|
|
5631
5635
|
import * as gfx from "rm-gxf-computing-rusts";
|
|
5636
|
+
import { existsSync } from "fs";
|
|
5632
5637
|
var getColLine = async (lines, runDataList, collectDataPath, pointCloudCluster = null) => {
|
|
5633
5638
|
if (!lines || lines.length <= 0) return;
|
|
5634
5639
|
let colDatas = {
|
|
@@ -5958,7 +5963,7 @@ var getColLine = async (lines, runDataList, collectDataPath, pointCloudCluster =
|
|
|
5958
5963
|
colDatas.threeEdgeRect.push(colIndexs);
|
|
5959
5964
|
}
|
|
5960
5965
|
}
|
|
5961
|
-
if (colDatas.threeEdgeRect) {
|
|
5966
|
+
if (colDatas.threeEdgeRect.length > 0 && existsSync(collectDataPath)) {
|
|
5962
5967
|
let trajectoryObj = {};
|
|
5963
5968
|
for (let r = 0; r < runDataList.length; r++) {
|
|
5964
5969
|
trajectoryObj[r] = runDataList[r];
|
|
@@ -5999,7 +6004,7 @@ var getColLine = async (lines, runDataList, collectDataPath, pointCloudCluster =
|
|
|
5999
6004
|
let maxNum = 0;
|
|
6000
6005
|
for (const cluster of clusterResult[0]) {
|
|
6001
6006
|
if (cluster.length < 50) continue;
|
|
6002
|
-
const newOriginalPoints = cluster.map((i2) =>
|
|
6007
|
+
const newOriginalPoints = cluster.map((i2) => allCenterPoints[i2]);
|
|
6003
6008
|
if (maxNum < newOriginalPoints.length) {
|
|
6004
6009
|
maxNum = newOriginalPoints.length;
|
|
6005
6010
|
newPoints = newOriginalPoints;
|
|
@@ -6435,11 +6440,11 @@ var Delaunator = class _Delaunator {
|
|
|
6435
6440
|
* @param {(p: P) => number} [getY]
|
|
6436
6441
|
*/
|
|
6437
6442
|
// @ts-expect-error TS2322
|
|
6438
|
-
static from(
|
|
6439
|
-
const n =
|
|
6443
|
+
static from(points, getX = defaultGetX, getY = defaultGetY) {
|
|
6444
|
+
const n = points.length;
|
|
6440
6445
|
const coords = new Float64Array(n * 2);
|
|
6441
6446
|
for (let i = 0; i < n; i++) {
|
|
6442
|
-
const p =
|
|
6447
|
+
const p = points[i];
|
|
6443
6448
|
coords[2 * i] = getX(p);
|
|
6444
6449
|
coords[2 * i + 1] = getY(p);
|
|
6445
6450
|
}
|
|
@@ -6916,19 +6921,19 @@ var Voronoi = class {
|
|
|
6916
6921
|
return this;
|
|
6917
6922
|
}
|
|
6918
6923
|
_init() {
|
|
6919
|
-
const { delaunay: { points
|
|
6924
|
+
const { delaunay: { points, hull, triangles }, vectors } = this;
|
|
6920
6925
|
let bx, by;
|
|
6921
6926
|
const circumcenters = this.circumcenters = this._circumcenters.subarray(0, triangles.length / 3 * 2);
|
|
6922
6927
|
for (let i = 0, j = 0, n = triangles.length, x, y; i < n; i += 3, j += 2) {
|
|
6923
6928
|
const t1 = triangles[i] * 2;
|
|
6924
6929
|
const t2 = triangles[i + 1] * 2;
|
|
6925
6930
|
const t3 = triangles[i + 2] * 2;
|
|
6926
|
-
const x12 =
|
|
6927
|
-
const y12 =
|
|
6928
|
-
const x2 =
|
|
6929
|
-
const y2 =
|
|
6930
|
-
const x3 =
|
|
6931
|
-
const y3 =
|
|
6931
|
+
const x12 = points[t1];
|
|
6932
|
+
const y12 = points[t1 + 1];
|
|
6933
|
+
const x2 = points[t2];
|
|
6934
|
+
const y2 = points[t2 + 1];
|
|
6935
|
+
const x3 = points[t3];
|
|
6936
|
+
const y3 = points[t3 + 1];
|
|
6932
6937
|
const dx = x2 - x12;
|
|
6933
6938
|
const dy = y2 - y12;
|
|
6934
6939
|
const ex = x3 - x12;
|
|
@@ -6937,7 +6942,7 @@ var Voronoi = class {
|
|
|
6937
6942
|
if (Math.abs(ab4) < 1e-9) {
|
|
6938
6943
|
if (bx === void 0) {
|
|
6939
6944
|
bx = by = 0;
|
|
6940
|
-
for (const i2 of hull) bx +=
|
|
6945
|
+
for (const i2 of hull) bx += points[i2 * 2], by += points[i2 * 2 + 1];
|
|
6941
6946
|
bx /= hull.length, by /= hull.length;
|
|
6942
6947
|
}
|
|
6943
6948
|
const a = 1e9 * Math.sign((bx - x12) * ey - (by - y12) * ex);
|
|
@@ -6955,13 +6960,13 @@ var Voronoi = class {
|
|
|
6955
6960
|
}
|
|
6956
6961
|
let h = hull[hull.length - 1];
|
|
6957
6962
|
let p0, p1 = h * 4;
|
|
6958
|
-
let x0, x1 =
|
|
6959
|
-
let y0, y1 =
|
|
6963
|
+
let x0, x1 = points[2 * h];
|
|
6964
|
+
let y0, y1 = points[2 * h + 1];
|
|
6960
6965
|
vectors.fill(0);
|
|
6961
6966
|
for (let i = 0; i < hull.length; ++i) {
|
|
6962
6967
|
h = hull[i];
|
|
6963
6968
|
p0 = p1, x0 = x1, y0 = y1;
|
|
6964
|
-
p1 = h * 4, x1 =
|
|
6969
|
+
p1 = h * 4, x1 = points[2 * h], y1 = points[2 * h + 1];
|
|
6965
6970
|
vectors[p0 + 2] = vectors[p1] = y0 - y1;
|
|
6966
6971
|
vectors[p0 + 3] = vectors[p1 + 1] = x1 - x0;
|
|
6967
6972
|
}
|
|
@@ -7000,21 +7005,21 @@ var Voronoi = class {
|
|
|
7000
7005
|
}
|
|
7001
7006
|
renderCell(i, context) {
|
|
7002
7007
|
const buffer = context == null ? context = new Path() : void 0;
|
|
7003
|
-
const
|
|
7004
|
-
if (
|
|
7005
|
-
context.moveTo(
|
|
7006
|
-
let n =
|
|
7007
|
-
while (
|
|
7008
|
+
const points = this._clip(i);
|
|
7009
|
+
if (points === null || !points.length) return;
|
|
7010
|
+
context.moveTo(points[0], points[1]);
|
|
7011
|
+
let n = points.length;
|
|
7012
|
+
while (points[0] === points[n - 2] && points[1] === points[n - 1] && n > 1) n -= 2;
|
|
7008
7013
|
for (let i2 = 2; i2 < n; i2 += 2) {
|
|
7009
|
-
if (
|
|
7010
|
-
context.lineTo(
|
|
7014
|
+
if (points[i2] !== points[i2 - 2] || points[i2 + 1] !== points[i2 - 1])
|
|
7015
|
+
context.lineTo(points[i2], points[i2 + 1]);
|
|
7011
7016
|
}
|
|
7012
7017
|
context.closePath();
|
|
7013
7018
|
return buffer && buffer.value();
|
|
7014
7019
|
}
|
|
7015
7020
|
*cellPolygons() {
|
|
7016
|
-
const { delaunay: { points
|
|
7017
|
-
for (let i = 0, n =
|
|
7021
|
+
const { delaunay: { points } } = this;
|
|
7022
|
+
for (let i = 0, n = points.length / 2; i < n; ++i) {
|
|
7018
7023
|
const cell = this.cellPolygon(i);
|
|
7019
7024
|
if (cell) cell.index = i, yield cell;
|
|
7020
7025
|
}
|
|
@@ -7058,35 +7063,35 @@ var Voronoi = class {
|
|
|
7058
7063
|
const { circumcenters, delaunay: { inedges, halfedges, triangles } } = this;
|
|
7059
7064
|
const e0 = inedges[i];
|
|
7060
7065
|
if (e0 === -1) return null;
|
|
7061
|
-
const
|
|
7066
|
+
const points = [];
|
|
7062
7067
|
let e = e0;
|
|
7063
7068
|
do {
|
|
7064
7069
|
const t = Math.floor(e / 3);
|
|
7065
|
-
|
|
7070
|
+
points.push(circumcenters[t * 2], circumcenters[t * 2 + 1]);
|
|
7066
7071
|
e = e % 3 === 2 ? e - 2 : e + 1;
|
|
7067
7072
|
if (triangles[e] !== i) break;
|
|
7068
7073
|
e = halfedges[e];
|
|
7069
7074
|
} while (e !== e0 && e !== -1);
|
|
7070
|
-
return
|
|
7075
|
+
return points;
|
|
7071
7076
|
}
|
|
7072
7077
|
_clip(i) {
|
|
7073
7078
|
if (i === 0 && this.delaunay.hull.length === 1) {
|
|
7074
7079
|
return [this.xmax, this.ymin, this.xmax, this.ymax, this.xmin, this.ymax, this.xmin, this.ymin];
|
|
7075
7080
|
}
|
|
7076
|
-
const
|
|
7077
|
-
if (
|
|
7081
|
+
const points = this._cell(i);
|
|
7082
|
+
if (points === null) return null;
|
|
7078
7083
|
const { vectors: V } = this;
|
|
7079
7084
|
const v2 = i * 4;
|
|
7080
|
-
return this._simplify(V[v2] || V[v2 + 1] ? this._clipInfinite(i,
|
|
7085
|
+
return this._simplify(V[v2] || V[v2 + 1] ? this._clipInfinite(i, points, V[v2], V[v2 + 1], V[v2 + 2], V[v2 + 3]) : this._clipFinite(i, points));
|
|
7081
7086
|
}
|
|
7082
|
-
_clipFinite(i,
|
|
7083
|
-
const n =
|
|
7087
|
+
_clipFinite(i, points) {
|
|
7088
|
+
const n = points.length;
|
|
7084
7089
|
let P = null;
|
|
7085
|
-
let x0, y0, x1 =
|
|
7090
|
+
let x0, y0, x1 = points[n - 2], y1 = points[n - 1];
|
|
7086
7091
|
let c0, c1 = this._regioncode(x1, y1);
|
|
7087
7092
|
let e0, e1 = 0;
|
|
7088
7093
|
for (let j = 0; j < n; j += 2) {
|
|
7089
|
-
x0 = x1, y0 = y1, x1 =
|
|
7094
|
+
x0 = x1, y0 = y1, x1 = points[j], y1 = points[j + 1];
|
|
7090
7095
|
c0 = c1, c1 = this._regioncode(x1, y1);
|
|
7091
7096
|
if (c0 === 0 && c1 === 0) {
|
|
7092
7097
|
e0 = e1, e1 = 0;
|
|
@@ -7134,8 +7139,8 @@ var Voronoi = class {
|
|
|
7134
7139
|
else x1 = x, y1 = y, c1 = this._regioncode(x1, y1);
|
|
7135
7140
|
}
|
|
7136
7141
|
}
|
|
7137
|
-
_clipInfinite(i,
|
|
7138
|
-
let P = Array.from(
|
|
7142
|
+
_clipInfinite(i, points, vx0, vy0, vxn, vyn) {
|
|
7143
|
+
let P = Array.from(points), p;
|
|
7139
7144
|
if (p = this._project(P[0], P[1], vx0, vy0)) P.unshift(p[0], p[1]);
|
|
7140
7145
|
if (p = this._project(P[P.length - 2], P[P.length - 1], vxn, vyn)) P.push(p[0], p[1]);
|
|
7141
7146
|
if (P = this._clipFinite(i, P)) {
|
|
@@ -7249,13 +7254,13 @@ function jitter(x, y, r) {
|
|
|
7249
7254
|
return [x + Math.sin(x + y) * r, y + Math.cos(x - y) * r];
|
|
7250
7255
|
}
|
|
7251
7256
|
var Delaunay = class _Delaunay {
|
|
7252
|
-
static from(
|
|
7253
|
-
return new _Delaunay("length" in
|
|
7257
|
+
static from(points, fx = pointX, fy = pointY, that) {
|
|
7258
|
+
return new _Delaunay("length" in points ? flatArray(points, fx, fy, that) : Float64Array.from(flatIterable(points, fx, fy, that)));
|
|
7254
7259
|
}
|
|
7255
|
-
constructor(
|
|
7256
|
-
this._delaunator = new Delaunator(
|
|
7257
|
-
this.inedges = new Int32Array(
|
|
7258
|
-
this._hullIndex = new Int32Array(
|
|
7260
|
+
constructor(points) {
|
|
7261
|
+
this._delaunator = new Delaunator(points);
|
|
7262
|
+
this.inedges = new Int32Array(points.length / 2);
|
|
7263
|
+
this._hullIndex = new Int32Array(points.length / 2);
|
|
7259
7264
|
this.points = this._delaunator.coords;
|
|
7260
7265
|
this._init();
|
|
7261
7266
|
}
|
|
@@ -7265,16 +7270,16 @@ var Delaunay = class _Delaunay {
|
|
|
7265
7270
|
return this;
|
|
7266
7271
|
}
|
|
7267
7272
|
_init() {
|
|
7268
|
-
const d = this._delaunator,
|
|
7273
|
+
const d = this._delaunator, points = this.points;
|
|
7269
7274
|
if (d.hull && d.hull.length > 2 && collinear(d)) {
|
|
7270
|
-
this.collinear = Int32Array.from({ length:
|
|
7271
|
-
const e = this.collinear[0], f = this.collinear[this.collinear.length - 1], bounds = [
|
|
7272
|
-
for (let i = 0, n =
|
|
7273
|
-
const p = jitter(
|
|
7274
|
-
|
|
7275
|
-
|
|
7276
|
-
}
|
|
7277
|
-
this._delaunator = new Delaunator(
|
|
7275
|
+
this.collinear = Int32Array.from({ length: points.length / 2 }, (_, i) => i).sort((i, j) => points[2 * i] - points[2 * j] || points[2 * i + 1] - points[2 * j + 1]);
|
|
7276
|
+
const e = this.collinear[0], f = this.collinear[this.collinear.length - 1], bounds = [points[2 * e], points[2 * e + 1], points[2 * f], points[2 * f + 1]], r = 1e-8 * Math.hypot(bounds[3] - bounds[1], bounds[2] - bounds[0]);
|
|
7277
|
+
for (let i = 0, n = points.length / 2; i < n; ++i) {
|
|
7278
|
+
const p = jitter(points[2 * i], points[2 * i + 1], r);
|
|
7279
|
+
points[2 * i] = p[0];
|
|
7280
|
+
points[2 * i + 1] = p[1];
|
|
7281
|
+
}
|
|
7282
|
+
this._delaunator = new Delaunator(points);
|
|
7278
7283
|
} else {
|
|
7279
7284
|
delete this.collinear;
|
|
7280
7285
|
}
|
|
@@ -7336,15 +7341,15 @@ var Delaunay = class _Delaunay {
|
|
|
7336
7341
|
return c;
|
|
7337
7342
|
}
|
|
7338
7343
|
_step(i, x, y) {
|
|
7339
|
-
const { inedges, hull, _hullIndex, halfedges, triangles, points
|
|
7340
|
-
if (inedges[i] === -1 || !
|
|
7344
|
+
const { inedges, hull, _hullIndex, halfedges, triangles, points } = this;
|
|
7345
|
+
if (inedges[i] === -1 || !points.length) return (i + 1) % (points.length >> 1);
|
|
7341
7346
|
let c = i;
|
|
7342
|
-
let dc = pow(x -
|
|
7347
|
+
let dc = pow(x - points[i * 2], 2) + pow(y - points[i * 2 + 1], 2);
|
|
7343
7348
|
const e0 = inedges[i];
|
|
7344
7349
|
let e = e0;
|
|
7345
7350
|
do {
|
|
7346
7351
|
let t = triangles[e];
|
|
7347
|
-
const dt = pow(x -
|
|
7352
|
+
const dt = pow(x - points[t * 2], 2) + pow(y - points[t * 2 + 1], 2);
|
|
7348
7353
|
if (dt < dc) dc = dt, c = t;
|
|
7349
7354
|
e = e % 3 === 2 ? e - 2 : e + 1;
|
|
7350
7355
|
if (triangles[e] !== i) break;
|
|
@@ -7352,7 +7357,7 @@ var Delaunay = class _Delaunay {
|
|
|
7352
7357
|
if (e === -1) {
|
|
7353
7358
|
e = hull[(_hullIndex[i] + 1) % hull.length];
|
|
7354
7359
|
if (e !== t) {
|
|
7355
|
-
if (pow(x -
|
|
7360
|
+
if (pow(x - points[e * 2], 2) + pow(y - points[e * 2 + 1], 2) < dc) return e;
|
|
7356
7361
|
}
|
|
7357
7362
|
break;
|
|
7358
7363
|
}
|
|
@@ -7361,14 +7366,14 @@ var Delaunay = class _Delaunay {
|
|
|
7361
7366
|
}
|
|
7362
7367
|
render(context) {
|
|
7363
7368
|
const buffer = context == null ? context = new Path() : void 0;
|
|
7364
|
-
const { points
|
|
7369
|
+
const { points, halfedges, triangles } = this;
|
|
7365
7370
|
for (let i = 0, n = halfedges.length; i < n; ++i) {
|
|
7366
7371
|
const j = halfedges[i];
|
|
7367
7372
|
if (j < i) continue;
|
|
7368
7373
|
const ti = triangles[i] * 2;
|
|
7369
7374
|
const tj = triangles[j] * 2;
|
|
7370
|
-
context.moveTo(
|
|
7371
|
-
context.lineTo(
|
|
7375
|
+
context.moveTo(points[ti], points[ti + 1]);
|
|
7376
|
+
context.lineTo(points[tj], points[tj + 1]);
|
|
7372
7377
|
}
|
|
7373
7378
|
this.renderHull(context);
|
|
7374
7379
|
return buffer && buffer.value();
|
|
@@ -7377,9 +7382,9 @@ var Delaunay = class _Delaunay {
|
|
|
7377
7382
|
if (r === void 0 && (!context || typeof context.moveTo !== "function")) r = context, context = null;
|
|
7378
7383
|
r = r == void 0 ? 2 : +r;
|
|
7379
7384
|
const buffer = context == null ? context = new Path() : void 0;
|
|
7380
|
-
const { points
|
|
7381
|
-
for (let i = 0, n =
|
|
7382
|
-
const x =
|
|
7385
|
+
const { points } = this;
|
|
7386
|
+
for (let i = 0, n = points.length; i < n; i += 2) {
|
|
7387
|
+
const x = points[i], y = points[i + 1];
|
|
7383
7388
|
context.moveTo(x + r, y);
|
|
7384
7389
|
context.arc(x, y, r, 0, tau);
|
|
7385
7390
|
}
|
|
@@ -7387,12 +7392,12 @@ var Delaunay = class _Delaunay {
|
|
|
7387
7392
|
}
|
|
7388
7393
|
renderHull(context) {
|
|
7389
7394
|
const buffer = context == null ? context = new Path() : void 0;
|
|
7390
|
-
const { hull, points
|
|
7395
|
+
const { hull, points } = this;
|
|
7391
7396
|
const h = hull[0] * 2, n = hull.length;
|
|
7392
|
-
context.moveTo(
|
|
7397
|
+
context.moveTo(points[h], points[h + 1]);
|
|
7393
7398
|
for (let i = 1; i < n; ++i) {
|
|
7394
7399
|
const h2 = 2 * hull[i];
|
|
7395
|
-
context.lineTo(
|
|
7400
|
+
context.lineTo(points[h2], points[h2 + 1]);
|
|
7396
7401
|
}
|
|
7397
7402
|
context.closePath();
|
|
7398
7403
|
return buffer && buffer.value();
|
|
@@ -7404,13 +7409,13 @@ var Delaunay = class _Delaunay {
|
|
|
7404
7409
|
}
|
|
7405
7410
|
renderTriangle(i, context) {
|
|
7406
7411
|
const buffer = context == null ? context = new Path() : void 0;
|
|
7407
|
-
const { points
|
|
7412
|
+
const { points, triangles } = this;
|
|
7408
7413
|
const t0 = triangles[i *= 3] * 2;
|
|
7409
7414
|
const t1 = triangles[i + 1] * 2;
|
|
7410
7415
|
const t2 = triangles[i + 2] * 2;
|
|
7411
|
-
context.moveTo(
|
|
7412
|
-
context.lineTo(
|
|
7413
|
-
context.lineTo(
|
|
7416
|
+
context.moveTo(points[t0], points[t0 + 1]);
|
|
7417
|
+
context.lineTo(points[t1], points[t1 + 1]);
|
|
7418
|
+
context.lineTo(points[t2], points[t2 + 1]);
|
|
7414
7419
|
context.closePath();
|
|
7415
7420
|
return buffer && buffer.value();
|
|
7416
7421
|
}
|
|
@@ -7426,21 +7431,21 @@ var Delaunay = class _Delaunay {
|
|
|
7426
7431
|
return polygon2.value();
|
|
7427
7432
|
}
|
|
7428
7433
|
};
|
|
7429
|
-
function flatArray(
|
|
7430
|
-
const n =
|
|
7434
|
+
function flatArray(points, fx, fy, that) {
|
|
7435
|
+
const n = points.length;
|
|
7431
7436
|
const array = new Float64Array(n * 2);
|
|
7432
7437
|
for (let i = 0; i < n; ++i) {
|
|
7433
|
-
const p =
|
|
7434
|
-
array[i * 2] = fx.call(that, p, i,
|
|
7435
|
-
array[i * 2 + 1] = fy.call(that, p, i,
|
|
7438
|
+
const p = points[i];
|
|
7439
|
+
array[i * 2] = fx.call(that, p, i, points);
|
|
7440
|
+
array[i * 2 + 1] = fy.call(that, p, i, points);
|
|
7436
7441
|
}
|
|
7437
7442
|
return array;
|
|
7438
7443
|
}
|
|
7439
|
-
function* flatIterable(
|
|
7444
|
+
function* flatIterable(points, fx, fy, that) {
|
|
7440
7445
|
let i = 0;
|
|
7441
|
-
for (const p of
|
|
7442
|
-
yield fx.call(that, p, i,
|
|
7443
|
-
yield fy.call(that, p, i,
|
|
7446
|
+
for (const p of points) {
|
|
7447
|
+
yield fx.call(that, p, i, points);
|
|
7448
|
+
yield fy.call(that, p, i, points);
|
|
7444
7449
|
++i;
|
|
7445
7450
|
}
|
|
7446
7451
|
}
|
|
@@ -7466,12 +7471,12 @@ function addAdj(adj, i, j) {
|
|
|
7466
7471
|
}
|
|
7467
7472
|
arr.push(j);
|
|
7468
7473
|
}
|
|
7469
|
-
function computeContour(
|
|
7470
|
-
if (!
|
|
7474
|
+
function computeContour(points) {
|
|
7475
|
+
if (!points || points.length < 3) return [];
|
|
7471
7476
|
const seen = /* @__PURE__ */ new Set();
|
|
7472
7477
|
const uniq = [];
|
|
7473
|
-
for (let i = 0; i <
|
|
7474
|
-
const p =
|
|
7478
|
+
for (let i = 0; i < points.length; i++) {
|
|
7479
|
+
const p = points[i];
|
|
7475
7480
|
const k = `${p[0]}_${p[1]}`;
|
|
7476
7481
|
if (!seen.has(k)) {
|
|
7477
7482
|
seen.add(k);
|
|
@@ -7927,14 +7932,14 @@ function geomReduce(geojson, callback, initialValue) {
|
|
|
7927
7932
|
var import_concaveman = __toESM(require_concaveman(), 1);
|
|
7928
7933
|
function convex(geojson, options = {}) {
|
|
7929
7934
|
options.concavity = options.concavity || Infinity;
|
|
7930
|
-
const
|
|
7935
|
+
const points = [];
|
|
7931
7936
|
coordEach(geojson, (coord) => {
|
|
7932
|
-
|
|
7937
|
+
points.push([coord[0], coord[1]]);
|
|
7933
7938
|
});
|
|
7934
|
-
if (!
|
|
7939
|
+
if (!points.length) {
|
|
7935
7940
|
return null;
|
|
7936
7941
|
}
|
|
7937
|
-
const convexHull = (0, import_concaveman.default)(
|
|
7942
|
+
const convexHull = (0, import_concaveman.default)(points, options.concavity);
|
|
7938
7943
|
if (convexHull.length > 3) {
|
|
7939
7944
|
return polygon([convexHull]);
|
|
7940
7945
|
}
|
|
@@ -8385,9 +8390,9 @@ function distance(p1, p2) {
|
|
|
8385
8390
|
const dy = p2[1] - p1[1];
|
|
8386
8391
|
return Math.sqrt(dx * dx + dy * dy);
|
|
8387
8392
|
}
|
|
8388
|
-
function getCenter(
|
|
8393
|
+
function getCenter(points) {
|
|
8389
8394
|
let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
|
|
8390
|
-
for (const [x, y] of
|
|
8395
|
+
for (const [x, y] of points) {
|
|
8391
8396
|
if (x < minX) minX = x;
|
|
8392
8397
|
if (x > maxX) maxX = x;
|
|
8393
8398
|
if (y < minY) minY = y;
|
|
@@ -8534,14 +8539,14 @@ function calculateClosePointRatioWithGrid2(pointsA, pointsB, threshold = 5e-3, m
|
|
|
8534
8539
|
function isNumber2(num) {
|
|
8535
8540
|
return !isNaN(num) && num !== null && !Array.isArray(num);
|
|
8536
8541
|
}
|
|
8537
|
-
function calculateClosePointWithOBB(
|
|
8542
|
+
function calculateClosePointWithOBB(points, box, maxCalculate = 0.5) {
|
|
8538
8543
|
let closePointsCount = 0;
|
|
8539
8544
|
let calculate = 0;
|
|
8540
|
-
for (const point2 of
|
|
8545
|
+
for (const point2 of points) {
|
|
8541
8546
|
const inside = box.containsPoint(point2);
|
|
8542
8547
|
if (inside) {
|
|
8543
8548
|
closePointsCount++;
|
|
8544
|
-
calculate = closePointsCount /
|
|
8549
|
+
calculate = closePointsCount / points.length;
|
|
8545
8550
|
if (calculate > maxCalculate) {
|
|
8546
8551
|
break;
|
|
8547
8552
|
}
|
|
@@ -8577,32 +8582,32 @@ function compareBoxVolume(box1, box2) {
|
|
|
8577
8582
|
return 0;
|
|
8578
8583
|
}
|
|
8579
8584
|
}
|
|
8580
|
-
function containsObbPoints(obb,
|
|
8585
|
+
function containsObbPoints(obb, points) {
|
|
8581
8586
|
let contains = true;
|
|
8582
|
-
for (let i = 0; i <
|
|
8583
|
-
if (!obb.containsPoint(
|
|
8587
|
+
for (let i = 0; i < points.length; i++) {
|
|
8588
|
+
if (!obb.containsPoint(points[i])) {
|
|
8584
8589
|
contains = false;
|
|
8585
8590
|
break;
|
|
8586
8591
|
}
|
|
8587
8592
|
}
|
|
8588
8593
|
return contains;
|
|
8589
8594
|
}
|
|
8590
|
-
function getCenterAndPointHeight(
|
|
8591
|
-
if (
|
|
8595
|
+
function getCenterAndPointHeight(points) {
|
|
8596
|
+
if (points.length === 0)
|
|
8592
8597
|
return { x: 0, y: 0, z: 0, h: 0 };
|
|
8593
8598
|
let x = 0;
|
|
8594
8599
|
let y = 0;
|
|
8595
8600
|
let maxz = -Infinity;
|
|
8596
8601
|
let minz = Infinity;
|
|
8597
|
-
for (const p of
|
|
8602
|
+
for (const p of points) {
|
|
8598
8603
|
x += p.x;
|
|
8599
8604
|
y += p.y;
|
|
8600
8605
|
maxz = Math.max(maxz, p.z);
|
|
8601
8606
|
minz = Math.min(minz, p.z);
|
|
8602
8607
|
}
|
|
8603
8608
|
return {
|
|
8604
|
-
x: x /
|
|
8605
|
-
y: y /
|
|
8609
|
+
x: x / points.length,
|
|
8610
|
+
y: y / points.length,
|
|
8606
8611
|
z: 0,
|
|
8607
8612
|
maxz,
|
|
8608
8613
|
minz,
|
|
@@ -8635,19 +8640,19 @@ var drawStaircase = (pcdPointsArr, scene) => {
|
|
|
8635
8640
|
side: THREE8.DoubleSide
|
|
8636
8641
|
});
|
|
8637
8642
|
for (let i = 0; i < pcdPointsArr.length; i++) {
|
|
8638
|
-
const
|
|
8643
|
+
const points = [];
|
|
8639
8644
|
for (let j = 0; j < pcdPointsArr[i].path.length; j++) {
|
|
8640
|
-
|
|
8645
|
+
points.push(new THREE8.Vector3(
|
|
8641
8646
|
pcdPointsArr[i].path[j][0],
|
|
8642
8647
|
pcdPointsArr[i].path[j][1],
|
|
8643
8648
|
0
|
|
8644
8649
|
));
|
|
8645
8650
|
}
|
|
8646
|
-
if (
|
|
8651
|
+
if (points.length == 0)
|
|
8647
8652
|
continue;
|
|
8648
8653
|
pointCloudGroup.add(pcdPointsArr[i].obb.getBoxEdge());
|
|
8649
8654
|
const geometry3 = new THREE8.BufferGeometry();
|
|
8650
|
-
geometry3.setFromPoints(
|
|
8655
|
+
geometry3.setFromPoints(points);
|
|
8651
8656
|
const hex = "green";
|
|
8652
8657
|
const _lineMaterial = new THREE8.LineBasicMaterial({ color: hex, depthTest: false, depthWrite: false });
|
|
8653
8658
|
const line2 = new THREE8.Line(geometry3, _lineMaterial);
|
|
@@ -8697,7 +8702,7 @@ var getMergeMeaning = (allProjectionResults, averagePz2, pointCloudCluster = nul
|
|
|
8697
8702
|
const pcdPointsArr = [];
|
|
8698
8703
|
const mapMaxSortFloor = /* @__PURE__ */ new Map();
|
|
8699
8704
|
for (let i = 0; i < allProjectionResults.length; i++) {
|
|
8700
|
-
let
|
|
8705
|
+
let points = allProjectionResults[i].points.map((p) => [p.x, p.y]);
|
|
8701
8706
|
let obj_id = allProjectionResults[i].obj_id;
|
|
8702
8707
|
obj_id = obj_id.replace(/calcony railing/g, "balcony railing").replace(/glass balcony railing/g, "balcony railing").replace(/metal balcony railing/g, "balcony railing").replace(/temporary construction guardrail/g, "balcony railing").replace(/the floor of the house/g, "floor").replace(/the outdoor floor/g, "floor").replace(/roof/g, "Ceiling");
|
|
8703
8708
|
const category = obj_id.split("_").slice(1, 3).join("_").split(".")[0].split("_")[0];
|
|
@@ -8748,8 +8753,8 @@ var getMergeMeaning = (allProjectionResults, averagePz2, pointCloudCluster = nul
|
|
|
8748
8753
|
let mostFrequentEntry = [...mapSortPoint.entries()].reduce(
|
|
8749
8754
|
(max, cur) => cur[1].num > max[1].num ? cur : max
|
|
8750
8755
|
);
|
|
8751
|
-
|
|
8752
|
-
|
|
8756
|
+
points = [];
|
|
8757
|
+
points = mostFrequentEntry[1].points.map((p) => [p.x, p.y]);
|
|
8753
8758
|
threePoints = [];
|
|
8754
8759
|
threePoints = mostFrequentEntry[1].points.map((p) => new THREE8.Vector3(p.x, p.y, p.z));
|
|
8755
8760
|
floorZ = mostFrequentEntry[0];
|
|
@@ -8757,7 +8762,7 @@ var getMergeMeaning = (allProjectionResults, averagePz2, pointCloudCluster = nul
|
|
|
8757
8762
|
const centerData = getCenterAndPointHeight(threePoints);
|
|
8758
8763
|
const data = {
|
|
8759
8764
|
points: threePoints,
|
|
8760
|
-
path: computeContour(
|
|
8765
|
+
path: computeContour(points),
|
|
8761
8766
|
h: centerData.h,
|
|
8762
8767
|
minz: centerData.minz,
|
|
8763
8768
|
maxz: centerData.maxz,
|
|
@@ -9224,15 +9229,15 @@ var getMergeMeaning = (allProjectionResults, averagePz2, pointCloudCluster = nul
|
|
|
9224
9229
|
let newArray = [];
|
|
9225
9230
|
for (let j = 0; j < array.length; j++) {
|
|
9226
9231
|
if (delArray.has(j)) continue;
|
|
9227
|
-
let
|
|
9232
|
+
let points = array[j].points;
|
|
9228
9233
|
let obj_id = array[j].obj_id;
|
|
9229
9234
|
let type2 = array[j].type;
|
|
9230
9235
|
let averagePz3 = array[j].averagePz;
|
|
9231
9236
|
let positionArr = array[j].positionArr;
|
|
9232
9237
|
let isStaircaseBalconyRailing = array[j].isStaircaseBalconyRailing;
|
|
9233
|
-
if (
|
|
9238
|
+
if (points.length < 50)
|
|
9234
9239
|
continue;
|
|
9235
|
-
let clusterResult = pointCloudCluster([
|
|
9240
|
+
let clusterResult = pointCloudCluster([points], {
|
|
9236
9241
|
tolerance: tolerancePointCloudCluster,
|
|
9237
9242
|
minClusterSize: 50,
|
|
9238
9243
|
maxClusterSize: 1e7,
|
|
@@ -9242,7 +9247,7 @@ var getMergeMeaning = (allProjectionResults, averagePz2, pointCloudCluster = nul
|
|
|
9242
9247
|
if (clusterResult.length > 0 && clusterResult[0].length > 1) {
|
|
9243
9248
|
for (const cluster of clusterResult[0]) {
|
|
9244
9249
|
if (cluster.length < 50) continue;
|
|
9245
|
-
const newOriginalPoints = cluster.map((i2) =>
|
|
9250
|
+
const newOriginalPoints = cluster.map((i2) => points[i2]);
|
|
9246
9251
|
const centerData = getCenterAndPointHeight(newOriginalPoints);
|
|
9247
9252
|
let pathPoints = newOriginalPoints.map((p) => [p.x, p.y]);
|
|
9248
9253
|
const data = {
|
|
@@ -9302,7 +9307,7 @@ var getMergeFloorMeaning = (allProjectionResults) => {
|
|
|
9302
9307
|
const pcdPointsArr = [];
|
|
9303
9308
|
const mapMaxSortFloor = /* @__PURE__ */ new Map();
|
|
9304
9309
|
for (let i = 0; i < allProjectionResults.length; i++) {
|
|
9305
|
-
let
|
|
9310
|
+
let points = allProjectionResults[i].points.map((p) => [p.x, p.y]);
|
|
9306
9311
|
let obj_id = allProjectionResults[i].obj_id;
|
|
9307
9312
|
obj_id = obj_id.replace(/the floor of the house/g, "floor").replace(/the outdoor floor/g, "floor");
|
|
9308
9313
|
const category = obj_id.split("_").slice(1, 3).join("_").split(".")[0].split("_")[0];
|
|
@@ -9337,8 +9342,8 @@ var getMergeFloorMeaning = (allProjectionResults) => {
|
|
|
9337
9342
|
let mostFrequentEntry = [...mapSortPoint.entries()].reduce(
|
|
9338
9343
|
(max, cur) => cur[1].num > max[1].num ? cur : max
|
|
9339
9344
|
);
|
|
9340
|
-
|
|
9341
|
-
|
|
9345
|
+
points = [];
|
|
9346
|
+
points = mostFrequentEntry[1].points.map((p) => [p.x, p.y]);
|
|
9342
9347
|
threePoints = [];
|
|
9343
9348
|
threePoints = mostFrequentEntry[1].points.map((p) => new THREE8.Vector3(p.x, p.y, p.z));
|
|
9344
9349
|
floorZ = mostFrequentEntry[0];
|
|
@@ -9346,7 +9351,7 @@ var getMergeFloorMeaning = (allProjectionResults) => {
|
|
|
9346
9351
|
const centerData = getCenterAndPointHeight(threePoints);
|
|
9347
9352
|
const data = {
|
|
9348
9353
|
points: threePoints,
|
|
9349
|
-
path: computeContour(
|
|
9354
|
+
path: computeContour(points),
|
|
9350
9355
|
h: centerData.h,
|
|
9351
9356
|
minz: centerData.minz,
|
|
9352
9357
|
maxz: centerData.maxz,
|
|
@@ -9482,7 +9487,7 @@ var getStaircase = (allProjectionResults, scene) => {
|
|
|
9482
9487
|
let pcdPointsArr = [];
|
|
9483
9488
|
const floorAllProjectionResults = splitFloorProjectsResults[i];
|
|
9484
9489
|
for (let i2 = 0; i2 < floorAllProjectionResults.length; i2++) {
|
|
9485
|
-
let
|
|
9490
|
+
let points = floorAllProjectionResults[i2].points.map((p) => [p.x, p.y]);
|
|
9486
9491
|
let obj_id = floorAllProjectionResults[i2].obj_id;
|
|
9487
9492
|
obj_id = obj_id.replace(/the floor of the house/g, "floor").replace(/the outdoor floor/g, "floor").replace(/calcony railing/g, "balcony railing").replace(/glass balcony railing/g, "balcony railing").replace(/metal balcony railing/g, "balcony railing").replace(/temporary construction guardrail/g, "balcony railing");
|
|
9488
9493
|
const category = obj_id.split("_").slice(1, 3).join("_").split(".")[0].split("_")[0];
|
|
@@ -9518,7 +9523,7 @@ var getStaircase = (allProjectionResults, scene) => {
|
|
|
9518
9523
|
const centerData = getCenterAndPointHeight(threePoints);
|
|
9519
9524
|
const data = {
|
|
9520
9525
|
points: threePoints,
|
|
9521
|
-
path: computeContour(
|
|
9526
|
+
path: computeContour(points),
|
|
9522
9527
|
h: centerData.h,
|
|
9523
9528
|
minz: centerData.minz,
|
|
9524
9529
|
maxz: centerData.maxz,
|
|
@@ -9759,7 +9764,7 @@ var getStaircase = (allProjectionResults, scene) => {
|
|
|
9759
9764
|
let minDist = 0.2;
|
|
9760
9765
|
for (let i = 0; i < StaircaseArray.length; i++) {
|
|
9761
9766
|
const size = StaircaseArray[i].obb.halfSize.clone().multiplyScalar(2);
|
|
9762
|
-
const
|
|
9767
|
+
const points = StaircaseArray[i].points;
|
|
9763
9768
|
let width = size.x;
|
|
9764
9769
|
let length2 = size.y;
|
|
9765
9770
|
let height = size.z;
|
|
@@ -9785,31 +9790,31 @@ var getStaircase = (allProjectionResults, scene) => {
|
|
|
9785
9790
|
let nearLine6PtArray = [];
|
|
9786
9791
|
let nearLine7PtArray = [];
|
|
9787
9792
|
let nearLine8PtArray = [];
|
|
9788
|
-
for (let j = 0; j <
|
|
9789
|
-
let pt1 = line1.closestPointToPoint(
|
|
9790
|
-
let pt2 = line2.closestPointToPoint(
|
|
9791
|
-
let pt3 = line3.closestPointToPoint(
|
|
9792
|
-
let pt4 = line4.closestPointToPoint(
|
|
9793
|
-
let pt5 = line5.closestPointToPoint(
|
|
9794
|
-
let pt6 = line6.closestPointToPoint(
|
|
9795
|
-
let pt7 = line7.closestPointToPoint(
|
|
9796
|
-
let pt8 = line8.closestPointToPoint(
|
|
9797
|
-
if (pt1.distanceTo(
|
|
9798
|
-
nearLine1PtArray.push(
|
|
9799
|
-
if (pt2.distanceTo(
|
|
9800
|
-
nearLine2PtArray.push(
|
|
9801
|
-
if (pt3.distanceTo(
|
|
9802
|
-
nearLine3PtArray.push(
|
|
9803
|
-
if (pt4.distanceTo(
|
|
9804
|
-
nearLine4PtArray.push(
|
|
9805
|
-
if (pt5.distanceTo(
|
|
9806
|
-
nearLine5PtArray.push(
|
|
9807
|
-
if (pt6.distanceTo(
|
|
9808
|
-
nearLine6PtArray.push(
|
|
9809
|
-
if (pt7.distanceTo(
|
|
9810
|
-
nearLine7PtArray.push(
|
|
9811
|
-
if (pt8.distanceTo(
|
|
9812
|
-
nearLine8PtArray.push(
|
|
9793
|
+
for (let j = 0; j < points.length; j++) {
|
|
9794
|
+
let pt1 = line1.closestPointToPoint(points[j], true, new THREE8.Vector3());
|
|
9795
|
+
let pt2 = line2.closestPointToPoint(points[j], true, new THREE8.Vector3());
|
|
9796
|
+
let pt3 = line3.closestPointToPoint(points[j], true, new THREE8.Vector3());
|
|
9797
|
+
let pt4 = line4.closestPointToPoint(points[j], true, new THREE8.Vector3());
|
|
9798
|
+
let pt5 = line5.closestPointToPoint(points[j], true, new THREE8.Vector3());
|
|
9799
|
+
let pt6 = line6.closestPointToPoint(points[j], true, new THREE8.Vector3());
|
|
9800
|
+
let pt7 = line7.closestPointToPoint(points[j], true, new THREE8.Vector3());
|
|
9801
|
+
let pt8 = line8.closestPointToPoint(points[j], true, new THREE8.Vector3());
|
|
9802
|
+
if (pt1.distanceTo(points[j]) < minDist)
|
|
9803
|
+
nearLine1PtArray.push(points[j]);
|
|
9804
|
+
if (pt2.distanceTo(points[j]) < minDist)
|
|
9805
|
+
nearLine2PtArray.push(points[j]);
|
|
9806
|
+
if (pt3.distanceTo(points[j]) < minDist)
|
|
9807
|
+
nearLine3PtArray.push(points[j]);
|
|
9808
|
+
if (pt4.distanceTo(points[j]) < minDist)
|
|
9809
|
+
nearLine4PtArray.push(points[j]);
|
|
9810
|
+
if (pt5.distanceTo(points[j]) < minDist)
|
|
9811
|
+
nearLine5PtArray.push(points[j]);
|
|
9812
|
+
if (pt6.distanceTo(points[j]) < minDist)
|
|
9813
|
+
nearLine6PtArray.push(points[j]);
|
|
9814
|
+
if (pt7.distanceTo(points[j]) < minDist)
|
|
9815
|
+
nearLine7PtArray.push(points[j]);
|
|
9816
|
+
if (pt8.distanceTo(points[j]) < minDist)
|
|
9817
|
+
nearLine8PtArray.push(points[j]);
|
|
9813
9818
|
}
|
|
9814
9819
|
let len1 = obbPoints[0].distanceTo(obbPoints[1]);
|
|
9815
9820
|
let len2 = obbPoints[1].distanceTo(obbPoints[2]);
|
|
@@ -10492,7 +10497,7 @@ function filterPointSetByMainDirection(inputPoints, options = {}) {
|
|
|
10492
10497
|
const sideY = dirX;
|
|
10493
10498
|
let minT = Infinity;
|
|
10494
10499
|
let maxT = -Infinity;
|
|
10495
|
-
const
|
|
10500
|
+
const points = rawPoints.map((p) => {
|
|
10496
10501
|
const dx = p.x - meanX;
|
|
10497
10502
|
const dy = p.y - meanY;
|
|
10498
10503
|
const t = dx * dirX + dy * dirY;
|
|
@@ -10508,7 +10513,7 @@ function filterPointSetByMainDirection(inputPoints, options = {}) {
|
|
|
10508
10513
|
const totalT = maxT - minT || 1;
|
|
10509
10514
|
const binSize = totalT / binCount;
|
|
10510
10515
|
const bins = /* @__PURE__ */ new Map();
|
|
10511
|
-
for (const p of
|
|
10516
|
+
for (const p of points) {
|
|
10512
10517
|
let bin = Math.floor((p.t - minT) / binSize);
|
|
10513
10518
|
if (bin < 0) bin = 0;
|
|
10514
10519
|
if (bin >= binCount) bin = binCount - 1;
|
|
@@ -10555,7 +10560,7 @@ function filterPointSetByMainDirection(inputPoints, options = {}) {
|
|
|
10555
10560
|
}
|
|
10556
10561
|
const keep = [];
|
|
10557
10562
|
const removed = [];
|
|
10558
|
-
for (const p of
|
|
10563
|
+
for (const p of points) {
|
|
10559
10564
|
let bin = Math.floor((p.t - minT) / binSize);
|
|
10560
10565
|
if (bin < 0) bin = 0;
|
|
10561
10566
|
if (bin >= binCount) bin = binCount - 1;
|
|
@@ -10599,10 +10604,10 @@ function medianSorted(arr) {
|
|
|
10599
10604
|
}
|
|
10600
10605
|
return arr[mid];
|
|
10601
10606
|
}
|
|
10602
|
-
function buildPointGrid(
|
|
10607
|
+
function buildPointGrid(points, cellSize) {
|
|
10603
10608
|
const grid = /* @__PURE__ */ new Map();
|
|
10604
|
-
for (let i = 0; i <
|
|
10605
|
-
const p =
|
|
10609
|
+
for (let i = 0; i < points.length; i++) {
|
|
10610
|
+
const p = points[i];
|
|
10606
10611
|
const ix = Math.floor(p.x / cellSize);
|
|
10607
10612
|
const iy = Math.floor(p.y / cellSize);
|
|
10608
10613
|
const iz = Math.floor(p.z / cellSize);
|
|
@@ -10614,8 +10619,8 @@ function buildPointGrid(points2, cellSize) {
|
|
|
10614
10619
|
}
|
|
10615
10620
|
return grid;
|
|
10616
10621
|
}
|
|
10617
|
-
function findPointNeighbors(
|
|
10618
|
-
const p =
|
|
10622
|
+
function findPointNeighbors(points, grid, pointIndex, radius, radiusSq) {
|
|
10623
|
+
const p = points[pointIndex];
|
|
10619
10624
|
const ix = Math.floor(p.x / radius);
|
|
10620
10625
|
const iy = Math.floor(p.y / radius);
|
|
10621
10626
|
const iz = Math.floor(p.z / radius);
|
|
@@ -10628,7 +10633,7 @@ function findPointNeighbors(points2, grid, pointIndex, radius, radiusSq) {
|
|
|
10628
10633
|
if (!list) continue;
|
|
10629
10634
|
for (const candidateIndex of list) {
|
|
10630
10635
|
if (candidateIndex === pointIndex) continue;
|
|
10631
|
-
const q =
|
|
10636
|
+
const q = points[candidateIndex];
|
|
10632
10637
|
const ddx = p.x - q.x;
|
|
10633
10638
|
const ddy = p.y - q.y;
|
|
10634
10639
|
const ddz = p.z - q.z;
|
|
@@ -10674,18 +10679,18 @@ function removeSmallClustersKeepInfo(inputPoints, options = {}) {
|
|
|
10674
10679
|
const {
|
|
10675
10680
|
radius = 0.35
|
|
10676
10681
|
} = options;
|
|
10677
|
-
const
|
|
10682
|
+
const points = inputPoints.map((p, index) => ({
|
|
10678
10683
|
index,
|
|
10679
10684
|
x: p.x,
|
|
10680
10685
|
y: p.y,
|
|
10681
10686
|
z: p.z,
|
|
10682
10687
|
raw: p
|
|
10683
10688
|
}));
|
|
10684
|
-
const grid = buildPointGrid(
|
|
10689
|
+
const grid = buildPointGrid(points, radius);
|
|
10685
10690
|
const radiusSq = radius * radius;
|
|
10686
|
-
const visited = new Array(
|
|
10691
|
+
const visited = new Array(points.length).fill(false);
|
|
10687
10692
|
const clusters = [];
|
|
10688
|
-
for (let i = 0; i <
|
|
10693
|
+
for (let i = 0; i < points.length; i++) {
|
|
10689
10694
|
if (visited[i]) continue;
|
|
10690
10695
|
const cluster = [];
|
|
10691
10696
|
const queue = [i];
|
|
@@ -10694,7 +10699,7 @@ function removeSmallClustersKeepInfo(inputPoints, options = {}) {
|
|
|
10694
10699
|
const currentIndex = queue.shift();
|
|
10695
10700
|
cluster.push(currentIndex);
|
|
10696
10701
|
const neighbors = findPointNeighbors(
|
|
10697
|
-
|
|
10702
|
+
points,
|
|
10698
10703
|
grid,
|
|
10699
10704
|
currentIndex,
|
|
10700
10705
|
radius,
|
|
@@ -10710,7 +10715,7 @@ function removeSmallClustersKeepInfo(inputPoints, options = {}) {
|
|
|
10710
10715
|
clusters.push(cluster);
|
|
10711
10716
|
}
|
|
10712
10717
|
return {
|
|
10713
|
-
points
|
|
10718
|
+
points,
|
|
10714
10719
|
clusters
|
|
10715
10720
|
};
|
|
10716
10721
|
}
|
|
@@ -10755,8 +10760,8 @@ function obbContainsPoint(obb, point2, epsilon3 = 1e-6) {
|
|
|
10755
10760
|
}
|
|
10756
10761
|
|
|
10757
10762
|
// src/utils/clusert.mjs
|
|
10758
|
-
function alphaForTriangle(
|
|
10759
|
-
const xZero =
|
|
10763
|
+
function alphaForTriangle(points, ia, ib, ic) {
|
|
10764
|
+
const xZero = points[ia][0] === 0 || points[ib][0] === 0 || points[ic][0] === 0;
|
|
10760
10765
|
return 1 + (xZero ? 1 : 0);
|
|
10761
10766
|
}
|
|
10762
10767
|
function circumradius2(ax, ay, bx, by, cx, cy) {
|
|
@@ -10767,11 +10772,11 @@ function circumradius2(ax, ay, bx, by, cx, cy) {
|
|
|
10767
10772
|
if (area2 === 0) return Infinity;
|
|
10768
10773
|
return a * b * c / (4 * area2);
|
|
10769
10774
|
}
|
|
10770
|
-
function computeContour2(
|
|
10771
|
-
if (!
|
|
10775
|
+
function computeContour2(points) {
|
|
10776
|
+
if (!points || points.length < 3) return [];
|
|
10772
10777
|
const seen = /* @__PURE__ */ new Set();
|
|
10773
10778
|
const uniq = [];
|
|
10774
|
-
for (const p of
|
|
10779
|
+
for (const p of points) {
|
|
10775
10780
|
const k = `${p[0]}_${p[1]}`;
|
|
10776
10781
|
if (!seen.has(k)) {
|
|
10777
10782
|
seen.add(k);
|
|
@@ -10863,28 +10868,28 @@ var getFlatSlabData = (lines, runDataList, pointCloudCluster = null) => {
|
|
|
10863
10868
|
let maxPointsNum = 0;
|
|
10864
10869
|
let maxPointsZ = 0;
|
|
10865
10870
|
for (const line2 of lines) {
|
|
10866
|
-
let
|
|
10867
|
-
if (
|
|
10871
|
+
let points = line2[1].points;
|
|
10872
|
+
if (points.length < 30) continue;
|
|
10868
10873
|
let mapSortPoint = /* @__PURE__ */ new Map();
|
|
10869
|
-
for (let c = 0; c <
|
|
10870
|
-
let z =
|
|
10874
|
+
for (let c = 0; c < points.length; c++) {
|
|
10875
|
+
let z = points[c].z;
|
|
10871
10876
|
z = Math.floor(z * 10) / 10;
|
|
10872
10877
|
if (mapSortPoint.has(z)) {
|
|
10873
10878
|
const item = mapSortPoint.get(z);
|
|
10874
10879
|
item.num += 1;
|
|
10875
|
-
item.points.push(
|
|
10880
|
+
item.points.push(points[c]);
|
|
10876
10881
|
mapSortPoint.set(z, item);
|
|
10877
10882
|
} else {
|
|
10878
|
-
mapSortPoint.set(z, { num: 1, points: [
|
|
10883
|
+
mapSortPoint.set(z, { num: 1, points: [points[c]] });
|
|
10879
10884
|
}
|
|
10880
10885
|
}
|
|
10881
10886
|
let mostFrequentEntry = [...mapSortPoint.entries()].reduce(
|
|
10882
10887
|
(max, cur) => cur[1].num > max[1].num ? cur : max
|
|
10883
10888
|
);
|
|
10884
|
-
|
|
10889
|
+
points = mostFrequentEntry[1].points.map((p) => new THREE9.Vector3(p.x, p.y, p.z));
|
|
10885
10890
|
let newPoints = [];
|
|
10886
10891
|
if (pointCloudCluster != null) {
|
|
10887
|
-
let clusterResult = pointCloudCluster([
|
|
10892
|
+
let clusterResult = pointCloudCluster([points], {
|
|
10888
10893
|
tolerance: 0.1,
|
|
10889
10894
|
minClusterSize: 30,
|
|
10890
10895
|
maxClusterSize: 1e7,
|
|
@@ -10893,13 +10898,13 @@ var getFlatSlabData = (lines, runDataList, pointCloudCluster = null) => {
|
|
|
10893
10898
|
if (clusterResult.length > 0) {
|
|
10894
10899
|
for (const cluster of clusterResult[0]) {
|
|
10895
10900
|
if (cluster.length < 50) continue;
|
|
10896
|
-
const newOriginalPoints = cluster.map((i) =>
|
|
10901
|
+
const newOriginalPoints = cluster.map((i) => points[i]);
|
|
10897
10902
|
newPoints.push(newOriginalPoints);
|
|
10898
10903
|
}
|
|
10899
10904
|
} else
|
|
10900
|
-
newPoints.push(
|
|
10905
|
+
newPoints.push(points);
|
|
10901
10906
|
} else
|
|
10902
|
-
newPoints.push(
|
|
10907
|
+
newPoints.push(points);
|
|
10903
10908
|
for (let u4 = 0; u4 < newPoints.length; u4++) {
|
|
10904
10909
|
let { minZ, maxZ, averagePz: averagePz2 } = getPointsMinAndMax(newPoints[u4]);
|
|
10905
10910
|
const height = maxZ - minZ;
|
|
@@ -10972,10 +10977,10 @@ var getObliqueSlabData = (lines, runDataList, pointCloudCluster = null) => {
|
|
|
10972
10977
|
}
|
|
10973
10978
|
const averageZ = totalZ / (runDataList.length - 1) + 0.3;
|
|
10974
10979
|
for (let i = 0; i < lines.length; i++) {
|
|
10975
|
-
let
|
|
10980
|
+
let points = lines[i][1].points;
|
|
10976
10981
|
let newPoints = [];
|
|
10977
10982
|
if (pointCloudCluster != null) {
|
|
10978
|
-
let clusterResult = pointCloudCluster([
|
|
10983
|
+
let clusterResult = pointCloudCluster([points], {
|
|
10979
10984
|
tolerance: 0.2,
|
|
10980
10985
|
minClusterSize: 30,
|
|
10981
10986
|
maxClusterSize: 1e7,
|
|
@@ -10984,13 +10989,13 @@ var getObliqueSlabData = (lines, runDataList, pointCloudCluster = null) => {
|
|
|
10984
10989
|
if (clusterResult.length > 0) {
|
|
10985
10990
|
for (const cluster of clusterResult[0]) {
|
|
10986
10991
|
if (cluster.length < 50) continue;
|
|
10987
|
-
const newOriginalPoints = cluster.map((i2) =>
|
|
10992
|
+
const newOriginalPoints = cluster.map((i2) => points[i2]);
|
|
10988
10993
|
newPoints.push(newOriginalPoints);
|
|
10989
10994
|
}
|
|
10990
10995
|
} else
|
|
10991
|
-
newPoints.push(
|
|
10996
|
+
newPoints.push(points);
|
|
10992
10997
|
} else
|
|
10993
|
-
newPoints.push(
|
|
10998
|
+
newPoints.push(points);
|
|
10994
10999
|
if (newPoints.length == 0)
|
|
10995
11000
|
continue;
|
|
10996
11001
|
for (let x = 0; x < newPoints.length; x++) {
|
|
@@ -11041,10 +11046,10 @@ var getObliqueSlabData = (lines, runDataList, pointCloudCluster = null) => {
|
|
|
11041
11046
|
}
|
|
11042
11047
|
slabDatas = [];
|
|
11043
11048
|
for (let i = 0; i < newSlabDatas.length; i++) {
|
|
11044
|
-
let
|
|
11049
|
+
let points = newSlabDatas[i].points;
|
|
11045
11050
|
let newPoints = [];
|
|
11046
11051
|
if (pointCloudCluster != null) {
|
|
11047
|
-
let clusterResult = pointCloudCluster([
|
|
11052
|
+
let clusterResult = pointCloudCluster([points], {
|
|
11048
11053
|
tolerance: 0.2,
|
|
11049
11054
|
minClusterSize: 30,
|
|
11050
11055
|
maxClusterSize: 1e7,
|
|
@@ -11053,13 +11058,13 @@ var getObliqueSlabData = (lines, runDataList, pointCloudCluster = null) => {
|
|
|
11053
11058
|
if (clusterResult.length > 0) {
|
|
11054
11059
|
for (const cluster of clusterResult[0]) {
|
|
11055
11060
|
if (cluster.length < 50) continue;
|
|
11056
|
-
const newOriginalPoints = cluster.map((i2) =>
|
|
11061
|
+
const newOriginalPoints = cluster.map((i2) => points[i2]);
|
|
11057
11062
|
newPoints.push(newOriginalPoints);
|
|
11058
11063
|
}
|
|
11059
11064
|
} else
|
|
11060
|
-
newPoints.push(
|
|
11065
|
+
newPoints.push(points);
|
|
11061
11066
|
} else
|
|
11062
|
-
newPoints.push(
|
|
11067
|
+
newPoints.push(points);
|
|
11063
11068
|
if (newPoints.length == 0)
|
|
11064
11069
|
continue;
|
|
11065
11070
|
for (let x = 0; x < newPoints.length; x++) {
|
|
@@ -11082,15 +11087,15 @@ var getObliqueSlabData = (lines, runDataList, pointCloudCluster = null) => {
|
|
|
11082
11087
|
}
|
|
11083
11088
|
return slabDatas;
|
|
11084
11089
|
};
|
|
11085
|
-
function getPathZ(path3,
|
|
11090
|
+
function getPathZ(path3, points) {
|
|
11086
11091
|
let pathPt = new THREE9.Vector3();
|
|
11087
|
-
for (let i = 0; i <
|
|
11092
|
+
for (let i = 0; i < points.length; i++) {
|
|
11088
11093
|
for (let j = 0; j < path3.length; j++) {
|
|
11089
11094
|
if (path3[j].length == 3)
|
|
11090
11095
|
continue;
|
|
11091
|
-
pathPt.set(path3[j][0], path3[j][1],
|
|
11092
|
-
if (pathPt.distanceTo(
|
|
11093
|
-
path3[j].push(
|
|
11096
|
+
pathPt.set(path3[j][0], path3[j][1], points[i].z);
|
|
11097
|
+
if (pathPt.distanceTo(points[i]) < 1e-3) {
|
|
11098
|
+
path3[j].push(points[i].z);
|
|
11094
11099
|
break;
|
|
11095
11100
|
}
|
|
11096
11101
|
}
|
|
@@ -14817,14 +14822,14 @@ function pointToSegDist(px, pz, x1, z1, x2, z2) {
|
|
|
14817
14822
|
const ez = pz - cz;
|
|
14818
14823
|
return Math.sqrt(ex * ex + ez * ez);
|
|
14819
14824
|
}
|
|
14820
|
-
function polygonArea2(
|
|
14821
|
-
if (
|
|
14825
|
+
function polygonArea2(points) {
|
|
14826
|
+
if (points.length < 3) return 0;
|
|
14822
14827
|
let area2 = 0;
|
|
14823
|
-
const n =
|
|
14828
|
+
const n = points.length;
|
|
14824
14829
|
for (let i = 0; i < n; i++) {
|
|
14825
14830
|
const j = (i + 1) % n;
|
|
14826
|
-
area2 +=
|
|
14827
|
-
area2 -=
|
|
14831
|
+
area2 += points[i].x * points[j].z;
|
|
14832
|
+
area2 -= points[j].x * points[i].z;
|
|
14828
14833
|
}
|
|
14829
14834
|
return Math.abs(area2) / 2;
|
|
14830
14835
|
}
|
|
@@ -15401,23 +15406,23 @@ function rotatePoint(x, z, angle) {
|
|
|
15401
15406
|
z: x * sin + z * cos
|
|
15402
15407
|
};
|
|
15403
15408
|
}
|
|
15404
|
-
function calcTotalLength(
|
|
15409
|
+
function calcTotalLength(points) {
|
|
15405
15410
|
let len = 0;
|
|
15406
|
-
for (let i = 1; i <
|
|
15407
|
-
const dx =
|
|
15408
|
-
const dz =
|
|
15411
|
+
for (let i = 1; i < points.length; i++) {
|
|
15412
|
+
const dx = points[i].x - points[i - 1].x;
|
|
15413
|
+
const dz = points[i].z - points[i - 1].z;
|
|
15409
15414
|
len += Math.sqrt(dx * dx + dz * dz);
|
|
15410
15415
|
}
|
|
15411
15416
|
return len;
|
|
15412
15417
|
}
|
|
15413
|
-
function polygonArea3(
|
|
15414
|
-
if (
|
|
15418
|
+
function polygonArea3(points) {
|
|
15419
|
+
if (points.length < 3) return 0;
|
|
15415
15420
|
let area2 = 0;
|
|
15416
|
-
const n =
|
|
15421
|
+
const n = points.length;
|
|
15417
15422
|
for (let i = 0; i < n; i++) {
|
|
15418
15423
|
const j = (i + 1) % n;
|
|
15419
|
-
area2 +=
|
|
15420
|
-
area2 -=
|
|
15424
|
+
area2 += points[i].x * points[j].z;
|
|
15425
|
+
area2 -= points[j].x * points[i].z;
|
|
15421
15426
|
}
|
|
15422
15427
|
return Math.abs(area2) / 2;
|
|
15423
15428
|
}
|
|
@@ -15463,10 +15468,10 @@ function minDistBetweenPolylines(a, b) {
|
|
|
15463
15468
|
}
|
|
15464
15469
|
|
|
15465
15470
|
// src/wall-shape-classifier/point-cloud.ts
|
|
15466
|
-
function buildDensityGrid(
|
|
15471
|
+
function buildDensityGrid(points, cellSize) {
|
|
15467
15472
|
const cells = /* @__PURE__ */ new Map();
|
|
15468
15473
|
let minX = Infinity, maxX = -Infinity, minZ = Infinity, maxZ = -Infinity;
|
|
15469
|
-
for (const p of
|
|
15474
|
+
for (const p of points) {
|
|
15470
15475
|
const cx = Math.floor(p.x / cellSize);
|
|
15471
15476
|
const cz = Math.floor(p.z / cellSize);
|
|
15472
15477
|
const key = cx + "," + cz;
|
|
@@ -15640,22 +15645,22 @@ function extractBoundaryContour(component, cellSize) {
|
|
|
15640
15645
|
}
|
|
15641
15646
|
return result;
|
|
15642
15647
|
}
|
|
15643
|
-
function simplifyPolyline(
|
|
15644
|
-
if (
|
|
15648
|
+
function simplifyPolyline(points, epsilon3) {
|
|
15649
|
+
if (points.length <= 2) return [...points];
|
|
15645
15650
|
let maxDist = 0;
|
|
15646
15651
|
let maxIdx = 0;
|
|
15647
|
-
const first =
|
|
15648
|
-
const last =
|
|
15649
|
-
for (let i = 1; i <
|
|
15650
|
-
const d = distToSegment(
|
|
15652
|
+
const first = points[0];
|
|
15653
|
+
const last = points[points.length - 1];
|
|
15654
|
+
for (let i = 1; i < points.length - 1; i++) {
|
|
15655
|
+
const d = distToSegment(points[i].x, points[i].z, first.x, first.z, last.x, last.z);
|
|
15651
15656
|
if (d > maxDist) {
|
|
15652
15657
|
maxDist = d;
|
|
15653
15658
|
maxIdx = i;
|
|
15654
15659
|
}
|
|
15655
15660
|
}
|
|
15656
15661
|
if (maxDist > epsilon3) {
|
|
15657
|
-
const left = simplifyPolyline(
|
|
15658
|
-
const right = simplifyPolyline(
|
|
15662
|
+
const left = simplifyPolyline(points.slice(0, maxIdx + 1), epsilon3);
|
|
15663
|
+
const right = simplifyPolyline(points.slice(maxIdx), epsilon3);
|
|
15659
15664
|
return [...left.slice(0, -1), ...right];
|
|
15660
15665
|
}
|
|
15661
15666
|
return [first, last];
|
|
@@ -16854,10 +16859,10 @@ function emptyResult(rawLines, startTime) {
|
|
|
16854
16859
|
}
|
|
16855
16860
|
|
|
16856
16861
|
// src/wall-shape-classifier/point-cloud-filter.ts
|
|
16857
|
-
function removeOutlierPoints(
|
|
16858
|
-
if (!
|
|
16862
|
+
function removeOutlierPoints(points, cellSize, minNeighbors) {
|
|
16863
|
+
if (!points.length || minNeighbors <= 1) return points;
|
|
16859
16864
|
const grid = /* @__PURE__ */ new Map();
|
|
16860
|
-
for (const p of
|
|
16865
|
+
for (const p of points) {
|
|
16861
16866
|
const gx = Math.floor(p.x / cellSize);
|
|
16862
16867
|
const gy = Math.floor(p.y / cellSize);
|
|
16863
16868
|
const key = `${gx},${gy}`;
|
|
@@ -16879,7 +16884,7 @@ function removeOutlierPoints(points2, cellSize, minNeighbors) {
|
|
|
16879
16884
|
}
|
|
16880
16885
|
const kept = [];
|
|
16881
16886
|
let removed = 0;
|
|
16882
|
-
for (const p of
|
|
16887
|
+
for (const p of points) {
|
|
16883
16888
|
const gx = Math.floor(p.x / cellSize);
|
|
16884
16889
|
const gy = Math.floor(p.y / cellSize);
|
|
16885
16890
|
const key = `${gx},${gy}`;
|
|
@@ -16891,10 +16896,10 @@ function removeOutlierPoints(points2, cellSize, minNeighbors) {
|
|
|
16891
16896
|
}
|
|
16892
16897
|
return kept;
|
|
16893
16898
|
}
|
|
16894
|
-
function applyVoxelFilter(
|
|
16895
|
-
if (!
|
|
16899
|
+
function applyVoxelFilter(points, voxelSize, minPointsPerVoxel) {
|
|
16900
|
+
if (!points.length || minPointsPerVoxel <= 1 || voxelSize <= 0) return points;
|
|
16896
16901
|
const grid = /* @__PURE__ */ new Map();
|
|
16897
|
-
for (const p of
|
|
16902
|
+
for (const p of points) {
|
|
16898
16903
|
const ix = Math.floor(p.x / voxelSize);
|
|
16899
16904
|
const iy = Math.floor(p.y / voxelSize);
|
|
16900
16905
|
const iz = Math.floor(p.z / voxelSize);
|
|
@@ -16913,9 +16918,9 @@ function applyVoxelFilter(points2, voxelSize, minPointsPerVoxel) {
|
|
|
16913
16918
|
}
|
|
16914
16919
|
return kept;
|
|
16915
16920
|
}
|
|
16916
|
-
function voxelFilter(
|
|
16917
|
-
const r = applyVoxelFilter(
|
|
16918
|
-
const removed =
|
|
16921
|
+
function voxelFilter(points, voxelSize, minPointsPerVoxel) {
|
|
16922
|
+
const r = applyVoxelFilter(points, voxelSize, minPointsPerVoxel);
|
|
16923
|
+
const removed = points.length - r.length;
|
|
16919
16924
|
return r;
|
|
16920
16925
|
}
|
|
16921
16926
|
function computeVoxelParams(data) {
|
|
@@ -17445,14 +17450,14 @@ function growPolylines(lines, connectDist, angleTolRad) {
|
|
|
17445
17450
|
}
|
|
17446
17451
|
return results;
|
|
17447
17452
|
}
|
|
17448
|
-
function computeTurnAngles(
|
|
17449
|
-
if (
|
|
17453
|
+
function computeTurnAngles(points) {
|
|
17454
|
+
if (points.length < 3) return [];
|
|
17450
17455
|
const deltas = [];
|
|
17451
|
-
for (let i = 1; i <
|
|
17452
|
-
const dx1 =
|
|
17453
|
-
const dz1 =
|
|
17454
|
-
const dx2 =
|
|
17455
|
-
const dz2 =
|
|
17456
|
+
for (let i = 1; i < points.length - 1; i++) {
|
|
17457
|
+
const dx1 = points[i].x - points[i - 1].x;
|
|
17458
|
+
const dz1 = points[i].z - points[i - 1].z;
|
|
17459
|
+
const dx2 = points[i + 1].x - points[i].x;
|
|
17460
|
+
const dz2 = points[i + 1].z - points[i].z;
|
|
17456
17461
|
const angle1 = Math.atan2(dz1, dx1);
|
|
17457
17462
|
const angle2 = Math.atan2(dz2, dx2);
|
|
17458
17463
|
let delta = normalizeAngle(angle2 - angle1);
|
|
@@ -17460,45 +17465,45 @@ function computeTurnAngles(points2) {
|
|
|
17460
17465
|
}
|
|
17461
17466
|
return deltas;
|
|
17462
17467
|
}
|
|
17463
|
-
function classifyType(
|
|
17464
|
-
if (
|
|
17465
|
-
const first =
|
|
17466
|
-
const last =
|
|
17468
|
+
function classifyType(points, minCurvePoints = 6) {
|
|
17469
|
+
if (points.length < 3) return "straight";
|
|
17470
|
+
const first = points[0];
|
|
17471
|
+
const last = points[points.length - 1];
|
|
17467
17472
|
const dx = last.x - first.x;
|
|
17468
17473
|
const dz = last.z - first.z;
|
|
17469
17474
|
const chordLen = Math.sqrt(dx * dx + dz * dz);
|
|
17470
17475
|
if (chordLen > 0.1) {
|
|
17471
17476
|
let maxDev = 0;
|
|
17472
|
-
for (const p of
|
|
17477
|
+
for (const p of points) {
|
|
17473
17478
|
const d = distToSegment(p.x, p.z, first.x, first.z, last.x, last.z);
|
|
17474
17479
|
if (d > maxDev) maxDev = d;
|
|
17475
17480
|
}
|
|
17476
17481
|
if (maxDev < 0.05) return "straight";
|
|
17477
17482
|
}
|
|
17478
|
-
const deltas = computeTurnAngles(
|
|
17483
|
+
const deltas = computeTurnAngles(points);
|
|
17479
17484
|
const totalBend = deltas.reduce((sum2, d) => sum2 + Math.abs(d), 0);
|
|
17480
17485
|
if (totalBend < 0.1) return "straight";
|
|
17481
|
-
if (
|
|
17486
|
+
if (points.length < minCurvePoints) return "straight";
|
|
17482
17487
|
let signChanges = 0;
|
|
17483
17488
|
for (let i = 0; i < deltas.length - 1; i++) {
|
|
17484
17489
|
if (deltas[i] * deltas[i + 1] < 0) signChanges++;
|
|
17485
17490
|
}
|
|
17486
17491
|
return signChanges > 0 ? "S_curve" : "C_curve";
|
|
17487
17492
|
}
|
|
17488
|
-
function splitAtHardCorners(
|
|
17489
|
-
if (
|
|
17493
|
+
function splitAtHardCorners(points, thresholdDeg) {
|
|
17494
|
+
if (points.length < 3) return [points];
|
|
17490
17495
|
const threshold = degToRad(thresholdDeg);
|
|
17491
|
-
const deltas = computeTurnAngles(
|
|
17496
|
+
const deltas = computeTurnAngles(points);
|
|
17492
17497
|
const segments = [];
|
|
17493
17498
|
let startIdx = 0;
|
|
17494
17499
|
for (let i = 0; i < deltas.length; i++) {
|
|
17495
17500
|
if (Math.abs(deltas[i]) > threshold) {
|
|
17496
|
-
segments.push(
|
|
17501
|
+
segments.push(points.slice(startIdx, i + 2));
|
|
17497
17502
|
startIdx = i + 1;
|
|
17498
17503
|
}
|
|
17499
17504
|
}
|
|
17500
|
-
if (startIdx <
|
|
17501
|
-
segments.push(
|
|
17505
|
+
if (startIdx < points.length - 1) {
|
|
17506
|
+
segments.push(points.slice(startIdx));
|
|
17502
17507
|
}
|
|
17503
17508
|
return segments;
|
|
17504
17509
|
}
|