build-dxf 0.1.126 → 0.1.128
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/package.json +1 -1
- package/src/build.js +62 -348
- package/src/demo.d.ts +1 -0
- package/src/index.css +4 -0
- package/src/utils/algorithms/ConstraintSystem.d.ts +17 -0
- package/src/utils/algorithms/OBB.d.ts +4 -4
- package/src/utils/algorithms/PointSpatialHash.d.ts +15 -3
- package/src/utils/algorithms/Polygon.d.ts +0 -4
- package/src/utils/algorithms/PolygonUtils.d.ts +9 -0
- package/src/utils/geometry-manager/GeometryManager.d.ts +2 -0
package/package.json
CHANGED
package/src/build.js
CHANGED
|
@@ -684,54 +684,71 @@ class PointSpatialHash {
|
|
|
684
684
|
}
|
|
685
685
|
return null;
|
|
686
686
|
}
|
|
687
|
-
/**
|
|
688
|
-
*
|
|
687
|
+
/** 通过点,从近到远按圈层搜索
|
|
688
|
+
* 同一圈内不保证距离顺序
|
|
689
|
+
* 返回第一个满足条件的圈层
|
|
689
690
|
*/
|
|
690
|
-
|
|
691
|
+
searchByRing(point2, fn2, maxRing = 1e3) {
|
|
692
|
+
let gridCount = this.map.size;
|
|
691
693
|
const centerI = Math.floor(point2.x / this.gridSize);
|
|
692
694
|
const centerJ = Math.floor(point2.y / this.gridSize);
|
|
693
|
-
const
|
|
694
|
-
|
|
695
|
+
const currentCircle = [];
|
|
696
|
+
const appendGrid = (i, j) => {
|
|
697
|
+
const set2 = this.map.get(this.getGridId(i, j));
|
|
698
|
+
if (!set2) return;
|
|
699
|
+
gridCount--;
|
|
695
700
|
for (const target of set2) {
|
|
696
|
-
|
|
701
|
+
currentCircle.push({
|
|
702
|
+
point: target.point,
|
|
703
|
+
userData: target.userData,
|
|
704
|
+
distanceSq: point2.distanceSquared(target.point)
|
|
705
|
+
});
|
|
697
706
|
}
|
|
707
|
+
};
|
|
708
|
+
appendGrid(centerI, centerJ);
|
|
709
|
+
if (fn2(currentCircle, 0)) {
|
|
710
|
+
return currentCircle;
|
|
698
711
|
}
|
|
712
|
+
if (gridCount === 0) return null;
|
|
699
713
|
for (let r2 = 1; r2 <= maxRing; r2++) {
|
|
714
|
+
currentCircle.length = 0;
|
|
700
715
|
const minI = centerI - r2;
|
|
701
716
|
const maxI = centerI + r2;
|
|
702
717
|
const minJ = centerJ - r2;
|
|
703
718
|
const maxJ = centerJ + r2;
|
|
704
719
|
for (let i = minI; i <= maxI; i++) {
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
for (const target of set22) {
|
|
708
|
-
if (fn2(target)) return target;
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
set22 = this.map.get(this.getGridId(i, maxJ));
|
|
712
|
-
if (set22) {
|
|
713
|
-
for (const target of set22) {
|
|
714
|
-
if (fn2(target)) return target;
|
|
715
|
-
}
|
|
716
|
-
}
|
|
720
|
+
appendGrid(i, minJ);
|
|
721
|
+
appendGrid(i, maxJ);
|
|
717
722
|
}
|
|
718
723
|
for (let j = minJ + 1; j < maxJ; j++) {
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
}
|
|
725
|
-
set22 = this.map.get(this.getGridId(maxI, j));
|
|
726
|
-
if (set22) {
|
|
727
|
-
for (const target of set22) {
|
|
728
|
-
if (fn2(target)) return target;
|
|
729
|
-
}
|
|
730
|
-
}
|
|
724
|
+
appendGrid(minI, j);
|
|
725
|
+
appendGrid(maxI, j);
|
|
726
|
+
}
|
|
727
|
+
if (fn2(currentCircle, r2)) {
|
|
728
|
+
return currentCircle;
|
|
731
729
|
}
|
|
730
|
+
if (gridCount === 0) return null;
|
|
732
731
|
}
|
|
733
732
|
return null;
|
|
734
733
|
}
|
|
734
|
+
/**
|
|
735
|
+
* @param point
|
|
736
|
+
* @param excludeSelf
|
|
737
|
+
* @returns
|
|
738
|
+
*/
|
|
739
|
+
findNearest(point2, excludeSelf = true) {
|
|
740
|
+
let nearest = null;
|
|
741
|
+
this.searchByRing(point2, (circle) => {
|
|
742
|
+
for (const item of circle) {
|
|
743
|
+
if (excludeSelf && item.point === point2) continue;
|
|
744
|
+
if (!nearest || item.distanceSq < nearest.distanceSq) {
|
|
745
|
+
nearest = item;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
return nearest !== null;
|
|
749
|
+
});
|
|
750
|
+
return nearest;
|
|
751
|
+
}
|
|
735
752
|
/**
|
|
736
753
|
* @param point
|
|
737
754
|
*/
|
|
@@ -5833,299 +5850,6 @@ function smallestSurroundingRectangleByArea(geoJsonInput) {
|
|
|
5833
5850
|
}
|
|
5834
5851
|
return resultPolygon;
|
|
5835
5852
|
}
|
|
5836
|
-
const tmpPoint1 = [0, 0];
|
|
5837
|
-
const tmpPoint2 = [0, 0];
|
|
5838
|
-
function lineSegmentsIntersect(p1, p2, q1, q2) {
|
|
5839
|
-
const dx = p2[0] - p1[0];
|
|
5840
|
-
const dy = p2[1] - p1[1];
|
|
5841
|
-
const da2 = q2[0] - q1[0];
|
|
5842
|
-
const db = q2[1] - q1[1];
|
|
5843
|
-
if (da2 * dy - db * dx === 0) {
|
|
5844
|
-
return false;
|
|
5845
|
-
}
|
|
5846
|
-
const s = (dx * (q1[1] - p1[1]) + dy * (p1[0] - q1[0])) / (da2 * dy - db * dx);
|
|
5847
|
-
const t2 = (da2 * (p1[1] - q1[1]) + db * (q1[0] - p1[0])) / (db * dx - da2 * dy);
|
|
5848
|
-
return s >= 0 && s <= 1 && t2 >= 0 && t2 <= 1;
|
|
5849
|
-
}
|
|
5850
|
-
function triangleArea(a2, b4, c) {
|
|
5851
|
-
return (b4[0] - a2[0]) * (c[1] - a2[1]) - (c[0] - a2[0]) * (b4[1] - a2[1]);
|
|
5852
|
-
}
|
|
5853
|
-
function isLeft(a2, b4, c) {
|
|
5854
|
-
return triangleArea(a2, b4, c) > 0;
|
|
5855
|
-
}
|
|
5856
|
-
function isLeftOn(a2, b4, c) {
|
|
5857
|
-
return triangleArea(a2, b4, c) >= 0;
|
|
5858
|
-
}
|
|
5859
|
-
function isRight(a2, b4, c) {
|
|
5860
|
-
return triangleArea(a2, b4, c) < 0;
|
|
5861
|
-
}
|
|
5862
|
-
function isRightOn(a2, b4, c) {
|
|
5863
|
-
return triangleArea(a2, b4, c) <= 0;
|
|
5864
|
-
}
|
|
5865
|
-
function collinear(a2, b4, c, thresholdAngle) {
|
|
5866
|
-
if (thresholdAngle === void 0) {
|
|
5867
|
-
thresholdAngle = 0;
|
|
5868
|
-
}
|
|
5869
|
-
if (!thresholdAngle) {
|
|
5870
|
-
return triangleArea(a2, b4, c) === 0;
|
|
5871
|
-
} else {
|
|
5872
|
-
const ab = tmpPoint1;
|
|
5873
|
-
const bc = tmpPoint2;
|
|
5874
|
-
ab[0] = b4[0] - a2[0];
|
|
5875
|
-
ab[1] = b4[1] - a2[1];
|
|
5876
|
-
bc[0] = c[0] - b4[0];
|
|
5877
|
-
bc[1] = c[1] - b4[1];
|
|
5878
|
-
const dot = ab[0] * bc[0] + ab[1] * bc[1];
|
|
5879
|
-
const magA = Math.sqrt(ab[0] * ab[0] + ab[1] * ab[1]);
|
|
5880
|
-
const magB = Math.sqrt(bc[0] * bc[0] + bc[1] * bc[1]);
|
|
5881
|
-
const angle = Math.acos(dot / (magA * magB));
|
|
5882
|
-
return angle < thresholdAngle;
|
|
5883
|
-
}
|
|
5884
|
-
}
|
|
5885
|
-
function sqdist(a2, b4) {
|
|
5886
|
-
const dx = b4[0] - a2[0];
|
|
5887
|
-
const dy = b4[1] - a2[1];
|
|
5888
|
-
return dx * dx + dy * dy;
|
|
5889
|
-
}
|
|
5890
|
-
function polygonAt(polygon2, i) {
|
|
5891
|
-
const s = polygon2.length;
|
|
5892
|
-
return polygon2[i < 0 ? i % s + s : i % s];
|
|
5893
|
-
}
|
|
5894
|
-
function polygonAppend(polygon2, poly, from, to2) {
|
|
5895
|
-
for (let i = from; i < to2; i++) {
|
|
5896
|
-
polygon2.push(poly[i]);
|
|
5897
|
-
}
|
|
5898
|
-
}
|
|
5899
|
-
function makeCCW(polygon2) {
|
|
5900
|
-
let br2 = 0;
|
|
5901
|
-
const v2 = polygon2;
|
|
5902
|
-
for (let i = 1; i < polygon2.length; ++i) {
|
|
5903
|
-
if (v2[i][1] < v2[br2][1] || v2[i][1] === v2[br2][1] && v2[i][0] > v2[br2][0]) {
|
|
5904
|
-
br2 = i;
|
|
5905
|
-
}
|
|
5906
|
-
}
|
|
5907
|
-
if (!isLeft(polygonAt(polygon2, br2 - 1), polygonAt(polygon2, br2), polygonAt(polygon2, br2 + 1))) {
|
|
5908
|
-
polygonReverse(polygon2);
|
|
5909
|
-
return true;
|
|
5910
|
-
} else {
|
|
5911
|
-
return false;
|
|
5912
|
-
}
|
|
5913
|
-
}
|
|
5914
|
-
function polygonReverse(polygon2) {
|
|
5915
|
-
const tmp = [];
|
|
5916
|
-
const N = polygon2.length;
|
|
5917
|
-
for (let i = 0; i !== N; i++) {
|
|
5918
|
-
tmp.push(polygon2.pop());
|
|
5919
|
-
}
|
|
5920
|
-
for (let i = 0; i !== N; i++) {
|
|
5921
|
-
polygon2[i] = tmp[i];
|
|
5922
|
-
}
|
|
5923
|
-
}
|
|
5924
|
-
function polygonIsReflex(polygon2, i) {
|
|
5925
|
-
return isRight(polygonAt(polygon2, i - 1), polygonAt(polygon2, i), polygonAt(polygon2, i + 1));
|
|
5926
|
-
}
|
|
5927
|
-
function polygonCanSee2(polygon2, a2, b4) {
|
|
5928
|
-
for (let i = 0; i !== polygon2.length; ++i) {
|
|
5929
|
-
if (i === a2 || i === b4 || (i + 1) % polygon2.length === a2 || (i + 1) % polygon2.length === b4) {
|
|
5930
|
-
continue;
|
|
5931
|
-
}
|
|
5932
|
-
if (lineSegmentsIntersect(polygonAt(polygon2, a2), polygonAt(polygon2, b4), polygonAt(polygon2, i), polygonAt(polygon2, i + 1))) {
|
|
5933
|
-
return false;
|
|
5934
|
-
}
|
|
5935
|
-
}
|
|
5936
|
-
return true;
|
|
5937
|
-
}
|
|
5938
|
-
function getIntersectionPoint(p1, p2, q1, q2, delta) {
|
|
5939
|
-
if (delta === void 0) {
|
|
5940
|
-
delta = 0;
|
|
5941
|
-
}
|
|
5942
|
-
const a1 = p2[1] - p1[1];
|
|
5943
|
-
const b1 = p1[0] - p2[0];
|
|
5944
|
-
const c1 = a1 * p1[0] + b1 * p1[1];
|
|
5945
|
-
const a2 = q2[1] - q1[1];
|
|
5946
|
-
const b22 = q1[0] - q2[0];
|
|
5947
|
-
const c22 = a2 * q1[0] + b22 * q1[1];
|
|
5948
|
-
const det = a1 * b22 - a2 * b1;
|
|
5949
|
-
if (!scalarsEqual(det, 0, delta)) {
|
|
5950
|
-
return [(b22 * c1 - b1 * c22) / det, (a1 * c22 - a2 * c1) / det];
|
|
5951
|
-
} else {
|
|
5952
|
-
return [0, 0];
|
|
5953
|
-
}
|
|
5954
|
-
}
|
|
5955
|
-
function quickDecomp(polygon2, result, reflexVertices, steinerPoints, delta, maxlevel, level) {
|
|
5956
|
-
if (result === void 0) {
|
|
5957
|
-
result = [];
|
|
5958
|
-
}
|
|
5959
|
-
if (reflexVertices === void 0) {
|
|
5960
|
-
reflexVertices = [];
|
|
5961
|
-
}
|
|
5962
|
-
if (steinerPoints === void 0) {
|
|
5963
|
-
steinerPoints = [];
|
|
5964
|
-
}
|
|
5965
|
-
if (delta === void 0) {
|
|
5966
|
-
delta = 25;
|
|
5967
|
-
}
|
|
5968
|
-
if (maxlevel === void 0) {
|
|
5969
|
-
maxlevel = 100;
|
|
5970
|
-
}
|
|
5971
|
-
if (level === void 0) {
|
|
5972
|
-
level = 0;
|
|
5973
|
-
}
|
|
5974
|
-
let upperInt = [0, 0];
|
|
5975
|
-
let lowerInt = [0, 0];
|
|
5976
|
-
let p2 = [0, 0];
|
|
5977
|
-
let upperDist = 0;
|
|
5978
|
-
let lowerDist = 0;
|
|
5979
|
-
let d2 = 0;
|
|
5980
|
-
let closestDist = 0;
|
|
5981
|
-
let upperIndex = 0;
|
|
5982
|
-
let lowerIndex = 0;
|
|
5983
|
-
let closestIndex = 0;
|
|
5984
|
-
const lowerPoly = [];
|
|
5985
|
-
const upperPoly = [];
|
|
5986
|
-
const poly = polygon2;
|
|
5987
|
-
const v2 = polygon2;
|
|
5988
|
-
if (v2.length < 3) {
|
|
5989
|
-
return result;
|
|
5990
|
-
}
|
|
5991
|
-
level++;
|
|
5992
|
-
if (level > maxlevel) {
|
|
5993
|
-
console.warn("quickDecomp: max level (" + maxlevel + ") reached.");
|
|
5994
|
-
return result;
|
|
5995
|
-
}
|
|
5996
|
-
for (let i = 0; i < polygon2.length; ++i) {
|
|
5997
|
-
if (polygonIsReflex(poly, i)) {
|
|
5998
|
-
reflexVertices.push(poly[i]);
|
|
5999
|
-
upperDist = lowerDist = Number.MAX_VALUE;
|
|
6000
|
-
for (let j = 0; j < polygon2.length; ++j) {
|
|
6001
|
-
if (isLeft(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j)) && isRightOn(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j - 1))) {
|
|
6002
|
-
p2 = getIntersectionPoint(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j), polygonAt(poly, j - 1));
|
|
6003
|
-
if (isRight(polygonAt(poly, i + 1), polygonAt(poly, i), p2)) {
|
|
6004
|
-
d2 = sqdist(poly[i], p2);
|
|
6005
|
-
if (d2 < lowerDist) {
|
|
6006
|
-
lowerDist = d2;
|
|
6007
|
-
lowerInt = p2;
|
|
6008
|
-
lowerIndex = j;
|
|
6009
|
-
}
|
|
6010
|
-
}
|
|
6011
|
-
}
|
|
6012
|
-
if (isLeft(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j + 1)) && isRightOn(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j))) {
|
|
6013
|
-
p2 = getIntersectionPoint(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j), polygonAt(poly, j + 1));
|
|
6014
|
-
if (isLeft(polygonAt(poly, i - 1), polygonAt(poly, i), p2)) {
|
|
6015
|
-
d2 = sqdist(poly[i], p2);
|
|
6016
|
-
if (d2 < upperDist) {
|
|
6017
|
-
upperDist = d2;
|
|
6018
|
-
upperInt = p2;
|
|
6019
|
-
upperIndex = j;
|
|
6020
|
-
}
|
|
6021
|
-
}
|
|
6022
|
-
}
|
|
6023
|
-
}
|
|
6024
|
-
if (lowerIndex === (upperIndex + 1) % polygon2.length) {
|
|
6025
|
-
p2[0] = (lowerInt[0] + upperInt[0]) / 2;
|
|
6026
|
-
p2[1] = (lowerInt[1] + upperInt[1]) / 2;
|
|
6027
|
-
steinerPoints.push(p2);
|
|
6028
|
-
if (i < upperIndex) {
|
|
6029
|
-
polygonAppend(lowerPoly, poly, i, upperIndex + 1);
|
|
6030
|
-
lowerPoly.push(p2);
|
|
6031
|
-
upperPoly.push(p2);
|
|
6032
|
-
if (lowerIndex !== 0) {
|
|
6033
|
-
polygonAppend(upperPoly, poly, lowerIndex, poly.length);
|
|
6034
|
-
}
|
|
6035
|
-
polygonAppend(upperPoly, poly, 0, i + 1);
|
|
6036
|
-
} else {
|
|
6037
|
-
if (i !== 0) {
|
|
6038
|
-
polygonAppend(lowerPoly, poly, i, poly.length);
|
|
6039
|
-
}
|
|
6040
|
-
polygonAppend(lowerPoly, poly, 0, upperIndex + 1);
|
|
6041
|
-
lowerPoly.push(p2);
|
|
6042
|
-
upperPoly.push(p2);
|
|
6043
|
-
polygonAppend(upperPoly, poly, lowerIndex, i + 1);
|
|
6044
|
-
}
|
|
6045
|
-
} else {
|
|
6046
|
-
if (lowerIndex > upperIndex) {
|
|
6047
|
-
upperIndex += polygon2.length;
|
|
6048
|
-
}
|
|
6049
|
-
closestDist = Number.MAX_VALUE;
|
|
6050
|
-
if (upperIndex < lowerIndex) {
|
|
6051
|
-
return result;
|
|
6052
|
-
}
|
|
6053
|
-
for (let j = lowerIndex; j <= upperIndex; ++j) {
|
|
6054
|
-
if (isLeftOn(polygonAt(poly, i - 1), polygonAt(poly, i), polygonAt(poly, j)) && isRightOn(polygonAt(poly, i + 1), polygonAt(poly, i), polygonAt(poly, j))) {
|
|
6055
|
-
d2 = sqdist(polygonAt(poly, i), polygonAt(poly, j));
|
|
6056
|
-
if (d2 < closestDist && polygonCanSee2(poly, i, j)) {
|
|
6057
|
-
closestDist = d2;
|
|
6058
|
-
closestIndex = j % polygon2.length;
|
|
6059
|
-
}
|
|
6060
|
-
}
|
|
6061
|
-
}
|
|
6062
|
-
if (i < closestIndex) {
|
|
6063
|
-
polygonAppend(lowerPoly, poly, i, closestIndex + 1);
|
|
6064
|
-
if (closestIndex !== 0) {
|
|
6065
|
-
polygonAppend(upperPoly, poly, closestIndex, v2.length);
|
|
6066
|
-
}
|
|
6067
|
-
polygonAppend(upperPoly, poly, 0, i + 1);
|
|
6068
|
-
} else {
|
|
6069
|
-
if (i !== 0) {
|
|
6070
|
-
polygonAppend(lowerPoly, poly, i, v2.length);
|
|
6071
|
-
}
|
|
6072
|
-
polygonAppend(lowerPoly, poly, 0, closestIndex + 1);
|
|
6073
|
-
polygonAppend(upperPoly, poly, closestIndex, i + 1);
|
|
6074
|
-
}
|
|
6075
|
-
}
|
|
6076
|
-
if (lowerPoly.length < upperPoly.length) {
|
|
6077
|
-
quickDecomp(lowerPoly, result, reflexVertices, steinerPoints, delta, maxlevel, level);
|
|
6078
|
-
quickDecomp(upperPoly, result, reflexVertices, steinerPoints, delta, maxlevel, level);
|
|
6079
|
-
} else {
|
|
6080
|
-
quickDecomp(upperPoly, result, reflexVertices, steinerPoints, delta, maxlevel, level);
|
|
6081
|
-
quickDecomp(lowerPoly, result, reflexVertices, steinerPoints, delta, maxlevel, level);
|
|
6082
|
-
}
|
|
6083
|
-
return result;
|
|
6084
|
-
}
|
|
6085
|
-
}
|
|
6086
|
-
result.push(polygon2);
|
|
6087
|
-
return result;
|
|
6088
|
-
}
|
|
6089
|
-
function removeCollinearPoints(polygon2, thresholdAngle) {
|
|
6090
|
-
if (thresholdAngle === void 0) {
|
|
6091
|
-
thresholdAngle = 0;
|
|
6092
|
-
}
|
|
6093
|
-
let num = 0;
|
|
6094
|
-
for (let i = polygon2.length - 1; polygon2.length > 3 && i >= 0; --i) {
|
|
6095
|
-
if (collinear(polygonAt(polygon2, i - 1), polygonAt(polygon2, i), polygonAt(polygon2, i + 1), thresholdAngle)) {
|
|
6096
|
-
polygon2.splice(i % polygon2.length, 1);
|
|
6097
|
-
num++;
|
|
6098
|
-
}
|
|
6099
|
-
}
|
|
6100
|
-
return num;
|
|
6101
|
-
}
|
|
6102
|
-
function scalarsEqual(a2, b4, precision) {
|
|
6103
|
-
if (precision === void 0) {
|
|
6104
|
-
precision = 0;
|
|
6105
|
-
}
|
|
6106
|
-
precision = precision || 0;
|
|
6107
|
-
return Math.abs(a2 - b4) <= precision;
|
|
6108
|
-
}
|
|
6109
|
-
function pointsEqual(a2, b4, precision) {
|
|
6110
|
-
if (precision === void 0) {
|
|
6111
|
-
precision = 0;
|
|
6112
|
-
}
|
|
6113
|
-
return scalarsEqual(a2[0], b4[0], precision) && scalarsEqual(a2[1], b4[1], precision);
|
|
6114
|
-
}
|
|
6115
|
-
function removeDuplicatePoints(polygon2, precision) {
|
|
6116
|
-
if (precision === void 0) {
|
|
6117
|
-
precision = 0;
|
|
6118
|
-
}
|
|
6119
|
-
for (let i = polygon2.length - 1; i >= 1; --i) {
|
|
6120
|
-
const pi2 = polygon2[i];
|
|
6121
|
-
for (let j = i - 1; j >= 0; --j) {
|
|
6122
|
-
if (pointsEqual(pi2, polygon2[j], precision)) {
|
|
6123
|
-
polygon2.splice(i, 1);
|
|
6124
|
-
continue;
|
|
6125
|
-
}
|
|
6126
|
-
}
|
|
6127
|
-
}
|
|
6128
|
-
}
|
|
6129
5853
|
class Polygon extends Array {
|
|
6130
5854
|
[Symbol.iterator]() {
|
|
6131
5855
|
return super[Symbol.iterator]();
|
|
@@ -6444,18 +6168,6 @@ class Polygon extends Array {
|
|
|
6444
6168
|
this.set(polygons[0]);
|
|
6445
6169
|
return true;
|
|
6446
6170
|
}
|
|
6447
|
-
/** 拆分为凸包
|
|
6448
|
-
* @returns
|
|
6449
|
-
*/
|
|
6450
|
-
splitConvexHull() {
|
|
6451
|
-
const concavePolygon = this.toArrays();
|
|
6452
|
-
makeCCW(concavePolygon);
|
|
6453
|
-
removeDuplicatePoints(concavePolygon);
|
|
6454
|
-
removeCollinearPoints(concavePolygon);
|
|
6455
|
-
const optimalConvexPolygons = quickDecomp(concavePolygon);
|
|
6456
|
-
if (!optimalConvexPolygons) return null;
|
|
6457
|
-
return optimalConvexPolygons.map((array) => new Polygon(array.map((item) => Point.from(item))));
|
|
6458
|
-
}
|
|
6459
6171
|
/** 包围盒检测
|
|
6460
6172
|
* @param box
|
|
6461
6173
|
* @returns
|
|
@@ -7539,27 +7251,27 @@ class OBB2 extends OBB$1 {
|
|
|
7539
7251
|
* @param box
|
|
7540
7252
|
* @param position
|
|
7541
7253
|
* @param rotation
|
|
7542
|
-
* @param
|
|
7254
|
+
* @param out
|
|
7543
7255
|
* @returns
|
|
7544
7256
|
*/
|
|
7545
|
-
static from(box, position, rotation,
|
|
7257
|
+
static from(box, position, rotation, out = new OBB2()) {
|
|
7546
7258
|
if (rotation instanceof THREE.Euler) quat.setFromEuler(rotation);
|
|
7547
7259
|
else if (rotation instanceof THREE.Quaternion) quat.copy(rotation);
|
|
7548
7260
|
else throw new Error(`传入的旋转不是欧拉角或者四元数`);
|
|
7549
7261
|
matrix4.compose(position, quat, scale);
|
|
7550
|
-
|
|
7551
|
-
|
|
7552
|
-
|
|
7553
|
-
return
|
|
7262
|
+
out.center.copy(position);
|
|
7263
|
+
out.halfSize.copy(box.multiplyScalar(0.5));
|
|
7264
|
+
out.rotation.setFromMatrix4(matrix4);
|
|
7265
|
+
return out;
|
|
7554
7266
|
}
|
|
7555
7267
|
/** 通过2d路径创建
|
|
7556
7268
|
* @param path
|
|
7557
7269
|
* @param origin
|
|
7558
7270
|
* @param height
|
|
7559
|
-
* @param
|
|
7271
|
+
* @param out
|
|
7560
7272
|
* @returns
|
|
7561
7273
|
*/
|
|
7562
|
-
static fromByPath2D(path, origin, height,
|
|
7274
|
+
static fromByPath2D(path, origin, height, out = new OBB2()) {
|
|
7563
7275
|
const result = smallestSurroundingRectangleByArea({
|
|
7564
7276
|
type: "Polygon",
|
|
7565
7277
|
coordinates: [path.map((p2) => [p2.x, p2.y])]
|
|
@@ -7574,8 +7286,8 @@ class OBB2 extends OBB$1 {
|
|
|
7574
7286
|
const [x, y] = getCenter(rectangle);
|
|
7575
7287
|
origin.x = x;
|
|
7576
7288
|
origin.y = y;
|
|
7577
|
-
|
|
7578
|
-
return
|
|
7289
|
+
out = this.from(vec3, origin, euler, out);
|
|
7290
|
+
return out;
|
|
7579
7291
|
}
|
|
7580
7292
|
}
|
|
7581
7293
|
const matrix4 = new THREE.Matrix4(), quat = new THREE.Quaternion(), euler = new THREE.Euler(), scale = new THREE.Vector3(1, 1, 1), vec3 = new THREE.Vector3(), box3$2 = new THREE.Box3();
|
|
@@ -10833,7 +10545,9 @@ class ThreeVJiaPipeline extends Pipeline {
|
|
|
10833
10545
|
console.warn(`第${i}个物品轮廓为空`);
|
|
10834
10546
|
return;
|
|
10835
10547
|
}
|
|
10836
|
-
const itemPoly = new Polygon(
|
|
10548
|
+
const itemPoly = new Polygon(
|
|
10549
|
+
contour.map((p2) => Point.from(p2).rotate(json.center, json.angle))
|
|
10550
|
+
), center = itemPoly.getCenter(), index2 = roomPloys.findIndex((poly) => poly.pointWithin(center));
|
|
10837
10551
|
if (index2 < 0) return;
|
|
10838
10552
|
try {
|
|
10839
10553
|
const rect = itemPoly.getMinimumBoundingRectangle().map((p2) => p2.toJson2D());
|
|
@@ -11080,7 +10794,7 @@ function innerWallLine(lines, trajectory2) {
|
|
|
11080
10794
|
lud.forEachPathLine((start, end, line, index2, endType, indxeList) => {
|
|
11081
10795
|
temLine.start.copy(start);
|
|
11082
10796
|
temLine.end.copy(end);
|
|
11083
|
-
const wallWidth =
|
|
10797
|
+
const wallWidth = DEFAULT_WALL_WIDTH;
|
|
11084
10798
|
wallWidths[index2] = wallWidth;
|
|
11085
10799
|
const hw = indxeList.length ? Math.max(...indxeList.map((i) => wallWidths[i])) * 0.5 : wallWidth * 0.5;
|
|
11086
10800
|
if (index2 !== 0) {
|
|
@@ -22434,7 +22148,7 @@ class SceneAutoGenerat {
|
|
|
22434
22148
|
await Promise.all(this.itemList.map(async (item) => await this.getModel(item)));
|
|
22435
22149
|
}
|
|
22436
22150
|
static itemParse(item) {
|
|
22437
|
-
if (!Array.isArray(item.contour) || !item.contour.length) return null;
|
|
22151
|
+
if (!Array.isArray(item.quadContour ?? item.contour) || !item.contour.length) return null;
|
|
22438
22152
|
const contour = Point.fromByList(item.contour ?? []), rectangle = new Polygon(Qa(contour.map((p2) => [p2.x, p2.y])).map((p2) => Point.from(p2)));
|
|
22439
22153
|
rectangle.pop();
|
|
22440
22154
|
const z = item.box.min.z, height = Math.abs(item.box.max.z - z), max = rectangle.getMaxLengthInfo(), min = rectangle.getMinLengthInfo(), direction = max.start.y < max.end.y ? max.start.directionFrom(max.end) : max.end.directionFrom(max.start), shape = new THREE.Shape();
|
package/src/demo.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/src/index.css
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare class Variable {
|
|
2
|
+
value: number;
|
|
3
|
+
fixed: boolean;
|
|
4
|
+
constructor(value: number, fixed?: boolean);
|
|
5
|
+
}
|
|
6
|
+
export interface Constraint {
|
|
7
|
+
evaluate(): number[];
|
|
8
|
+
}
|
|
9
|
+
export declare class ConstraintSystem {
|
|
10
|
+
constraints: Constraint[];
|
|
11
|
+
variables: Variable[];
|
|
12
|
+
addConstraint(c: Constraint): void;
|
|
13
|
+
addVariable(v: Variable): void;
|
|
14
|
+
residuals(): number[];
|
|
15
|
+
jacobian(eps?: number): number[][];
|
|
16
|
+
solve(iterations?: number): void;
|
|
17
|
+
}
|
|
@@ -12,19 +12,19 @@ export declare class OBB extends OBB_ {
|
|
|
12
12
|
* @param box
|
|
13
13
|
* @param position
|
|
14
14
|
* @param rotation
|
|
15
|
-
* @param
|
|
15
|
+
* @param out
|
|
16
16
|
* @returns
|
|
17
17
|
*/
|
|
18
|
-
static from(box: THREE.Vector3, position: THREE.Vector3, rotation: THREE.Euler | THREE.Quaternion,
|
|
18
|
+
static from(box: THREE.Vector3, position: THREE.Vector3, rotation: THREE.Euler | THREE.Quaternion, out?: OBB): OBB;
|
|
19
19
|
/** 通过2d路径创建
|
|
20
20
|
* @param path
|
|
21
21
|
* @param origin
|
|
22
22
|
* @param height
|
|
23
|
-
* @param
|
|
23
|
+
* @param out
|
|
24
24
|
* @returns
|
|
25
25
|
*/
|
|
26
26
|
static fromByPath2D(path: {
|
|
27
27
|
x: number;
|
|
28
28
|
y: number;
|
|
29
|
-
}[], origin: THREE.Vector3, height: number,
|
|
29
|
+
}[], origin: THREE.Vector3, height: number, out?: OBB): OBB;
|
|
30
30
|
}
|
|
@@ -10,6 +10,11 @@ type Target<T> = {
|
|
|
10
10
|
type NodeSet<T> = Set<Target<T>>;
|
|
11
11
|
export type PvgTarget<T> = Target<T>;
|
|
12
12
|
export type ResultList<T = any> = Array<Target<T>>;
|
|
13
|
+
export type CircleResult<T = any> = {
|
|
14
|
+
point: Point;
|
|
15
|
+
distanceSq: number;
|
|
16
|
+
userData?: T;
|
|
17
|
+
};
|
|
13
18
|
export declare class PointSpatialHash<T = Record<string, any>> {
|
|
14
19
|
map: Map<string, NodeSet<T>>;
|
|
15
20
|
gridSize: number;
|
|
@@ -109,10 +114,17 @@ export declare class PointSpatialHash<T = Record<string, any>> {
|
|
|
109
114
|
point: Point;
|
|
110
115
|
userData: T;
|
|
111
116
|
} | null;
|
|
112
|
-
/**
|
|
113
|
-
*
|
|
117
|
+
/** 通过点,从近到远按圈层搜索
|
|
118
|
+
* 同一圈内不保证距离顺序
|
|
119
|
+
* 返回第一个满足条件的圈层
|
|
120
|
+
*/
|
|
121
|
+
searchByRing(point: Point, fn: (circle: CircleResult<T>[], circleNum: number) => boolean, maxRing?: number): CircleResult<T>[] | null;
|
|
122
|
+
/**
|
|
123
|
+
* @param point
|
|
124
|
+
* @param excludeSelf
|
|
125
|
+
* @returns
|
|
114
126
|
*/
|
|
115
|
-
|
|
127
|
+
findNearest(point: Point, excludeSelf?: boolean): CircleResult<T> | null;
|
|
116
128
|
/**
|
|
117
129
|
* @param point
|
|
118
130
|
*/
|
|
@@ -91,10 +91,6 @@ export declare class Polygon<T = any> extends Array<Point<T>> {
|
|
|
91
91
|
* @param polygon
|
|
92
92
|
*/
|
|
93
93
|
difference(polygons: Polygon | Polygon[], scale?: number): boolean;
|
|
94
|
-
/** 拆分为凸包
|
|
95
|
-
* @returns
|
|
96
|
-
*/
|
|
97
|
-
splitConvexHull(): Polygon<Record<string, any>>[] | null;
|
|
98
94
|
/** 包围盒检测
|
|
99
95
|
* @param box
|
|
100
96
|
* @returns
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { LineSegment } from './LineSegment';
|
|
2
|
+
import { Polygon } from './Polygon';
|
|
3
|
+
export declare class PolygonUtils {
|
|
4
|
+
/** 拆分为凸包
|
|
5
|
+
* @returns
|
|
6
|
+
*/
|
|
7
|
+
static splitConvexHull(ploy: Polygon): Polygon<Record<string, any>>[] | null;
|
|
8
|
+
static splitByLine(lines: LineSegment[], clipLine: LineSegment): LineSegment[][];
|
|
9
|
+
}
|