build-dxf 0.1.87 → 0.1.88

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "build-dxf",
3
- "version": "0.1.87",
3
+ "version": "0.1.88",
4
4
  "description": "线段构建双线墙壁的dxf版本",
5
5
  "main": "./src/index.js",
6
6
  "types": "./src/index.d.ts",
package/src/build.js CHANGED
@@ -377,7 +377,7 @@ class PointVirtualGrid {
377
377
  * 查找相同点
378
378
  * @param point
379
379
  */
380
- queryPoint(point2, excludeOneself = false) {
380
+ queryPoint(point2, excludeOneself = false, eps = 1e-9) {
381
381
  const list = new PvgList();
382
382
  let set2;
383
383
  if (point2.currentData[this.id]) {
@@ -387,7 +387,7 @@ class PointVirtualGrid {
387
387
  if (this.map.has(id)) set2 = this.map.get(id);
388
388
  }
389
389
  set2?.forEach((item) => {
390
- if (point2.equal(item.point)) {
390
+ if (point2.equal(item.point, eps)) {
391
391
  if (excludeOneself && point2 === item.point) return;
392
392
  list.push(item);
393
393
  }
@@ -1706,13 +1706,20 @@ class LineSegment {
1706
1706
  return (px * dx + py * dy) / len2;
1707
1707
  }
1708
1708
  /** 获取两条线段夹角
1709
- * @deprecated 已废弃
1709
+ * @deprecated 已废弃, 请使用 angle
1710
1710
  * @param line
1711
1711
  */
1712
1712
  includedAngle(line) {
1713
1713
  const d1 = this.direction(), d2 = line.direction();
1714
1714
  return d1.angleBetween(d2) / (Math.PI / 180);
1715
1715
  }
1716
+ /** 获取两条线段夹角
1717
+ * @param line
1718
+ */
1719
+ angle(line, opt) {
1720
+ const d1 = this.direction(), d2 = line.direction();
1721
+ return d1.angle(d2, opt);
1722
+ }
1716
1723
  /**
1717
1724
  * 判断两条线段,是否在同一直线上:
1718
1725
  * - 返回 -1:不在同一直线(不共线)
@@ -2332,7 +2339,7 @@ class Point {
2332
2339
  * @param point
2333
2340
  * @returns
2334
2341
  */
2335
- equal(point2) {
2342
+ equal(point2, eps = 1e-9) {
2336
2343
  return Math.abs(point2.x - this.x) < 1e-9 && Math.abs(point2.y - this.y) < 1e-9;
2337
2344
  }
2338
2345
  /**
@@ -2594,8 +2601,8 @@ class Point {
2594
2601
  }
2595
2602
  return num;
2596
2603
  }
2597
- hashCode(fixed = 4) {
2598
- return `${this.x.toFixed(fixed)},${this.y.toFixed(6)}`;
2604
+ hashCode(fixed = 6) {
2605
+ return `${this.x.toFixed(fixed)},${this.y.toFixed(fixed)}`;
2599
2606
  }
2600
2607
  /**
2601
2608
  * 克隆
@@ -2641,7 +2648,7 @@ class Point {
2641
2648
  * @param tolerance
2642
2649
  * @returns
2643
2650
  */
2644
- static adsorb(points, tolerance = 15e-5, mode = "average") {
2651
+ static adsorb(points, tolerance = 1e-3, mode = "average") {
2645
2652
  const grid = new PointVirtualGrid();
2646
2653
  points.forEach((p2) => grid.insert(p2));
2647
2654
  const visited = /* @__PURE__ */ new Set();
@@ -2662,7 +2669,6 @@ class Point {
2662
2669
  results.forEach((p2) => {
2663
2670
  p2.set(x, y);
2664
2671
  visited.add(p2);
2665
- grid.update(p2);
2666
2672
  grid.remove(p2);
2667
2673
  });
2668
2674
  }
@@ -3473,6 +3479,18 @@ class UndirectedGraph {
3473
3479
  callbackFun(node, neighbors);
3474
3480
  }
3475
3481
  }
3482
+ /** 遍历边
3483
+ * @param callbackFun
3484
+ */
3485
+ forEachEdge(callbackFun) {
3486
+ for (const [node, neighbors] of this.adjacencyList.entries()) {
3487
+ for (const neighbor of neighbors) {
3488
+ if (neighbor > node) {
3489
+ callbackFun(node, neighbor);
3490
+ }
3491
+ }
3492
+ }
3493
+ }
3476
3494
  }
3477
3495
  class LineSegmentUndirectedGraph extends UndirectedGraph {
3478
3496
  // 线段存储:使用规范化 key (小索引-大索引) 避免双向存储
@@ -3630,7 +3648,7 @@ class LineSegmentUndirectedGraph extends UndirectedGraph {
3630
3648
  * @returns
3631
3649
  */
3632
3650
  static breakpointMerging(lines, callBack, removeLines = /* @__PURE__ */ new Set(), newLines = []) {
3633
- Point.adsorb(lines.flatMap((line) => line.points));
3651
+ Point.adsorb(lines.flatMap((line) => line.points), 1e-4);
3634
3652
  const lud = new LineSegmentUndirectedGraph(lines);
3635
3653
  lud.breakpointMerging(callBack, removeLines, newLines);
3636
3654
  lines = lud.getLineAll();
@@ -5915,7 +5933,7 @@ function migration(newLine, oldLine) {
5915
5933
  }) ?? [];
5916
5934
  });
5917
5935
  }
5918
- function lineSegmentClipping(lines, minLen = 0.03, dedup = true) {
5936
+ function lineSegmentClipping(lines, minLen = 1e-9, dedup = true) {
5919
5937
  const quadtree = new Quadtree(Box2.fromByLineSegment(...lines));
5920
5938
  lines.forEach((line) => quadtree.insert({ line, userData: void 0 }));
5921
5939
  let newLines = lines.flatMap((line) => {
@@ -5952,34 +5970,30 @@ var Side = /* @__PURE__ */ ((Side2) => {
5952
5970
  })(Side || {});
5953
5971
  class MiniCircles {
5954
5972
  debug = {
5955
- angle: false
5973
+ angle: false,
5974
+ edges: false
5956
5975
  };
5976
+ scope = 1e-3;
5957
5977
  /** 通过并查集,查找为环的一部分边
5958
5978
  * @description
5959
5979
  * @param lines
5960
5980
  */
5961
5981
  findCycleEntryEdges(lineUG_) {
5962
5982
  if (!(lineUG_ instanceof LineSegmentUndirectedGraph)) {
5963
- if (Array.isArray(lineUG_)) lineUG_ = new LineSegmentUndirectedGraph(lineUG_);
5964
- else throw new Error("参数错误,非线段数组或者线段无向图对象");
5965
- }
5966
- const unionFindSet = new UnionFindSet(lineUG_.size), visited = /* @__PURE__ */ new Set(), ringEdges = [], lineUG = lineUG_;
5967
- function find(n1) {
5968
- visited.add(n1);
5969
- const neighbors = lineUG.getNeighbors(n1);
5970
- neighbors?.forEach((n2) => {
5971
- if (visited.has(n2)) return;
5972
- if (unionFindSet.find(n1) === unionFindSet.find(n2)) {
5973
- const line = lineUG.getLine(n1, n2);
5974
- ringEdges.push(line);
5975
- } else {
5976
- unionFindSet.union(n1, n2);
5977
- }
5978
- });
5983
+ if (Array.isArray(lineUG_)) {
5984
+ lineUG_ = new LineSegmentUndirectedGraph(lineUG_);
5985
+ } else {
5986
+ throw new Error("参数错误");
5987
+ }
5979
5988
  }
5980
- lineUG.forEach((n1) => {
5981
- if (visited.has(n1)) return;
5982
- find(n1);
5989
+ const lineUG = lineUG_, unionFind = new UnionFindSet(lineUG.size), ringEdges = [];
5990
+ lineUG.forEachEdge((n1, n2) => {
5991
+ const line = lineUG.getLine(n1, n2);
5992
+ if (unionFind.find(n1) === unionFind.find(n2)) {
5993
+ ringEdges.push(line);
5994
+ } else {
5995
+ unionFind.union(n1, n2);
5996
+ }
5983
5997
  });
5984
5998
  return ringEdges;
5985
5999
  }
@@ -6024,7 +6038,7 @@ class MiniCircles {
6024
6038
  */
6025
6039
  findSameSidePath(opt) {
6026
6040
  let count = 0;
6027
- let { A, B, exitPoint, grid, path = /* @__PURE__ */ new Set() } = opt;
6041
+ let { A, B, exitPoint = A, grid, path = /* @__PURE__ */ new Set() } = opt;
6028
6042
  if (Array.isArray(grid)) {
6029
6043
  const lines = grid;
6030
6044
  grid = new PointVirtualGrid();
@@ -6036,7 +6050,7 @@ class MiniCircles {
6036
6050
  return;
6037
6051
  }
6038
6052
  if (exitPoint.equal(B)) return [...path];
6039
- const candidates = grid.queryPoint(B, true).filter((item) => !path.has(item.userData));
6053
+ const candidates = grid.queryCircle(B, this.scope).filter((item) => item.point !== B).filter((item) => !path.has(item.userData));
6040
6054
  if (candidates.length === 0) return;
6041
6055
  const BA = A.directionFrom(B);
6042
6056
  let minAngle = Infinity;
@@ -6626,7 +6640,7 @@ function initData(lines) {
6626
6640
  doorLines.push(line);
6627
6641
  continue;
6628
6642
  }
6629
- if (line.userData.isBayWindow) {
6643
+ if (line.userData.isBayWindow || line.userData.isWindow && LineGroupType.hasType(line, "bayWindow")) {
6630
6644
  bayWindowLines.push(line);
6631
6645
  continue;
6632
6646
  }
@@ -6659,11 +6673,11 @@ function getPeDoubleDoorCircles(lines, peDoubleDoorLines) {
6659
6673
  };
6660
6674
  }
6661
6675
  function buildDoubleWallGroup_(lines_, clearInternalLine = false) {
6676
+ Point.adsorb(lines_.flatMap((line) => line.points), 5e-4);
6677
+ lines_ = lines_.filter((line) => line.len > 1e-7);
6662
6678
  const {
6663
6679
  doorLines,
6664
6680
  otherLines,
6665
- // bayWindowLines,
6666
- // peDoors,
6667
6681
  peDoubleDoors
6668
6682
  } = initData(lines_);
6669
6683
  const { circlesList } = getPeDoubleDoorCircles(otherLines, peDoubleDoors);
@@ -6689,7 +6703,7 @@ function buildDoubleWallGroup_(lines_, clearInternalLine = false) {
6689
6703
  });
6690
6704
  const internalEdgesSet = new Set(internalEdges);
6691
6705
  lines_ = lines_.filter((line) => !internalEdgesSet.has(line));
6692
- return LineSegmentUndirectedGraph.breakpointMerging(lines_, mergeLineUserData).filter((line) => line.length() > 1e-6);
6706
+ return LineSegmentUndirectedGraph.breakpointMerging(lines_, mergeLineUserData).filter((line) => line.length() > 1e-9);
6693
6707
  }
6694
6708
  const buildDoubleWallGroup = Object.assign(buildDoubleWallGroup_, {
6695
6709
  setTrajectory(trajectory_) {
@@ -6792,7 +6806,7 @@ class DoubleWallHelper {
6792
6806
  }
6793
6807
  resultList.forEach((result) => {
6794
6808
  const project0 = result.project, project1 = result.project2, line0 = result.source, line1 = result.target;
6795
- if (project0.includedAngle(project1) > 135) {
6809
+ if (project0.angle(project1, { unit: "degree", range: "180" }) > 135) {
6796
6810
  project1.points = [project1.points[1], project1.points[0]];
6797
6811
  }
6798
6812
  const newLine1 = new LineSegment(project0.start.clone(), project1.start.clone());
@@ -6828,7 +6842,7 @@ class DoubleWallHelper {
6828
6842
  quadtree.clear();
6829
6843
  lines.push(...otherLines);
6830
6844
  Point.adsorb(lines.flatMap((line) => line.points), 1e-4);
6831
- return lines.filter((line) => line.length() > 1e-5);
6845
+ return lines.filter((line) => line.length() > 1e-9);
6832
6846
  }
6833
6847
  /**
6834
6848
  * 创建分组
@@ -6836,14 +6850,16 @@ class DoubleWallHelper {
6836
6850
  static buildGroup(lineSegments) {
6837
6851
  const doors = [];
6838
6852
  lineSegments = lineSegments.filter((line) => {
6839
- if (line.userData.isDoor) {
6853
+ if (line.userData.isDoor || line.userData.isBalconyRailing || line.userData.isBayWindow) {
6840
6854
  doors.push(line);
6841
6855
  return false;
6842
6856
  }
6843
6857
  return true;
6844
6858
  });
6859
+ lineSegments = buildDoubleWallGroup(lineSegments, true);
6845
6860
  lineSegments = this.complementSide(lineSegments);
6846
- lineSegments = buildDoubleWallGroup([...lineSegments], true);
6861
+ WallInsertObject.recomputed(lineSegments);
6862
+ lineSegments = buildDoubleWallGroup(lineSegments, true);
6847
6863
  return [...lineSegments, ...doors];
6848
6864
  }
6849
6865
  }
@@ -7477,7 +7493,6 @@ class ThreeVJiaJson extends Pipeline {
7477
7493
  }
7478
7494
  }
7479
7495
  function lineDataToThreeVJiaJson(lineSegments, angle = 0, updateGroup = true) {
7480
- angle = 0;
7481
7496
  lineSegments = LineSegmentUndirectedGraph.rotate(lineSegments.map((line) => line.clone()), angle, (line, center, angle2) => {
7482
7497
  WallInsertObject.forEachInsertObjectData(line, (data) => {
7483
7498
  data.forEach((item) => {
@@ -8180,7 +8195,7 @@ class DxfDrawPlugin {
8180
8195
  const line = lineSegment.clone();
8181
8196
  const doorThickness = DEFAULT_WALL_WIDTH * 0.2;
8182
8197
  const list = [];
8183
- setColor("cyan");
8198
+ setColor("yellow");
8184
8199
  if (line.length() < 1.2) {
8185
8200
  line.extendAlongDirection(-doorThickness * 0.5);
8186
8201
  const normal = lineSegment.normal();
@@ -8213,7 +8228,7 @@ class DxfDrawPlugin {
8213
8228
  cad.addDrawHandler({
8214
8229
  type: ["window"],
8215
8230
  handler: ({ group, drawLine, setColor }) => {
8216
- setColor("yellow");
8231
+ setColor("cyan");
8217
8232
  group.lines.forEach((line) => {
8218
8233
  drawLine(line.start, line.end);
8219
8234
  line.toRectangle(line?.userData?.wallWidth ?? DEFAULT_WALL_WIDTH, "butt").path2D((p1, p2) => drawLine(p1, p2));
@@ -18751,67 +18766,6 @@ function init(lines, option) {
18751
18766
  buildDoubleWallGroup.setTrajectory(option.trajectory);
18752
18767
  return lines;
18753
18768
  }
18754
- class LineQueryer {
18755
- pointVirtualGrid;
18756
- quadtree;
18757
- constructor(lines) {
18758
- this.pointVirtualGrid = createPointVirtualGrid(lines);
18759
- this.quadtree = createQuadtree(lines);
18760
- }
18761
- update(lines) {
18762
- this.clear();
18763
- this.pointVirtualGrid = createPointVirtualGrid(lines);
18764
- this.quadtree = createQuadtree(lines);
18765
- }
18766
- clear() {
18767
- this.pointVirtualGrid.clear();
18768
- this.quadtree.clear();
18769
- }
18770
- /**
18771
- * @param point
18772
- * @param radius
18773
- * @param opt
18774
- * @returns
18775
- */
18776
- queryNearestPoint(point2, opt) {
18777
- if (!point2) throw new Error("请传入查询点");
18778
- const { resultIndex = 0, radius = 0.4, condition } = opt ?? {};
18779
- const results = this.pointVirtualGrid.queryCircle(point2, radius).filter((item) => item.point !== point2).filter((item) => condition ? condition(item) : true);
18780
- results.sort((a2, b4) => a2.point.distance(point2, true) - b4.point.distance(point2, true));
18781
- if (results.length > resultIndex) return {
18782
- point: results[resultIndex].point,
18783
- line: results[resultIndex].userData
18784
- };
18785
- return null;
18786
- }
18787
- /**
18788
- * @param point
18789
- * @param radius
18790
- * @param opt
18791
- * @returns
18792
- */
18793
- queryNearestLine(point2, opt) {
18794
- if (!point2) throw new Error("请传入查询点");
18795
- const { resultIndex = 0, radius = 0.4, condition } = opt ?? {};
18796
- const results = this.quadtree.queryCircle(point2, radius).map((item) => {
18797
- const projPoint = item.line.projectPoint(point2, false);
18798
- if (projPoint && (!condition || condition(item, projPoint))) {
18799
- if (projPoint) return {
18800
- ...item,
18801
- distance: projPoint.distance(point2) ?? Infinity,
18802
- projPoint
18803
- };
18804
- }
18805
- return null;
18806
- }).filter((i) => !!i);
18807
- results.sort((a2, b4) => a2.distance - b4.distance);
18808
- if (results.length > resultIndex) return {
18809
- point: results[resultIndex].projPoint,
18810
- line: results[resultIndex].line
18811
- };
18812
- return null;
18813
- }
18814
- }
18815
18769
  function parallel(line, baseline) {
18816
18770
  const currentAngle = Math.atan2(line.end.y - line.start.y, line.end.x - line.start.x);
18817
18771
  const targetAngle = Math.atan2(baseline.end.y - baseline.start.y, baseline.end.x - baseline.start.x);
@@ -18933,6 +18887,67 @@ class AxisAlignCorr {
18933
18887
  this.addVisited(line);
18934
18888
  }
18935
18889
  }
18890
+ class LineQueryer {
18891
+ pointVirtualGrid;
18892
+ quadtree;
18893
+ constructor(lines) {
18894
+ this.pointVirtualGrid = createPointVirtualGrid(lines);
18895
+ this.quadtree = createQuadtree(lines);
18896
+ }
18897
+ update(lines) {
18898
+ this.clear();
18899
+ this.pointVirtualGrid = createPointVirtualGrid(lines);
18900
+ this.quadtree = createQuadtree(lines);
18901
+ }
18902
+ clear() {
18903
+ this.pointVirtualGrid.clear();
18904
+ this.quadtree.clear();
18905
+ }
18906
+ /**
18907
+ * @param point
18908
+ * @param radius
18909
+ * @param opt
18910
+ * @returns
18911
+ */
18912
+ queryNearestPoint(point2, opt) {
18913
+ if (!point2) throw new Error("请传入查询点");
18914
+ const { resultIndex = 0, radius = 0.4, condition } = opt ?? {};
18915
+ const results = this.pointVirtualGrid.queryCircle(point2, radius).filter((item) => item.point !== point2).filter((item) => condition ? condition(item) : true);
18916
+ results.sort((a2, b4) => a2.point.distance(point2, true) - b4.point.distance(point2, true));
18917
+ if (results.length > resultIndex) return {
18918
+ point: results[resultIndex].point,
18919
+ line: results[resultIndex].userData
18920
+ };
18921
+ return null;
18922
+ }
18923
+ /**
18924
+ * @param point
18925
+ * @param radius
18926
+ * @param opt
18927
+ * @returns
18928
+ */
18929
+ queryNearestLine(point2, opt) {
18930
+ if (!point2) throw new Error("请传入查询点");
18931
+ const { resultIndex = 0, radius = 0.4, condition } = opt ?? {};
18932
+ const results = this.quadtree.queryCircle(point2, radius).map((item) => {
18933
+ const projPoint = item.line.projectPoint(point2, false);
18934
+ if (projPoint && (!condition || condition(item, projPoint))) {
18935
+ if (projPoint) return {
18936
+ ...item,
18937
+ distance: projPoint.distance(point2) ?? Infinity,
18938
+ projPoint
18939
+ };
18940
+ }
18941
+ return null;
18942
+ }).filter((i) => !!i);
18943
+ results.sort((a2, b4) => a2.distance - b4.distance);
18944
+ if (results.length > resultIndex) return {
18945
+ point: results[resultIndex].projPoint,
18946
+ line: results[resultIndex].line
18947
+ };
18948
+ return null;
18949
+ }
18950
+ }
18936
18951
  function shortDistanceLink(lines, radius = 0.1) {
18937
18952
  const dpSet = findDiscretePoint(lines.filter((line) => !line.userData.isDoor)), pointVirtualGrid = createPointVirtualGrid(dpSet.map((v2) => v2)), appendLines = [], visited = /* @__PURE__ */ new Set();
18938
18953
  const getWeight2 = (target, point2, line) => {
@@ -19001,22 +19016,6 @@ function adsorption(lines, option) {
19001
19016
  });
19002
19017
  if (result) return modifyManager.setPoint(line, point2, result.point.clone());
19003
19018
  }
19004
- function adsorptPoint(point2, line) {
19005
- const result = lineQueryer.queryNearestPoint(point2, {
19006
- radius: threshold,
19007
- condition(node) {
19008
- const line2 = node.userData;
19009
- return line2.isPerpendicularTo(line, 15);
19010
- }
19011
- });
19012
- if (result) {
19013
- const propPoint = result.line.projectPoint(point2, false);
19014
- if (propPoint) {
19015
- modifyManager.setPoint(line, point2, propPoint);
19016
- modifyManager.setPoint(result.line, result.point, propPoint);
19017
- }
19018
- }
19019
- }
19020
19019
  for (let i = 0; i < lines.length; i++) {
19021
19020
  const line = lines[i];
19022
19021
  line.points.map((point2) => {
@@ -19025,25 +19024,13 @@ function adsorption(lines, option) {
19025
19024
  });
19026
19025
  }
19027
19026
  modifyManager.modify();
19028
- lines = lines.filter((line) => line.length() > 1e-9);
19029
- const dpls = [...findDiscretePointLine2(lines)];
19030
- lineQueryer.update(lines);
19031
- for (let i = 0; i < dpls.length; i++) {
19032
- const line = dpls[i];
19033
- line.points.map((point2) => {
19034
- let results = lineQueryer.pointVirtualGrid.queryPoint(point2, true);
19035
- if (results.length === 0 && lineQueryer.quadtree.queryCircle(point2, 1e-4).length < 2) {
19036
- adsorptPoint(point2, line);
19037
- }
19038
- });
19039
- }
19040
- modifyManager.modify();
19041
19027
  lineQueryer.clear();
19042
- Point.adsorb(lines.flatMap((line) => line.points), 1e-4, "first");
19028
+ Point.adsorb(lines.flatMap((line) => line.points), 1e-3);
19043
19029
  return lines;
19044
19030
  }
19045
19031
  function removeShortLine(lines, len = 0.01) {
19046
19032
  let defaultLines = [], doorLines = [];
19033
+ Point.adsorb(lines.flatMap((line) => line.points), 1e-3);
19047
19034
  for (let i = 0; i < lines.length; i++) {
19048
19035
  const line = lines[i];
19049
19036
  if (line.userData.isDoor) doorLines.push(line);
@@ -19091,17 +19078,14 @@ function correction(lines, targettLine, option) {
19091
19078
  newLines = buildBayWindowGroup(newLines, false);
19092
19079
  const { wallGroup = true } = option ?? {};
19093
19080
  if (wallGroup) {
19094
- newLines = DoubleWallHelper.complementSide(newLines);
19095
- WallInsertObject.recomputed(newLines);
19096
- newLines = buildDoubleWallGroup(newLines, true);
19081
+ newLines = DoubleWallHelper.buildGroup(newLines);
19097
19082
  newLines = buildBayWindowGroup(newLines, false);
19098
19083
  }
19099
- new WallInsertObject(lines).recomputed().merge();
19084
+ new WallInsertObject(newLines).recomputed().merge();
19100
19085
  newLines.push(...doorLines);
19101
- Point.adsorb(newLines.flatMap((line) => line.points), 1e-4);
19102
- lines = removeShortLine(lines, 0.05);
19103
- lines = breakpointMerging(lines);
19104
- return newLines;
19086
+ newLines = removeShortLine(newLines, 0.05);
19087
+ newLines = breakpointMerging(newLines);
19088
+ return newLines.filter((line) => line.len > 7e-9);
19105
19089
  }
19106
19090
  function axisAlignCorr(lines, option, verticalReferenceLine) {
19107
19091
  verticalReferenceLine = verticalReferenceLine ?? findVerticalReference(lines.filter((line) => !line.userData.isDoor));
@@ -19288,7 +19272,7 @@ function getNextPoint(point2, line, next, width) {
19288
19272
  function stepElimination(lineSegments, findMinWidth = 0.1, onMerge) {
19289
19273
  const grid = createPointVirtualGrid(lineSegments);
19290
19274
  function getIntersInfo(line, point2) {
19291
- const intersList = grid.queryPoint(point2, true);
19275
+ const intersList = grid.queryCircle(point2, 1e-4).filter((item) => item.point !== point2);
19292
19276
  if (intersList.length == 0) return;
19293
19277
  let firstLine = null, firstPoint = null;
19294
19278
  let count = 0;
@@ -19306,7 +19290,7 @@ function stepElimination(lineSegments, findMinWidth = 0.1, onMerge) {
19306
19290
  if (count !== 1) return;
19307
19291
  if (!firstLine || !firstPoint) return;
19308
19292
  const firstOtherPoint = firstLine.getAnotherPoint(firstPoint);
19309
- const nextResult = grid.queryPoint(firstOtherPoint, true);
19293
+ const nextResult = grid.queryCircle(firstOtherPoint, 1e-4).filter((item) => item.point !== firstOtherPoint);
19310
19294
  return {
19311
19295
  length: firstLine.length(),
19312
19296
  firstLine,
@@ -19318,17 +19302,18 @@ function stepElimination(lineSegments, findMinWidth = 0.1, onMerge) {
19318
19302
  parallel: parallel2
19319
19303
  };
19320
19304
  }
19321
- const removeLines = [];
19305
+ const removeLinesSet = /* @__PURE__ */ new Set();
19322
19306
  for (let i = 0; i < lineSegments.length; i++) {
19323
19307
  const line = lineSegments[i];
19308
+ if (removeLinesSet.has(line)) continue;
19324
19309
  const len = line.length();
19325
19310
  if (len > findMinWidth) continue;
19326
19311
  const startInfo = getIntersInfo(line, line.start);
19327
19312
  if (!startInfo) continue;
19328
19313
  const endInfo = getIntersInfo(line, line.end);
19329
19314
  if (!endInfo) continue;
19330
- const angle = startInfo.direction.angleBetween(endInfo.direction);
19331
- if (angle < 1e-5) continue;
19315
+ const angle = startInfo.direction.angle(endInfo.direction, { unit: "degree", range: "180" });
19316
+ if (angle < 177) continue;
19332
19317
  if (!startInfo.nextOnlyVertical && !endInfo.nextOnlyVertical) continue;
19333
19318
  let mainInfo = startInfo, secondaryInfo = endInfo;
19334
19319
  if (startInfo.nextOnlyVertical && endInfo.nextOnlyVertical) {
@@ -19343,13 +19328,13 @@ function stepElimination(lineSegments, findMinWidth = 0.1, onMerge) {
19343
19328
  const parallel2 = startInfo.parallel.concat(endInfo.parallel);
19344
19329
  const newPoint = getNextPoint(mainInfo.firstPoint, mainInfo.firstLine, secondaryInfo.next, secondaryInfo.length);
19345
19330
  if (!newPoint) continue;
19346
- removeLines.push(line);
19331
+ removeLinesSet.add(line);
19347
19332
  line.points.forEach((p2) => grid.remove(p2));
19348
19333
  if (parallel2.length === 0) {
19349
19334
  const oldLine = mainInfo.firstLine.clone();
19350
19335
  mainInfo.firstPoint.copy(newPoint);
19351
19336
  secondaryInfo.next.forEach((d2) => d2.point.copy(newPoint));
19352
- removeLines.push(secondaryInfo.firstLine);
19337
+ removeLinesSet.add(secondaryInfo.firstLine);
19353
19338
  secondaryInfo.firstLine.points.forEach((p2) => grid.remove(p2));
19354
19339
  mainInfo.firstLine.points.forEach((p2) => grid.update(p2));
19355
19340
  if (typeof onMerge === "function") onMerge(mainInfo.firstLine, line, secondaryInfo.firstLine, oldLine);
@@ -19363,7 +19348,6 @@ function stepElimination(lineSegments, findMinWidth = 0.1, onMerge) {
19363
19348
  startInfo.parallel.concat(endInfo.parallel).forEach((item) => grid.update(item.point));
19364
19349
  }
19365
19350
  }
19366
- const removeLinesSet = new Set(removeLines);
19367
19351
  lineSegments = lineSegments.filter((line) => !removeLinesSet.has(line));
19368
19352
  return lineSegments;
19369
19353
  }
@@ -19647,7 +19631,6 @@ class CorrectionDxf extends Dxf {
19647
19631
  onAddFromParent(parent) {
19648
19632
  parent.Dxf.addEventListener("cadChange", (e) => {
19649
19633
  e.options.trajectory && this.addPreProcessor(PRE_PROCESSOR.BoundExt);
19650
- this.addPreProcessor(PRE_PROCESSOR.DoubleWallAlignment);
19651
19634
  const lines = parent.Dxf.getLineSegments(true);
19652
19635
  this.set(lineDataToOriginalData(lines, parent.Dxf.originalZAverage), {
19653
19636
  trajectory: e.options.trajectory,
package/src/index.css CHANGED
@@ -387,10 +387,6 @@
387
387
  height: 20px;
388
388
  }
389
389
 
390
- .h-\[100\%\] {
391
- height: 100%;
392
- }
393
-
394
390
  .h-\[100vh\] {
395
391
  height: 100vh;
396
392
  }
@@ -399,6 +395,10 @@
399
395
  height: 100%;
400
396
  }
401
397
 
398
+ .h-screen {
399
+ height: 100vh;
400
+ }
401
+
402
402
  .max-h-\[300px\] {
403
403
  max-height: 300px;
404
404
  }
@@ -427,6 +427,10 @@
427
427
  width: 100%;
428
428
  }
429
429
 
430
+ .w-screen {
431
+ width: 100vw;
432
+ }
433
+
430
434
  .max-w-\[150px\] {
431
435
  max-width: 150px;
432
436
  }
@@ -1,8 +1,5 @@
1
1
  import { LineSegment } from '../../../../algorithmsStructures/LineSegment';
2
2
  import { SetDataOption, LineUserData } from '../../../type';
3
- /**
4
- * 门的障碍物清理
5
- */
6
3
  /**
7
4
  * 轴对齐垂直修正
8
5
  * @param lines 待调整线段组
@@ -169,10 +169,17 @@ export declare class LineSegment<T = Record<string, any>> {
169
169
  */
170
170
  projectPointValue(point: Point, eps?: number): number;
171
171
  /** 获取两条线段夹角
172
- * @deprecated 已废弃
172
+ * @deprecated 已废弃, 请使用 angle
173
173
  * @param line
174
174
  */
175
175
  includedAngle(line: LineSegment): number;
176
+ /** 获取两条线段夹角
177
+ * @param line
178
+ */
179
+ angle(line: LineSegment, opt?: {
180
+ unit?: "radian" | "degree" | "cos";
181
+ range?: "180" | "360";
182
+ }): number;
176
183
  /**
177
184
  * 判断两条线段,是否在同一直线上:
178
185
  * - 返回 -1:不在同一直线(不共线)
@@ -15,7 +15,9 @@ export interface MiniCirclesOption {
15
15
  export declare class MiniCircles {
16
16
  debug: {
17
17
  angle: boolean;
18
+ edges: boolean;
18
19
  };
20
+ scope: number;
19
21
  /** 通过并查集,查找为环的一部分边
20
22
  * @description
21
23
  * @param lines
@@ -38,7 +40,7 @@ export declare class MiniCircles {
38
40
  findSameSidePath(opt: {
39
41
  A: Point;
40
42
  B: Point;
41
- exitPoint: Point;
43
+ exitPoint?: Point;
42
44
  grid: PointVirtualGrid<LineSegment> | LineSegment[];
43
45
  path?: Set<LineSegment>;
44
46
  }): LineSegment<Record<string, any>>[] | undefined;
@@ -22,7 +22,7 @@ export declare class Point<T = Record<string, any>> {
22
22
  * @param point
23
23
  * @returns
24
24
  */
25
- equal(point: Point): boolean;
25
+ equal(point: Point, eps?: number): boolean;
26
26
  /**
27
27
  *
28
28
  * @param arr
@@ -81,7 +81,7 @@ export declare class PointVirtualGrid<T = Record<string, any>> {
81
81
  * 查找相同点
82
82
  * @param point
83
83
  */
84
- queryPoint(point: Point, excludeOneself?: boolean): PvgList<T>;
84
+ queryPoint(point: Point, excludeOneself?: boolean, eps?: number): PvgList<T>;
85
85
  /** 获取多边形内的点
86
86
  * @param polygon
87
87
  */
@@ -18,6 +18,10 @@ export declare class UndirectedGraph {
18
18
  * @param callbackFun
19
19
  */
20
20
  forEach(callbackFun: (node: number, neighbors: Set<number>) => void): void;
21
+ /** 遍历边
22
+ * @param callbackFun
23
+ */
24
+ forEachEdge(callbackFun: (u: number, v: number) => void): void;
21
25
  }
22
26
  /**
23
27
  * 线段无向图