build-dxf 0.1.88 → 0.1.89

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.88",
3
+ "version": "0.1.89",
4
4
  "description": "线段构建双线墙壁的dxf版本",
5
5
  "main": "./src/index.js",
6
6
  "types": "./src/index.d.ts",
@@ -1,4 +1,4 @@
1
- import { IRegion, ISpace } from './type';
1
+ import { IModelItem, IRegion, ISpace } from './type';
2
2
  export declare function getSpaceListApi(): Promise<ISpace[]>;
3
3
  /** 获取区域列表api
4
4
  * @param idSpace
@@ -20,3 +20,4 @@ export declare function updateThreeJiaJsonApi(body: {
20
20
  models: string;
21
21
  dxf: string;
22
22
  }): Promise<boolean>;
23
+ export declare function getModelsApi(idRegion: string): Promise<IModelItem[]>;
package/src/build.js CHANGED
@@ -266,6 +266,13 @@ class PointVirtualGrid {
266
266
  }
267
267
  return this;
268
268
  }
269
+ /** 移除点
270
+ * @param point
271
+ */
272
+ removes(point2) {
273
+ point2.map(this.remove.bind(this));
274
+ return this;
275
+ }
269
276
  update(point2) {
270
277
  const { target, set: set2 } = point2.currentData[this.id];
271
278
  if (!target) return false;
@@ -2049,11 +2056,11 @@ class LineSegment {
2049
2056
  static mergeLines(...lines) {
2050
2057
  if (lines.length === 1) return lines[0];
2051
2058
  const list = lines.slice(0).sort((a2, b4) => b4.length() - a2.length());
2059
+ const principal = list[0].direction().normalize();
2052
2060
  const endpoints = [];
2053
2061
  lines.forEach((line) => {
2054
2062
  endpoints.push(line.start.clone(), line.end.clone());
2055
2063
  });
2056
- const principal = list[0].direction().normalize();
2057
2064
  let minProj = Infinity, maxProj = -Infinity;
2058
2065
  let sumX = 0, sumY = 0;
2059
2066
  endpoints.forEach((pt2) => {
@@ -2071,6 +2078,41 @@ class LineSegment {
2071
2078
  lines.forEach((line) => line.currentData.fittedLine = fittedLine);
2072
2079
  return fittedLine;
2073
2080
  }
2081
+ /** 传入的线段全部投影为一条线段,默认以最长线线段为位置和方向
2082
+ * @param lines 请确保共线
2083
+ * @returns
2084
+ */
2085
+ static mergeCollinearSegments(lines) {
2086
+ if (lines.length === 1) return lines[0];
2087
+ let mainLine = lines[0];
2088
+ for (const l of lines) if (l.length() > mainLine.length()) mainLine = l;
2089
+ let maxPValue = -Infinity, minPValue = Infinity;
2090
+ let maxPoint = null;
2091
+ let minPoint = null;
2092
+ for (let i = 0; i < lines.length; i++) {
2093
+ const line = lines[i];
2094
+ for (let j = 0; j < line.points.length; j++) {
2095
+ const p2 = line.points[j];
2096
+ const pValue = mainLine.projectPointValue(p2);
2097
+ if (pValue > maxPValue) {
2098
+ maxPValue = pValue;
2099
+ maxPoint = p2;
2100
+ }
2101
+ if (pValue < minPValue) {
2102
+ minPValue = pValue;
2103
+ minPoint = p2;
2104
+ }
2105
+ }
2106
+ }
2107
+ if (!minPoint || !maxPoint) {
2108
+ throw new Error("mergeCollinearSegments: 无效输入");
2109
+ }
2110
+ const newStart = minPoint.clone();
2111
+ const newEnd = maxPoint.clone();
2112
+ const fittedLine = new LineSegment(newStart, newEnd);
2113
+ lines.forEach((line) => line.currentData.fittedLine = fittedLine);
2114
+ return fittedLine;
2115
+ }
2074
2116
  /** 合并满足平行的线段
2075
2117
  * @param selectLines
2076
2118
  */
@@ -2098,7 +2140,7 @@ class LineSegment {
2098
2140
  * @param callBack
2099
2141
  * @returns
2100
2142
  */
2101
- static mergeCollinearSegments(lines, callBack, removeLines = /* @__PURE__ */ new Set(), newLines = []) {
2143
+ static mergeCollinearSegmentsAll(lines, callBack, removeLines = /* @__PURE__ */ new Set(), newLines = []) {
2102
2144
  const map = /* @__PURE__ */ new Map();
2103
2145
  lines.forEach((line) => line.points.forEach((p2) => {
2104
2146
  const id = `${p2.X.toFixed(6)}_${p2.Y.toFixed(6)}`;
@@ -2260,6 +2302,20 @@ class LineSegment {
2260
2302
  }
2261
2303
  return line;
2262
2304
  }
2305
+ /** 通过线段提取所有点
2306
+ * @param lines
2307
+ * @returns
2308
+ */
2309
+ static flatPoints(lines) {
2310
+ if (lines instanceof LineSegment) return [...lines.points];
2311
+ const points = new Array(lines.length * 2);
2312
+ for (let i = 0; i < lines.length; i++) {
2313
+ const line = lines[i];
2314
+ points[i * 2] = line.start;
2315
+ points[i * 2 + 1] = line.end;
2316
+ }
2317
+ return points;
2318
+ }
2263
2319
  /** 创建线段修改管理器
2264
2320
  * @returns
2265
2321
  */
@@ -2339,7 +2395,7 @@ class Point {
2339
2395
  * @param point
2340
2396
  * @returns
2341
2397
  */
2342
- equal(point2, eps = 1e-9) {
2398
+ equal(point2) {
2343
2399
  return Math.abs(point2.x - this.x) < 1e-9 && Math.abs(point2.y - this.y) < 1e-9;
2344
2400
  }
2345
2401
  /**
@@ -2648,7 +2704,7 @@ class Point {
2648
2704
  * @param tolerance
2649
2705
  * @returns
2650
2706
  */
2651
- static adsorb(points, tolerance = 1e-3, mode = "average") {
2707
+ static adsorb(points, tolerance = 1e-4, mode = "average") {
2652
2708
  const grid = new PointVirtualGrid();
2653
2709
  points.forEach((p2) => grid.insert(p2));
2654
2710
  const visited = /* @__PURE__ */ new Set();
@@ -2707,6 +2763,30 @@ class Point {
2707
2763
  });
2708
2764
  }
2709
2765
  }
2766
+ class PointUtils {
2767
+ /** 值网格化
2768
+ * @param points
2769
+ * @param tolerance
2770
+ */
2771
+ static quantize(points, tolerance = 2e-3) {
2772
+ const gridSize = tolerance;
2773
+ for (const p2 of points) {
2774
+ p2.x = Math.round(p2.x / gridSize) * gridSize;
2775
+ p2.y = Math.round(p2.y / gridSize) * gridSize;
2776
+ }
2777
+ return points;
2778
+ }
2779
+ /**保留小数位数
2780
+ * @param points
2781
+ */
2782
+ static round(points, scale2 = 1e4) {
2783
+ for (const p2 of points) {
2784
+ p2.x = Math.round(p2.x * scale2) / scale2;
2785
+ p2.y = Math.round(p2.y * scale2) / scale2;
2786
+ }
2787
+ return points;
2788
+ }
2789
+ }
2710
2790
  class Box2 {
2711
2791
  minX = 0;
2712
2792
  maxX = 0;
@@ -3632,7 +3712,7 @@ class LineSegmentUndirectedGraph extends UndirectedGraph {
3632
3712
  });
3633
3713
  unionFindSet.getAllSets().forEach((list) => {
3634
3714
  if (list.length <= 1) return;
3635
- const lines = list.map((i) => lineIndexGenerator.getLine(i)), newLine = LineSegment.mergeLines(...lines);
3715
+ const lines = list.map((i) => lineIndexGenerator.getLine(i)), newLine = LineSegment.mergeCollinearSegments(lines);
3636
3716
  callBack && callBack(newLine, lines);
3637
3717
  lines.forEach((line) => removeLines.add(line));
3638
3718
  newLines.push(newLine);
@@ -3648,7 +3728,7 @@ class LineSegmentUndirectedGraph extends UndirectedGraph {
3648
3728
  * @returns
3649
3729
  */
3650
3730
  static breakpointMerging(lines, callBack, removeLines = /* @__PURE__ */ new Set(), newLines = []) {
3651
- Point.adsorb(lines.flatMap((line) => line.points), 1e-4);
3731
+ Point.adsorb(LineSegment.flatPoints(lines), 1e-4);
3652
3732
  const lud = new LineSegmentUndirectedGraph(lines);
3653
3733
  lud.breakpointMerging(callBack, removeLines, newLines);
3654
3734
  lines = lud.getLineAll();
@@ -5952,6 +6032,14 @@ function lineSegmentClipping(lines, minLen = 1e-9, dedup = true) {
5952
6032
  newLines2[i].userData.isBayWindow = false;
5953
6033
  }
5954
6034
  }
6035
+ if (line.userData.isBalconyRailing) {
6036
+ const len = line.length();
6037
+ newLines2.forEach((line2) => {
6038
+ if (line2.length() / len < 0.2) {
6039
+ delete line2.userData.isBalconyRailing;
6040
+ }
6041
+ });
6042
+ }
5955
6043
  return newLines2;
5956
6044
  }
5957
6045
  return line;
@@ -5973,7 +6061,7 @@ class MiniCircles {
5973
6061
  angle: false,
5974
6062
  edges: false
5975
6063
  };
5976
- scope = 1e-3;
6064
+ scope = 1e-4;
5977
6065
  /** 通过并查集,查找为环的一部分边
5978
6066
  * @description
5979
6067
  * @param lines
@@ -6551,7 +6639,8 @@ class MaxiCircles extends MiniCircles {
6551
6639
  const linesGroup = LineSegment.groupByPath(lines), circles = [], internalEdges = [];
6552
6640
  linesGroup.forEach((lines2, _) => {
6553
6641
  try {
6554
- const findCircles = findMinCirclesFilter(this.miniCircle(lines2).circles);
6642
+ const miniCircles2 = this.miniCircle(lines2).circles;
6643
+ const findCircles = findMinCirclesFilter(miniCircles2);
6555
6644
  const result = this.mergeCircles(findCircles);
6556
6645
  circles.push(...result.circles);
6557
6646
  internalEdges.push(...result.internalEdges);
@@ -6703,7 +6792,7 @@ function buildDoubleWallGroup_(lines_, clearInternalLine = false) {
6703
6792
  });
6704
6793
  const internalEdgesSet = new Set(internalEdges);
6705
6794
  lines_ = lines_.filter((line) => !internalEdgesSet.has(line));
6706
- return LineSegmentUndirectedGraph.breakpointMerging(lines_, mergeLineUserData).filter((line) => line.length() > 1e-9);
6795
+ return lines_;
6707
6796
  }
6708
6797
  const buildDoubleWallGroup = Object.assign(buildDoubleWallGroup_, {
6709
6798
  setTrajectory(trajectory_) {
@@ -6756,7 +6845,7 @@ class DoubleWallHelper {
6756
6845
  * @returns
6757
6846
  */
6758
6847
  static findDoubleLine(lines, wallWidth = 0.4) {
6759
- let walls = lines.filter((line) => !line.userData.isDoor && !LineGroupType.hasType(line, "doubleWall")), visited = /* @__PURE__ */ new Set(), resultList = [];
6848
+ let walls = lines.filter((line) => !line.userData.isDoor), visited = /* @__PURE__ */ new Set(), resultList = [];
6760
6849
  walls = walls.filter((line) => !line.userData.isWindowWall);
6761
6850
  let quadtree = new Quadtree(Box2.fromByLineSegment(...walls));
6762
6851
  walls.forEach((line, index2) => quadtree.insert({ line, userData: index2 }));
@@ -6773,6 +6862,12 @@ class DoubleWallHelper {
6773
6862
  }
6774
6863
  });
6775
6864
  });
6865
+ resultList.forEach((result) => {
6866
+ const project0 = result.project, project1 = result.project2;
6867
+ if (project0.angle(project1, { unit: "degree", range: "180" }) > 135) {
6868
+ project1.points = [project1.points[1], project1.points[0]];
6869
+ }
6870
+ });
6776
6871
  return {
6777
6872
  resultList,
6778
6873
  walls,
@@ -6784,7 +6879,7 @@ class DoubleWallHelper {
6784
6879
  * @param wallWidth
6785
6880
  * @returns
6786
6881
  */
6787
- static complementSide(lines, wallWidth = 0.4) {
6882
+ static complementSide(lines, obstacleAegment = [], wallWidth = 0.4) {
6788
6883
  const otherLines = [];
6789
6884
  lines = lines.filter((line) => {
6790
6885
  if (line.userData.isBayWindow || line.userData.isBalconyRailing || LineGroupType.hasType(line, "bayWindow") && line.userData.isWindow) {
@@ -6806,9 +6901,6 @@ class DoubleWallHelper {
6806
6901
  }
6807
6902
  resultList.forEach((result) => {
6808
6903
  const project0 = result.project, project1 = result.project2, line0 = result.source, line1 = result.target;
6809
- if (project0.angle(project1, { unit: "degree", range: "180" }) > 135) {
6810
- project1.points = [project1.points[1], project1.points[0]];
6811
- }
6812
6904
  const newLine1 = new LineSegment(project0.start.clone(), project1.start.clone());
6813
6905
  const newLine2 = new LineSegment(project0.end.clone(), project1.end.clone());
6814
6906
  newLine1.userData.height = line0.userData.height;
@@ -6823,11 +6915,10 @@ class DoubleWallHelper {
6823
6915
  });
6824
6916
  lines = lines.filter((line) => !removeLines.has(line));
6825
6917
  quadtree.clear();
6826
- quadtree = new Quadtree(Box2.fromByLineSegment(...lines));
6827
- lines.forEach((line) => line.userData.isDoor || quadtree.insert(line));
6918
+ quadtree = createQuadtree([...lines, ...otherLines, ...obstacleAegment]);
6828
6919
  appendLines = lineSegmentClipping(appendLines, 1e-9);
6829
6920
  appendLines.flatMap((line) => {
6830
- const queryLines = quadtree.queryLineSegment(line).filter((item) => item.line.isParallelTo(line)).map((item) => item.line);
6921
+ const queryLines = quadtree.queryRect(line.toRectangle(1e-3, "butt")).filter((item) => item.line.isParallelTo(line)).map((item) => item.line);
6831
6922
  if (queryLines.length) {
6832
6923
  const newLines = LineSegment.clippingByLines(line, queryLines);
6833
6924
  if (newLines) return newLines.forEach((line2) => {
@@ -6848,19 +6939,22 @@ class DoubleWallHelper {
6848
6939
  * 创建分组
6849
6940
  */
6850
6941
  static buildGroup(lineSegments) {
6851
- const doors = [];
6942
+ const otherLines = [];
6852
6943
  lineSegments = lineSegments.filter((line) => {
6853
- if (line.userData.isDoor || line.userData.isBalconyRailing || line.userData.isBayWindow) {
6854
- doors.push(line);
6944
+ if (line.userData.isDoor || line.userData.isBalconyRailing || line.userData.isWindowWall || line.userData.isBayWindow) {
6945
+ otherLines.push(line);
6855
6946
  return false;
6856
6947
  }
6857
6948
  return true;
6858
6949
  });
6859
6950
  lineSegments = buildDoubleWallGroup(lineSegments, true);
6860
- lineSegments = this.complementSide(lineSegments);
6951
+ lineSegments = this.complementSide(lineSegments, otherLines);
6861
6952
  WallInsertObject.recomputed(lineSegments);
6862
6953
  lineSegments = buildDoubleWallGroup(lineSegments, true);
6863
- return [...lineSegments, ...doors];
6954
+ PointUtils.round(
6955
+ PointUtils.quantize(LineSegment.flatPoints(lineSegments), 1e-4)
6956
+ );
6957
+ return [...lineSegments, ...otherLines];
6864
6958
  }
6865
6959
  }
6866
6960
  class WallGroupManager {
@@ -7659,8 +7753,8 @@ function findVerticalReference(lineSegments) {
7659
7753
  if (!lineMap.has(angle)) lineMap.set(angle, []);
7660
7754
  lineMap.get(angle)?.push(lines[index2]);
7661
7755
  });
7662
- const line = [...lineMap.values()].sort((a2, b4) => b4.length - a2.length)[0].sort((a2, b4) => b4.length() - a2.length())[0];
7663
- return line;
7756
+ const line = [...lineMap.values()].sort((a2, b4) => b4.length - a2.length)[0]?.sort((a2, b4) => b4.length() - a2.length())[0];
7757
+ return line ?? new LineSegment();
7664
7758
  }
7665
7759
  class Group {
7666
7760
  type = "";
@@ -8239,7 +8333,7 @@ class DxfDrawPlugin {
8239
8333
  type: ["bayWindow"],
8240
8334
  handler({ drawDottedLine, setColor, group }) {
8241
8335
  group.lines.forEach((line) => {
8242
- setColor("yellow");
8336
+ setColor("cyan");
8243
8337
  line = line.clone().extendAlongDirection(-DEFAULT_WALL_WIDTH * 0.5);
8244
8338
  drawDottedLine(line.start, line.end);
8245
8339
  });
@@ -8427,7 +8521,7 @@ class BoundExt {
8427
8521
  lines = lineSegmentClipping(lines, 1e-9);
8428
8522
  const doors = lines.filter((line) => line.userData.isDoor);
8429
8523
  const walls = lines.filter((line) => !line.userData.isDoor);
8430
- lines = [...LineSegment.mergeCollinearSegments(walls, mergeLineUserData), ...doors];
8524
+ lines = [...LineSegment.mergeCollinearSegmentsAll(walls, mergeLineUserData), ...doors];
8431
8525
  WallInsertObject.recomputed(lines);
8432
8526
  lines = lines.filter((line) => line.length() > 1e-4).filter((line) => line.userData.isDoor ? line.length() > 0.25 : true);
8433
8527
  findCallBack && findCallBack([...exteriorLines, ...appendLines], trajectoryPoints);
@@ -18814,6 +18908,8 @@ class AxisAlignCorr {
18814
18908
  if (this.visited.has(line)) continue;
18815
18909
  this.correction(line);
18816
18910
  }
18911
+ const quadtree = createQuadtree(this.lines);
18912
+ this.newLines = this.newLines.filter((line) => quadtree.queryCircle(line.center, 1e-4).length === 0);
18817
18913
  return [
18818
18914
  ...this.lines,
18819
18915
  ...this.newLines
@@ -18948,6 +19044,163 @@ class LineQueryer {
18948
19044
  return null;
18949
19045
  }
18950
19046
  }
19047
+ function removeDangline(lines, len = 0.01, consecutive = false) {
19048
+ const grid = createPointVirtualGrid(lines);
19049
+ let defaultLines = [];
19050
+ const doorLines = [];
19051
+ const removeLineSet = /* @__PURE__ */ new Set();
19052
+ lines.forEach((line) => {
19053
+ if (line.userData.isDoor) doorLines.push(line);
19054
+ else defaultLines.push(line);
19055
+ });
19056
+ function find(lines2) {
19057
+ removeLineSet.clear();
19058
+ const shortLine = lines2.filter((line) => line.length() <= len);
19059
+ for (let i = 0; i < shortLine.length; i++) {
19060
+ const line = shortLine[i];
19061
+ const is2 = line.points.every((p2) => grid.queryCircle(p2, 1e-4).length > 1);
19062
+ if (!is2) removeLineSet.add(line);
19063
+ }
19064
+ return removeLineSet;
19065
+ }
19066
+ while (find(defaultLines).size != 0 && consecutive) {
19067
+ defaultLines = defaultLines.filter((line) => !removeLineSet.has(line));
19068
+ removeLineSet.forEach((line) => {
19069
+ grid.removes(line.points);
19070
+ });
19071
+ }
19072
+ defaultLines = LineSegmentUndirectedGraph.breakpointMerging(defaultLines, (newLine, lines2) => {
19073
+ lines2 = lines2.filter((line) => line.length() > 0);
19074
+ mergeLineUserData(newLine, lines2);
19075
+ newLine.userData.isBayWindow = lines2.some((line) => line.userData.isBayWindow);
19076
+ });
19077
+ WallInsertObject.recomputed(defaultLines);
19078
+ return [...defaultLines, ...doorLines];
19079
+ }
19080
+ function getNextPoint(point2, line, next, width) {
19081
+ if (next.length === 0) {
19082
+ const direct = point2.directionFrom(line.getAnotherPoint(point2));
19083
+ return point2.clone().add(direct.multiplyScalar(width));
19084
+ }
19085
+ const p2 = next[0].userData.projectPoint(point2, false);
19086
+ if (!p2) return false;
19087
+ return p2;
19088
+ }
19089
+ function stepElimination(lineSegments, findMinWidth = 0.1, onMerge) {
19090
+ const grid = createPointVirtualGrid(lineSegments);
19091
+ function getIntersInfo(line, point2) {
19092
+ const intersList = grid.queryCircle(point2, 1e-4).filter((item) => item.point !== point2);
19093
+ if (intersList.length == 0) return;
19094
+ let firstLine = null, firstPoint = null;
19095
+ let count = 0;
19096
+ let parallel2 = new PvgList();
19097
+ for (let i = 0; i < intersList.length; i++) {
19098
+ const res = intersList[i];
19099
+ if (line.isPerpendicularTo(res.userData, 5)) {
19100
+ count++;
19101
+ firstLine = res.userData;
19102
+ firstPoint = res.point;
19103
+ } else {
19104
+ parallel2.push(res);
19105
+ }
19106
+ }
19107
+ if (count !== 1) return;
19108
+ if (!firstLine || !firstPoint) return;
19109
+ const firstOtherPoint = firstLine.getAnotherPoint(firstPoint);
19110
+ const nextResult = grid.queryCircle(firstOtherPoint, 1e-4).filter((item) => item.point !== firstOtherPoint);
19111
+ return {
19112
+ length: firstLine.length(),
19113
+ firstLine,
19114
+ firstPoint,
19115
+ firstOtherPoint,
19116
+ direction: firstOtherPoint.directionFrom(firstPoint),
19117
+ nextOnlyVertical: nextResult.every((d2) => d2.userData.isPerpendicularTo(firstLine)),
19118
+ next: nextResult,
19119
+ parallel: parallel2
19120
+ };
19121
+ }
19122
+ const removeLinesSet = /* @__PURE__ */ new Set();
19123
+ for (let i = 0; i < lineSegments.length; i++) {
19124
+ const line = lineSegments[i];
19125
+ if (removeLinesSet.has(line)) continue;
19126
+ const len = line.length();
19127
+ if (len > findMinWidth) continue;
19128
+ const startInfo = getIntersInfo(line, line.start);
19129
+ if (!startInfo) continue;
19130
+ const endInfo = getIntersInfo(line, line.end);
19131
+ if (!endInfo) continue;
19132
+ const angle = startInfo.direction.angle(endInfo.direction, { unit: "degree", range: "180" });
19133
+ if (angle < 177) continue;
19134
+ if (!startInfo.nextOnlyVertical && !endInfo.nextOnlyVertical) continue;
19135
+ let mainInfo = startInfo, secondaryInfo = endInfo;
19136
+ if (startInfo.nextOnlyVertical && endInfo.nextOnlyVertical) {
19137
+ if (startInfo.length < endInfo.length) {
19138
+ mainInfo = endInfo;
19139
+ secondaryInfo = startInfo;
19140
+ }
19141
+ } else if (startInfo.nextOnlyVertical) {
19142
+ mainInfo = endInfo;
19143
+ secondaryInfo = startInfo;
19144
+ }
19145
+ const parallel2 = startInfo.parallel.concat(endInfo.parallel);
19146
+ const newPoint = getNextPoint(mainInfo.firstPoint, mainInfo.firstLine, secondaryInfo.next, secondaryInfo.length);
19147
+ if (!newPoint) continue;
19148
+ removeLinesSet.add(line);
19149
+ line.points.forEach((p2) => grid.remove(p2));
19150
+ if (parallel2.length === 0) {
19151
+ const oldLine = mainInfo.firstLine.clone();
19152
+ mainInfo.firstPoint.copy(newPoint);
19153
+ secondaryInfo.next.forEach((d2) => d2.point.copy(newPoint));
19154
+ removeLinesSet.add(secondaryInfo.firstLine);
19155
+ secondaryInfo.firstLine.points.forEach((p2) => grid.remove(p2));
19156
+ mainInfo.firstLine.points.forEach((p2) => grid.update(p2));
19157
+ if (typeof onMerge === "function") onMerge(mainInfo.firstLine, line, secondaryInfo.firstLine, oldLine);
19158
+ } else {
19159
+ secondaryInfo.firstPoint.copy(mainInfo.firstPoint);
19160
+ secondaryInfo.firstOtherPoint.copy(newPoint);
19161
+ secondaryInfo.next.forEach((d2) => d2.point.copy(newPoint));
19162
+ startInfo.parallel.concat(endInfo.parallel).forEach((item) => item.point.copy(mainInfo.firstPoint));
19163
+ secondaryInfo.firstLine.points.forEach((p2) => grid.update(p2));
19164
+ secondaryInfo.next.forEach((d2) => grid.update(d2.point));
19165
+ startInfo.parallel.concat(endInfo.parallel).forEach((item) => grid.update(item.point));
19166
+ }
19167
+ }
19168
+ lineSegments = lineSegments.filter((line) => !removeLinesSet.has(line));
19169
+ return lineSegments;
19170
+ }
19171
+ function repetitiveTask(count, callfun) {
19172
+ for (let i = 0; i < count; i++) {
19173
+ callfun(i);
19174
+ }
19175
+ }
19176
+ function stepEliminationMerge(target, _, source, oldLine) {
19177
+ if (source.userData.isDoor) WallInsertObject.addInsertObject(target, {
19178
+ p: source.center.toJson(),
19179
+ width: source.length(),
19180
+ full: false,
19181
+ type: "door",
19182
+ height: source.userData.drawDoorData.height,
19183
+ groundClearance: source.userData.drawDoorData.groundClearance
19184
+ });
19185
+ if (target.userData.isDoor) {
19186
+ delete target.userData.isDoor;
19187
+ WallInsertObject.addInsertObject(target, {
19188
+ p: oldLine.center.toJson(),
19189
+ width: oldLine.length(),
19190
+ full: false,
19191
+ type: "door",
19192
+ height: target.userData.drawDoorData?.height,
19193
+ groundClearance: target.userData.drawDoorData?.groundClearance ?? 0
19194
+ });
19195
+ }
19196
+ WallInsertObject.copyInsertObject(target, source);
19197
+ WallInsertObject.recomputed([target]);
19198
+ }
19199
+ function linesSmoothing(lines, _) {
19200
+ repetitiveTask(2, () => lines = stepElimination(lines, 0.15, stepEliminationMerge));
19201
+ WallInsertObject.recomputed(lines);
19202
+ return lines;
19203
+ }
18951
19204
  function shortDistanceLink(lines, radius = 0.1) {
18952
19205
  const dpSet = findDiscretePoint(lines.filter((line) => !line.userData.isDoor)), pointVirtualGrid = createPointVirtualGrid(dpSet.map((v2) => v2)), appendLines = [], visited = /* @__PURE__ */ new Set();
18953
19206
  const getWeight2 = (target, point2, line) => {
@@ -19025,34 +19278,9 @@ function adsorption(lines, option) {
19025
19278
  }
19026
19279
  modifyManager.modify();
19027
19280
  lineQueryer.clear();
19028
- Point.adsorb(lines.flatMap((line) => line.points), 1e-3);
19281
+ Point.adsorb(lines.flatMap((line) => line.points), 1e-4);
19029
19282
  return lines;
19030
19283
  }
19031
- function removeShortLine(lines, len = 0.01) {
19032
- let defaultLines = [], doorLines = [];
19033
- Point.adsorb(lines.flatMap((line) => line.points), 1e-3);
19034
- for (let i = 0; i < lines.length; i++) {
19035
- const line = lines[i];
19036
- if (line.userData.isDoor) doorLines.push(line);
19037
- else defaultLines.push(line);
19038
- }
19039
- const lineSet = findDiscretePointLine2(lines);
19040
- const grid = createPointVirtualGrid([...lineSet]);
19041
- for (let i = 0; i < doorLines.length; i++) {
19042
- const doorLine = doorLines[i];
19043
- doorLine.points.forEach((p2) => {
19044
- grid.queryPoint(p2, true).forEach((item) => lineSet.delete(item.userData));
19045
- });
19046
- }
19047
- defaultLines = defaultLines.filter((line) => !lineSet.has(line) || line.length() > len);
19048
- defaultLines = LineSegmentUndirectedGraph.breakpointMerging(defaultLines, (newLine, lines2) => {
19049
- lines2 = lines2.filter((line) => line.length() > 0);
19050
- mergeLineUserData(newLine, lines2);
19051
- newLine.userData.isBayWindow = lines2.some((line) => line.userData.isBayWindow);
19052
- });
19053
- WallInsertObject.recomputed(defaultLines);
19054
- return [...defaultLines, ...doorLines];
19055
- }
19056
19284
  function breakpointMerging(lines) {
19057
19285
  let defaultLines = [], doorLines = [];
19058
19286
  for (let i = 0; i < lines.length; i++) {
@@ -19072,25 +19300,32 @@ function correction(lines, targettLine, option) {
19072
19300
  lines = AxisAlignCorr.start(lines, targettLine);
19073
19301
  lines = adsorption(lines, option);
19074
19302
  lines = lineSegmentClipping(lines, 1e-9);
19075
- lines = removeShortLine(lines, 0.15);
19303
+ lines = removeDangline(lines, 0.15, true);
19304
+ lines = linesSmoothing(lines);
19076
19305
  let newLines = lines.filter((line) => !line.userData.isDoor);
19077
19306
  let doorLines = lines.filter((line) => line.userData.isDoor);
19078
19307
  newLines = buildBayWindowGroup(newLines, false);
19079
19308
  const { wallGroup = true } = option ?? {};
19080
19309
  if (wallGroup) {
19081
19310
  newLines = DoubleWallHelper.buildGroup(newLines);
19311
+ newLines = breakpointMerging(newLines);
19082
19312
  newLines = buildBayWindowGroup(newLines, false);
19083
19313
  }
19084
19314
  new WallInsertObject(newLines).recomputed().merge();
19085
19315
  newLines.push(...doorLines);
19086
- newLines = removeShortLine(newLines, 0.05);
19087
- newLines = breakpointMerging(newLines);
19088
- return newLines.filter((line) => line.len > 7e-9);
19316
+ newLines = removeDangline(newLines, 0.15, true);
19317
+ return newLines.filter((line) => line.len > 1e-9);
19089
19318
  }
19090
19319
  function axisAlignCorr(lines, option, verticalReferenceLine) {
19091
19320
  verticalReferenceLine = verticalReferenceLine ?? findVerticalReference(lines.filter((line) => !line.userData.isDoor));
19092
19321
  if (verticalReferenceLine) {
19093
19322
  const t2 = performance.now();
19323
+ lines.forEach((line) => {
19324
+ const id = LineGroupType.getIdByType(line, "bayWindow");
19325
+ if (id && line.userData.isWindow) {
19326
+ line.userData.isWindowWall = true;
19327
+ }
19328
+ });
19094
19329
  const lineSegments = correction(lines, verticalReferenceLine, option);
19095
19330
  console.log("垂直纠正总消耗时间:", (performance.now() - t2).toFixed(2), "ms", "处理线段数量:", lines.length);
19096
19331
  return lineSegments;
@@ -19164,11 +19399,11 @@ function doubleWallAlignment(lines) {
19164
19399
  return [newLines, doubleWall].flat(10);
19165
19400
  });
19166
19401
  lines = [singleWall, newDoubleWalls].flat(10);
19167
- lines = LineSegmentUndirectedGraph.breakpointMerging(lines, mergeLineUserData);
19168
19402
  lines = lineSegmentClipping(lines, 1e-9);
19169
19403
  lines = buildDoubleWallGroup(lines);
19170
19404
  lines.push(...doorLines);
19171
19405
  WallInsertObject.recomputed(lines);
19406
+ lines = LineSegmentUndirectedGraph.breakpointMerging(lines, mergeLineUserData);
19172
19407
  return lines;
19173
19408
  }
19174
19409
  const point = new Point();
@@ -19260,130 +19495,6 @@ function removeShortDoubleWall(lineSegments) {
19260
19495
  const doubleWalls = LineGroupType.getGroupsByType(lineSegments, "doubleWall"), freePointLines = [...findDiscretePointLine2(lineSegments)].filter((line) => line.length() < 0.3), grid = createPointVirtualGrid(doubleWalls.flat(4)), lines = freePointLines.filter((line) => grid.queryPoint(line.start).length > 0 || grid.queryPoint(line.end).length > 0), removeSet = new Set(lines);
19261
19496
  return lineSegments.filter((line) => !removeSet.has(line));
19262
19497
  }
19263
- function getNextPoint(point2, line, next, width) {
19264
- if (next.length === 0) {
19265
- const direct = point2.directionFrom(line.getAnotherPoint(point2));
19266
- return point2.clone().add(direct.multiplyScalar(width));
19267
- }
19268
- const p2 = next[0].userData.projectPoint(point2, false);
19269
- if (!p2) return false;
19270
- return p2;
19271
- }
19272
- function stepElimination(lineSegments, findMinWidth = 0.1, onMerge) {
19273
- const grid = createPointVirtualGrid(lineSegments);
19274
- function getIntersInfo(line, point2) {
19275
- const intersList = grid.queryCircle(point2, 1e-4).filter((item) => item.point !== point2);
19276
- if (intersList.length == 0) return;
19277
- let firstLine = null, firstPoint = null;
19278
- let count = 0;
19279
- let parallel2 = new PvgList();
19280
- for (let i = 0; i < intersList.length; i++) {
19281
- const res = intersList[i];
19282
- if (line.isPerpendicularTo(res.userData, 5)) {
19283
- count++;
19284
- firstLine = res.userData;
19285
- firstPoint = res.point;
19286
- } else {
19287
- parallel2.push(res);
19288
- }
19289
- }
19290
- if (count !== 1) return;
19291
- if (!firstLine || !firstPoint) return;
19292
- const firstOtherPoint = firstLine.getAnotherPoint(firstPoint);
19293
- const nextResult = grid.queryCircle(firstOtherPoint, 1e-4).filter((item) => item.point !== firstOtherPoint);
19294
- return {
19295
- length: firstLine.length(),
19296
- firstLine,
19297
- firstPoint,
19298
- firstOtherPoint,
19299
- direction: firstOtherPoint.directionFrom(firstPoint),
19300
- nextOnlyVertical: nextResult.every((d2) => d2.userData.isPerpendicularTo(firstLine)),
19301
- next: nextResult,
19302
- parallel: parallel2
19303
- };
19304
- }
19305
- const removeLinesSet = /* @__PURE__ */ new Set();
19306
- for (let i = 0; i < lineSegments.length; i++) {
19307
- const line = lineSegments[i];
19308
- if (removeLinesSet.has(line)) continue;
19309
- const len = line.length();
19310
- if (len > findMinWidth) continue;
19311
- const startInfo = getIntersInfo(line, line.start);
19312
- if (!startInfo) continue;
19313
- const endInfo = getIntersInfo(line, line.end);
19314
- if (!endInfo) continue;
19315
- const angle = startInfo.direction.angle(endInfo.direction, { unit: "degree", range: "180" });
19316
- if (angle < 177) continue;
19317
- if (!startInfo.nextOnlyVertical && !endInfo.nextOnlyVertical) continue;
19318
- let mainInfo = startInfo, secondaryInfo = endInfo;
19319
- if (startInfo.nextOnlyVertical && endInfo.nextOnlyVertical) {
19320
- if (startInfo.length < endInfo.length) {
19321
- mainInfo = endInfo;
19322
- secondaryInfo = startInfo;
19323
- }
19324
- } else if (startInfo.nextOnlyVertical) {
19325
- mainInfo = endInfo;
19326
- secondaryInfo = startInfo;
19327
- }
19328
- const parallel2 = startInfo.parallel.concat(endInfo.parallel);
19329
- const newPoint = getNextPoint(mainInfo.firstPoint, mainInfo.firstLine, secondaryInfo.next, secondaryInfo.length);
19330
- if (!newPoint) continue;
19331
- removeLinesSet.add(line);
19332
- line.points.forEach((p2) => grid.remove(p2));
19333
- if (parallel2.length === 0) {
19334
- const oldLine = mainInfo.firstLine.clone();
19335
- mainInfo.firstPoint.copy(newPoint);
19336
- secondaryInfo.next.forEach((d2) => d2.point.copy(newPoint));
19337
- removeLinesSet.add(secondaryInfo.firstLine);
19338
- secondaryInfo.firstLine.points.forEach((p2) => grid.remove(p2));
19339
- mainInfo.firstLine.points.forEach((p2) => grid.update(p2));
19340
- if (typeof onMerge === "function") onMerge(mainInfo.firstLine, line, secondaryInfo.firstLine, oldLine);
19341
- } else {
19342
- secondaryInfo.firstPoint.copy(mainInfo.firstPoint);
19343
- secondaryInfo.firstOtherPoint.copy(newPoint);
19344
- secondaryInfo.next.forEach((d2) => d2.point.copy(newPoint));
19345
- startInfo.parallel.concat(endInfo.parallel).forEach((item) => item.point.copy(mainInfo.firstPoint));
19346
- secondaryInfo.firstLine.points.forEach((p2) => grid.update(p2));
19347
- secondaryInfo.next.forEach((d2) => grid.update(d2.point));
19348
- startInfo.parallel.concat(endInfo.parallel).forEach((item) => grid.update(item.point));
19349
- }
19350
- }
19351
- lineSegments = lineSegments.filter((line) => !removeLinesSet.has(line));
19352
- return lineSegments;
19353
- }
19354
- function repetitiveTask(count, callfun) {
19355
- for (let i = 0; i < count; i++) {
19356
- callfun(i);
19357
- }
19358
- }
19359
- function stepEliminationMerge(target, _, source, oldLine) {
19360
- if (source.userData.isDoor) WallInsertObject.addInsertObject(target, {
19361
- p: source.center.toJson(),
19362
- width: source.length(),
19363
- full: false,
19364
- type: "door",
19365
- height: source.userData.drawDoorData.height,
19366
- groundClearance: source.userData.drawDoorData.groundClearance
19367
- });
19368
- if (target.userData.isDoor) {
19369
- delete target.userData.isDoor;
19370
- WallInsertObject.addInsertObject(target, {
19371
- p: oldLine.center.toJson(),
19372
- width: oldLine.length(),
19373
- full: false,
19374
- type: "door",
19375
- height: target.userData.drawDoorData?.height,
19376
- groundClearance: target.userData.drawDoorData?.groundClearance ?? 0
19377
- });
19378
- }
19379
- WallInsertObject.copyInsertObject(target, source);
19380
- WallInsertObject.recomputed([target]);
19381
- }
19382
- function linesSmoothing(lines, _) {
19383
- repetitiveTask(2, () => lines = stepElimination(lines, 0.1, stepEliminationMerge));
19384
- WallInsertObject.recomputed(lines);
19385
- return lines;
19386
- }
19387
19498
  const PRE_PROCESSOR = {
19388
19499
  init,
19389
19500
  AxisAlignCorr: axisAlignCorr,
@@ -19631,6 +19742,7 @@ class CorrectionDxf extends Dxf {
19631
19742
  onAddFromParent(parent) {
19632
19743
  parent.Dxf.addEventListener("cadChange", (e) => {
19633
19744
  e.options.trajectory && this.addPreProcessor(PRE_PROCESSOR.BoundExt);
19745
+ this.addPreProcessor(PRE_PROCESSOR.DoubleWallAlignment);
19634
19746
  const lines = parent.Dxf.getLineSegments(true);
19635
19747
  this.set(lineDataToOriginalData(lines, parent.Dxf.originalZAverage), {
19636
19748
  trajectory: e.options.trajectory,
@@ -21920,6 +22032,7 @@ const index$2 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePrope
21920
22032
  OBB: OBB2,
21921
22033
  PCSparseOctree,
21922
22034
  Point,
22035
+ PointUtils,
21923
22036
  PointVirtualGrid,
21924
22037
  Polygon,
21925
22038
  PvgList,
package/src/index3.js CHANGED
@@ -15904,7 +15904,7 @@ function modifyWindow(context, winLine, line2, index2) {
15904
15904
  dragPoint.copy(p.toJson());
15905
15905
  lineMesh.setPoint(winLine.start.toVector3(), winLine.end.toVector3());
15906
15906
  editBtn.setPosition(winLine.center);
15907
- const [l1, l2] = LineSegment.clippingByLine(line2, winLine);
15907
+ const [l1, l2] = LineSegment.clippingByLine(line2, winLine) ?? [];
15908
15908
  if (l1) {
15909
15909
  text1.visible = true;
15910
15910
  text1.position.copy(l1.center.toJson(0));
@@ -15,7 +15,7 @@ export declare class CorrectionDxf<TEventMap extends {} = {}> extends Dxf<{} & T
15
15
  DoubleWallAlignment: typeof import('../utils/lineHandle/CadPreProcessor/doubleWallAlignment').doubleWallAlignment;
16
16
  WallHeightHandle: typeof import('../utils/lineHandle/CadPreProcessor/wallHeightHandle').wallHeightHandle;
17
17
  DoorSpaceHandle: typeof import('../utils/lineHandle/CadPreProcessor/doorSpaceHandle').doorSpaceHandle;
18
- LinesSmoothing: typeof import('../utils/lineHandle/CadPreProcessor/linesSmoothing').linesSmoothing;
18
+ LinesSmoothing: typeof import('../utils/lineHandle/CadPreProcessor/axisAlignCorr/linesSmoothing').linesSmoothing;
19
19
  RemoveShortDoubleWall: typeof import('../utils/lineHandle/CadPreProcessor/removeShortDoubleWall').removeShortDoubleWall;
20
20
  };
21
21
  rotateCorrCad?: CAD;
@@ -29,7 +29,7 @@ export declare class Dxf<TEventMap extends {} = {}> extends Component<{
29
29
  DoubleWallAlignment: typeof import('../utils/lineHandle/CadPreProcessor/doubleWallAlignment').doubleWallAlignment;
30
30
  WallHeightHandle: typeof import('../utils/lineHandle/CadPreProcessor/wallHeightHandle').wallHeightHandle;
31
31
  DoorSpaceHandle: typeof import('../utils/lineHandle/CadPreProcessor/doorSpaceHandle').doorSpaceHandle;
32
- LinesSmoothing: typeof import('../utils/lineHandle/CadPreProcessor/linesSmoothing').linesSmoothing;
32
+ LinesSmoothing: typeof import('../utils/lineHandle/CadPreProcessor/axisAlignCorr/linesSmoothing').linesSmoothing;
33
33
  RemoveShortDoubleWall: typeof import('../utils/lineHandle/CadPreProcessor/removeShortDoubleWall').removeShortDoubleWall;
34
34
  };
35
35
  width: number;
@@ -1,5 +1,5 @@
1
- import { LineSegment } from '../../../../algorithmsStructures/LineSegment';
2
- import { SetDataOption, LineUserData } from '../../../type';
1
+ import { LineSegment } from '../../../../../algorithmsStructures/LineSegment';
2
+ import { SetDataOption, LineUserData } from '../../../../type';
3
3
  /**
4
4
  * 轴对齐垂直修正
5
5
  * @param lines 待调整线段组
@@ -0,0 +1,3 @@
1
+ import { LineSegment } from '../../../../../algorithmsStructures/LineSegment';
2
+ import { SetDataOption } from '../../../../type';
3
+ export declare function linesSmoothing(lines: LineSegment[], _?: SetDataOption): LineSegment<Record<string, any>>[];
@@ -0,0 +1,6 @@
1
+ import { LineSegment } from '../../../../../algorithmsStructures/LineSegment';
2
+ /** 路径阶梯合并
3
+ * @param lineSegments
4
+ * @returns
5
+ */
6
+ export declare function removeQuad(lineSegments: LineSegment[], findMinWidth?: number, onMerge?: (mainLine: LineSegment, sortLine: LineSegment, secondaryLine: LineSegment, oldLine: LineSegment) => void): LineSegment<Record<string, any>>[];
@@ -6,7 +6,7 @@ import { doubleWallAlignment } from './doubleWallAlignment';
6
6
  import { wallHeightHandle } from './wallHeightHandle';
7
7
  import { doorSpaceHandle } from './doorSpaceHandle';
8
8
  import { removeShortDoubleWall } from './removeShortDoubleWall';
9
- import { linesSmoothing } from './linesSmoothing';
9
+ import { linesSmoothing } from './axisAlignCorr/linesSmoothing';
10
10
  /**
11
11
  * 默认提供的预处理函数
12
12
  */
@@ -34,7 +34,7 @@ export declare class DoubleWallHelper {
34
34
  * @param wallWidth
35
35
  * @returns
36
36
  */
37
- static complementSide(lines: LineSegment<LineUserData>[], wallWidth?: number): LineSegment<LineUserData>[];
37
+ static complementSide(lines: LineSegment<LineUserData>[], obstacleAegment?: LineSegment[], wallWidth?: number): LineSegment<LineUserData>[];
38
38
  /**
39
39
  * 创建分组
40
40
  */
@@ -5,7 +5,7 @@ import { LineUserData } from '../../../type';
5
5
  * @param clearInternalLine
6
6
  * @returns
7
7
  */
8
- export declare function buildDoubleWallGroup_(lines_: LineSegment<LineUserData>[], clearInternalLine?: boolean): LineSegment<Record<string, any>>[];
8
+ export declare function buildDoubleWallGroup_(lines_: LineSegment<LineUserData>[], clearInternalLine?: boolean): LineSegment<LineUserData>[];
9
9
  /** */
10
10
  export declare const buildDoubleWallGroup: typeof buildDoubleWallGroup_ & {
11
11
  setTrajectory(trajectory_: Record<string, any> | undefined): void;
@@ -0,0 +1,7 @@
1
+ import { LineSegment } from '../../../algorithmsStructures/LineSegment';
2
+ /** 移除游离短线段
3
+ * @param lines
4
+ * @param len
5
+ * @returns
6
+ */
7
+ export declare function removeDangline(lines: LineSegment[], len?: number, consecutive?: boolean): LineSegment<Record<string, any>>[];
@@ -279,6 +279,11 @@ export declare class LineSegment<T = Record<string, any>> {
279
279
  * @returns
280
280
  */
281
281
  static mergeLines(...lines: LineSegment[]): LineSegment<Record<string, any>>;
282
+ /** 传入的线段全部投影为一条线段,默认以最长线线段为位置和方向
283
+ * @param lines 请确保共线
284
+ * @returns
285
+ */
286
+ static mergeCollinearSegments(lines: LineSegment[]): LineSegment<Record<string, any>>;
282
287
  /** 合并满足平行的线段
283
288
  * @param selectLines
284
289
  */
@@ -292,7 +297,7 @@ export declare class LineSegment<T = Record<string, any>> {
292
297
  * @param callBack
293
298
  * @returns
294
299
  */
295
- static mergeCollinearSegments(lines: LineSegment[], callBack?: (newLine: LineSegment, group: LineSegment[]) => void, removeLines?: Set<LineSegment<Record<string, any>>>, newLines?: LineSegment[]): LineSegment<Record<string, any>>[];
300
+ static mergeCollinearSegmentsAll(lines: LineSegment[], callBack?: (newLine: LineSegment, group: LineSegment[]) => void, removeLines?: Set<LineSegment<Record<string, any>>>, newLines?: LineSegment[]): LineSegment<Record<string, any>>[];
296
301
  /** 去重
297
302
  * @param lines
298
303
  * @returns
@@ -317,6 +322,11 @@ export declare class LineSegment<T = Record<string, any>> {
317
322
  */
318
323
  static clippingByLines(target: LineSegment, clippingLines: LineSegment[], callBack?: (newLine: LineSegment, line: LineSegment) => void): LineSegment<Record<string, any>>[] | undefined;
319
324
  static constrainLine(line: LineSegment, base: LineSegment): LineSegment<Record<string, any>>;
325
+ /** 通过线段提取所有点
326
+ * @param lines
327
+ * @returns
328
+ */
329
+ static flatPoints(lines: LineSegment[] | LineSegment): any[];
320
330
  /** 创建线段修改管理器
321
331
  * @returns
322
332
  */
@@ -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, eps?: number): boolean;
25
+ equal(point: Point): boolean;
26
26
  /**
27
27
  *
28
28
  * @param arr
@@ -196,3 +196,14 @@ export declare class Point<T = Record<string, any>> {
196
196
  private static distanceClearQueue;
197
197
  private static addDistanceCacheClear;
198
198
  }
199
+ export declare class PointUtils {
200
+ /** 值网格化
201
+ * @param points
202
+ * @param tolerance
203
+ */
204
+ static quantize(points: Point[], tolerance?: number): Point<Record<string, any>>[];
205
+ /**保留小数位数
206
+ * @param points
207
+ */
208
+ static round(points: Point[], scale?: number): Point<Record<string, any>>[];
209
+ }
@@ -35,6 +35,10 @@ export declare class PointVirtualGrid<T = Record<string, any>> {
35
35
  * @param point
36
36
  */
37
37
  remove(point: Point): this;
38
+ /** 移除点
39
+ * @param point
40
+ */
41
+ removes(point: Point[]): this;
38
42
  update(point: Point): boolean;
39
43
  /**
40
44
  * 获取通过坐标,获取唯一网格索引
@@ -1,3 +0,0 @@
1
- import { LineSegment } from '../../../../algorithmsStructures/LineSegment';
2
- import { SetDataOption } from '../../../type';
3
- export declare function linesSmoothing(lines: LineSegment[], _?: SetDataOption): LineSegment<Record<string, any>>[];