build-dxf 0.1.109 → 0.1.110

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.109",
3
+ "version": "0.1.110",
4
4
  "description": "线段构建双线墙壁的dxf版本",
5
5
  "main": "./src/index.js",
6
6
  "types": "./src/index.d.ts",
package/src/build.js CHANGED
@@ -399,9 +399,9 @@ class LineSegment {
399
399
  currentData = {};
400
400
  // line: any
401
401
  uuid = uuid();
402
- #length = 0;
402
+ _length = 0;
403
403
  get len() {
404
- return this.#length;
404
+ return this._length;
405
405
  }
406
406
  get start() {
407
407
  return this.points[0];
@@ -409,11 +409,11 @@ class LineSegment {
409
409
  get end() {
410
410
  return this.points[1];
411
411
  }
412
- #center = Point.zero();
412
+ _center = Point.zero();
413
413
  get center() {
414
- return this.#center.clone();
414
+ return this._center.clone();
415
415
  }
416
- #direction = Point.zero();
416
+ _direction = Point.zero();
417
417
  constructor(p1, p2) {
418
418
  this.set(p1 ?? this.start, p2 ?? this.end);
419
419
  this.start.currentData[LineSegment.LINE_SYMBOL] = this;
@@ -422,12 +422,12 @@ class LineSegment {
422
422
  }
423
423
  _initLenListener() {
424
424
  const distanceUpdate = () => {
425
- this.#length = this.points[0].distance(this.points[1]);
426
- this.#center.set(
425
+ this._length = this.points[0].distance(this.points[1]);
426
+ this._center.set(
427
427
  this.points[0].x + (this.points[1].x - this.points[0].x) * 0.5,
428
428
  this.points[0].y + (this.points[1].y - this.points[0].y) * 0.5
429
429
  );
430
- this.#direction = this.points[1].directionFrom(this.points[0]);
430
+ this._direction = this.points[1].directionFrom(this.points[0]);
431
431
  };
432
432
  this.points.forEach((p2) => fields.forEach((k) => {
433
433
  let value = p2[k];
@@ -455,12 +455,12 @@ class LineSegment {
455
455
  const dx = direct.x * half;
456
456
  const dy = direct.y * half;
457
457
  this.start.set(
458
- this.#center.x - dx,
459
- this.#center.y - dy
458
+ this._center.x - dx,
459
+ this._center.y - dy
460
460
  );
461
461
  this.end.set(
462
- this.#center.x + dx,
463
- this.#center.y + dy
462
+ this._center.x + dx,
463
+ this._center.y + dy
464
464
  );
465
465
  return this;
466
466
  }
@@ -477,7 +477,7 @@ class LineSegment {
477
477
  * @returns
478
478
  */
479
479
  length(_ = false) {
480
- return this.#length;
480
+ return this._length;
481
481
  }
482
482
  /** 开始点向线段内收缩 width
483
483
  * @param width
@@ -500,35 +500,35 @@ class LineSegment {
500
500
  * @param line
501
501
  * @returns
502
502
  */
503
- isSameEndpoint(line) {
504
- return this.start.equal(line.start) || this.start.equal(line.end) || this.end.equal(line.start) || this.end.equal(line.end);
503
+ isSameEndpoint(line, eps = 1e-9) {
504
+ return this.start.equal(line.start, eps) || this.start.equal(line.end, eps) || this.end.equal(line.start, eps) || this.end.equal(line.end, eps);
505
505
  }
506
506
  /**
507
507
  * 相同端点是否为开始
508
508
  * @param line
509
509
  * @returns
510
510
  */
511
- isSameEndpointAsStart(line) {
512
- return this.start.equal(line.start) || this.start.equal(line.end);
511
+ isSameEndpointAsStart(line, eps = 1e-9) {
512
+ return this.start.equal(line.start, eps) || this.start.equal(line.end, eps);
513
513
  }
514
514
  /**
515
515
  * 相同端点是否为结束
516
516
  * @param line
517
517
  * @returns
518
518
  */
519
- isSameEndpointAsEnd(line) {
520
- return this.end.equal(line.start) || this.end.equal(line.end);
519
+ isSameEndpointAsEnd(line, eps = 1e-9) {
520
+ return this.end.equal(line.start, eps) || this.end.equal(line.end, eps);
521
521
  }
522
522
  /**
523
523
  * 获取共线点
524
524
  * @param line
525
525
  * @returns
526
526
  */
527
- getSameEndpoint(line) {
528
- if (this.start.equal(line.start)) return [this.start, line.start];
529
- else if (this.start.equal(line.end)) return [this.start, line.end];
530
- else if (this.end.equal(line.start)) return [this.end, line.start];
531
- else if (this.end.equal(line.end)) return [this.end, line.end];
527
+ getSameEndpoint(line, eps = 1e-9) {
528
+ if (this.start.equal(line.start, eps)) return [this.start, line.start];
529
+ else if (this.start.equal(line.end, eps)) return [this.start, line.end];
530
+ else if (this.end.equal(line.start, eps)) return [this.end, line.start];
531
+ else if (this.end.equal(line.end, eps)) return [this.end, line.end];
532
532
  return null;
533
533
  }
534
534
  /**
@@ -608,7 +608,7 @@ class LineSegment {
608
608
  * @returns
609
609
  */
610
610
  direction() {
611
- return this.#direction.clone();
611
+ return this._direction.clone();
612
612
  }
613
613
  /**
614
614
  * 获取发向量-左法线
@@ -1058,8 +1058,8 @@ class Point {
1058
1058
  * @param point
1059
1059
  * @returns
1060
1060
  */
1061
- equal(point2) {
1062
- return Math.abs(point2.x - this.x) < 1e-9 && Math.abs(point2.y - this.y) < 1e-9;
1061
+ equal(point2, eps = 1e-9) {
1062
+ return Math.abs(point2.x - this.x) < eps && Math.abs(point2.y - this.y) < eps;
1063
1063
  }
1064
1064
  /**
1065
1065
  *
@@ -2417,6 +2417,11 @@ class Quadtree {
2417
2417
  }));
2418
2418
  return array;
2419
2419
  }
2420
+ static from(lines) {
2421
+ const quadtree = new Quadtree(Box2.fromByLineSegment(...lines));
2422
+ lines.forEach((line) => quadtree.insert({ line, userData: void 0 }));
2423
+ return quadtree;
2424
+ }
2420
2425
  }
2421
2426
  class WallInsertObject {
2422
2427
  static mountedObjectType = [];
@@ -3655,6 +3660,33 @@ class LineSegmentUtils {
3655
3660
  }
3656
3661
  return points;
3657
3662
  }
3663
+ static resolveIntersection(lines, onClip) {
3664
+ const quadtree = Quadtree.from(lines), queryLine = new LineSegment(), arrayMap = new ArrayMap();
3665
+ for (let i = 0; i < lines.length; i++) {
3666
+ const line = lines[i];
3667
+ queryLine.copy(line).setLength(line.len + 0.04);
3668
+ quadtree.queryLineSegment(queryLine).forEach((res) => {
3669
+ if (res.line === line) return;
3670
+ if (line.isSameEndpoint(res.line, 1e-4)) return;
3671
+ const point2 = res.line.getIntersection(line);
3672
+ if (!point2) return;
3673
+ arrayMap.append(res.line, point2);
3674
+ });
3675
+ }
3676
+ const newLines = [];
3677
+ const removeSet = /* @__PURE__ */ new Set();
3678
+ arrayMap.forEach((points, line) => {
3679
+ if (points.length) {
3680
+ let lines2 = LineSegmentUtils.clippingByPoints(line, points);
3681
+ onClip?.(line, lines2);
3682
+ newLines.push(...lines2);
3683
+ removeSet.add(line);
3684
+ } else newLines.push(line);
3685
+ });
3686
+ lines = lines.filter((line) => !removeSet.has(line));
3687
+ lines.push(...newLines);
3688
+ return lines;
3689
+ }
3658
3690
  /** 对线段组统计,找到主导方向线
3659
3691
  * @param lineSegments
3660
3692
  * @returns
@@ -6010,39 +6042,25 @@ function migration(newLine, oldLine) {
6010
6042
  });
6011
6043
  }
6012
6044
  function lineSegmentClipping(lines, minLen = 1e-9, dedup = true) {
6013
- const quadtree = new Quadtree(Box2.fromByLineSegment(...lines));
6014
- lines.forEach((line) => quadtree.insert({ line, userData: void 0 }));
6015
- let newLines = lines.flatMap((line) => {
6016
- const points = quadtree.queryLineSegment(line).map((res) => {
6017
- if (res.line === line) return;
6018
- const point2 = res.line.getIntersection(line);
6019
- if (!point2 || line.start.equal(point2) || line.end.equal(point2)) return;
6020
- return point2;
6021
- }).filter((i) => !!i);
6022
- if (points.length) {
6023
- const newLines2 = LineSegmentUtils.clippingByPoints(line, points);
6024
- newLines2.map((newLine) => migration(newLine, line));
6025
- if (line.userData.isBayWindow) {
6026
- newLines2.sort((a2, b4) => b4.length() - a2.length());
6027
- for (let i = 1; i < newLines2.length; i++) {
6028
- newLines2[i].userData.isBayWindow = false;
6029
- }
6045
+ lines = LineSegmentUtils.resolveIntersection(lines, (line, newLines) => {
6046
+ newLines.map((newLine) => migration(newLine, line));
6047
+ if (line.userData.isBayWindow) {
6048
+ newLines.sort((a2, b4) => b4.length() - a2.length());
6049
+ for (let i = 1; i < newLines.length; i++) {
6050
+ newLines[i].userData.isBayWindow = false;
6030
6051
  }
6031
- if (line.userData.isBalconyRailing) {
6032
- const len = line.length();
6033
- newLines2.forEach((line2) => {
6034
- if (line2.length() / len < 0.2) {
6035
- delete line2.userData.isBalconyRailing;
6036
- }
6037
- });
6038
- }
6039
- return newLines2;
6040
6052
  }
6041
- return line;
6053
+ if (line.userData.isBalconyRailing) {
6054
+ const len = line.length();
6055
+ newLines.forEach((line2) => {
6056
+ if (line2.length() / len < 0.2) {
6057
+ delete line2.userData.isBalconyRailing;
6058
+ }
6059
+ });
6060
+ }
6042
6061
  });
6043
- newLines = newLines.filter((line) => line.length() >= minLen);
6044
- quadtree.clear();
6045
- return dedup ? LineSegmentUtils.deduplication(newLines) : newLines;
6062
+ lines = lines.filter((line) => line.length() >= minLen);
6063
+ return dedup ? LineSegmentUtils.deduplication(lines) : lines;
6046
6064
  }
6047
6065
  class LineIndexGenerator {
6048
6066
  index = 0;
@@ -6641,7 +6659,6 @@ function clippingDoubleWall(lines) {
6641
6659
  }
6642
6660
  const miniCircles = new MiniCircles();
6643
6661
  function clippingInsertObjectDoubleWall(lines) {
6644
- if (lines.length === 4) return [lines];
6645
6662
  const hasInsertObject = lines.some((line) => WallInsertObject.isInsertObject(line));
6646
6663
  if (!hasInsertObject) return clippingDoubleWall(lines);
6647
6664
  const quadtree = createQuadtree(lines), poly = Polygon.fromByLines2(lines), far = 10;
@@ -6653,7 +6670,7 @@ function clippingInsertObjectDoubleWall(lines) {
6653
6670
  if (!poly.pointWithin(center.add(normal.clone().multiplyScalar(1e-6)))) normal.multiplyScalar(-1);
6654
6671
  WallInsertObject.forEachInsertObjectData(line, (data) => data.forEach((d2) => {
6655
6672
  const wioLine = wallInsertObjectToLine(line, d2);
6656
- wioLine.setLength(wioLine.len * 0.98);
6673
+ wioLine.setLength(wioLine.len - 4e-3);
6657
6674
  const len = wioLine.length();
6658
6675
  let startResults = quadtree.raycaster(wioLine.start, normal, 1e-4, far).filter((item) => item.targetLine.isParallelTo(wioLine));
6659
6676
  let endResults = quadtree.raycaster(wioLine.end, normal, 1e-4, far).filter((item) => item.targetLine.isParallelTo(wioLine));
@@ -9689,6 +9706,7 @@ class ThreeVJiaPipeline extends Pipeline {
9689
9706
  if (info) {
9690
9707
  const { dottedLine, windowLine, depth, side } = info, line = new LineSegment(dottedLine.start.clone(), dottedLine.end.clone()), win = windowLine?.userData.drawWindow && windowLine.userData.drawWindow[0];
9691
9708
  if (side === "LEFT") line.swapValue();
9709
+ line.translate(-DEFAULT_WALL_WIDTH * 0.5, line.normal());
9692
9710
  line.userData = {
9693
9711
  groundClearance: win?.groundClearance ?? 0,
9694
9712
  height: win?.height,
@@ -9815,7 +9833,7 @@ class ThreeVJiaPipeline extends Pipeline {
9815
9833
  if (roomPloys.length === 0) return json;
9816
9834
  publicInfo.itemInfo.forEach((item, i) => {
9817
9835
  if (!placeHoldersMap[item.category]) return;
9818
- const itemPoly = new Polygon(item.contour.map((p2) => Point.from(p2).rotate(json.center, json.angle))), center = itemPoly.getCenter(), index2 = roomPloys.findIndex((poly) => poly.pointWithin(center));
9836
+ const contour = item.quadContour ?? item.contour, itemPoly = new Polygon(contour.map((p2) => Point.from(p2).rotate(json.center, json.angle))), center = itemPoly.getCenter(), index2 = roomPloys.findIndex((poly) => poly.pointWithin(center));
9819
9837
  if (index2 < 0) return;
9820
9838
  json.placeHolders.push({
9821
9839
  name: placeHoldersMap[item.category],
@@ -9977,39 +9995,6 @@ const tools = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
9977
9995
  toOriginalDataItem,
9978
9996
  wallInsertObjectToLine
9979
9997
  }, Symbol.toStringTag, { value: "Module" }));
9980
- class Group {
9981
- type = "";
9982
- userData = { color: "#fff" };
9983
- constructor(lines = [], type = "", userData = {}) {
9984
- this.type = type;
9985
- this.addLine(...lines);
9986
- Object.assign(this.userData, userData);
9987
- }
9988
- lines = [];
9989
- /** 添加线段
9990
- * @param arg
9991
- */
9992
- addLine(...arg) {
9993
- this.lines.push(...arg);
9994
- }
9995
- removeLine(...lines) {
9996
- if (lines.length === 0) return;
9997
- if (lines.length === 1) {
9998
- const index2 = this.lines.indexOf(lines[0]);
9999
- this.lines.splice(index2, 1);
10000
- return;
10001
- }
10002
- const set2 = new Set(lines);
10003
- this.lines = this.lines.filter((line) => !set2.has(line));
10004
- }
10005
- clone() {
10006
- const group = new this.constructor();
10007
- group.type = this.type;
10008
- group.lines = this.lines.map((line) => line.clone());
10009
- Object.assign(group.userData, this.userData);
10010
- return group;
10011
- }
10012
- }
10013
9998
  const units = {
10014
9999
  Unitless: 1,
10015
10000
  // 无单位,1米 = 1(无单位)
@@ -10054,6 +10039,223 @@ const units = {
10054
10039
  Parsecs: 3240779289666404e-32
10055
10040
  // 秒差距,1米 ≈ 0.00000000000000003240779289666404秒差距
10056
10041
  };
10042
+ function toDrawData(unit = "Centimeters") {
10043
+ if (!this.needUpdate && this._cachedDrawDataMap.has(unit)) return this._cachedDrawDataMap.get(unit);
10044
+ this._cachedDrawDataMap.clear();
10045
+ this.needUpdate = false;
10046
+ const lines = this.groups.flatMap((group) => group.lines), s = units[unit], expansionWidth = 2, box = Box2.fromByLineSegment(...lines).expansion(expansionWidth), center = box.center, data = {
10047
+ unit,
10048
+ lines: [],
10049
+ lines2: [],
10050
+ arcs: [],
10051
+ texts: [],
10052
+ center: center.clone().multiplyScalar(s).toJson(),
10053
+ width: box.width * s,
10054
+ height: box.height * s,
10055
+ scale: s
10056
+ };
10057
+ let color = "white";
10058
+ function drawText2(str, p2) {
10059
+ data.texts.push([str, p2.x * s, p2.y * s, color]);
10060
+ }
10061
+ function drawLine(p1, p2) {
10062
+ data.lines.push([p1.x * s, p1.y * s, p2.x * s, p2.y * s, color]);
10063
+ }
10064
+ function drawLine2(p1, p2) {
10065
+ data.lines2.push([p1.x * s, p1.y * s, p2.x * s, p2.y * s, color]);
10066
+ }
10067
+ function drawDottedLine(p1, p2, dash = 0.04, gap = 0.05, mode = "line") {
10068
+ const distance2 = dash + gap;
10069
+ let current = 0;
10070
+ const direction = p2.directionFrom(p1);
10071
+ const length = p1.distance(p2);
10072
+ while (current < length) {
10073
+ const dashEnd = Math.min(current + dash, length);
10074
+ const start = p1.clone().add(direction.clone().multiplyScalar(current));
10075
+ const end = p1.clone().add(direction.clone().multiplyScalar(dashEnd));
10076
+ if (mode === "line") drawLine(start, end);
10077
+ else drawLine2(start, end);
10078
+ current += distance2;
10079
+ }
10080
+ }
10081
+ const line = new LineSegment();
10082
+ function drawRulerLine(p1, p2) {
10083
+ line.set(p1, p2);
10084
+ const length = line.length();
10085
+ const angle = line.direction().angle(new Point(0, 1), { unit: "degree", range: "180" });
10086
+ const p1C = p1.clone();
10087
+ const p2C = p2.clone();
10088
+ const offset = expansionWidth * 0.4;
10089
+ if (Math.min(angle, 180 - angle) < 1) {
10090
+ if (p1.x < center.x) {
10091
+ p1C.x = box.minX + offset;
10092
+ p2C.x = box.minX + offset;
10093
+ } else {
10094
+ p1C.x = box.maxX - offset;
10095
+ p2C.x = box.maxX - offset;
10096
+ }
10097
+ } else {
10098
+ if (p1.y < center.y) {
10099
+ p1C.y = box.minY + offset;
10100
+ p2C.y = box.minY + offset;
10101
+ } else {
10102
+ p1C.y = box.maxY - offset;
10103
+ p2C.y = box.maxY - offset;
10104
+ }
10105
+ }
10106
+ line.set(p1C, p2C);
10107
+ drawDottedLine(p1C, p1, 0.04, 0.05, "line2");
10108
+ drawDottedLine(p2C, p2, 0.04, 0.05, "line2");
10109
+ drawLine2(p1C, p2C);
10110
+ color = "white";
10111
+ drawText2((length * 1e3).toFixed(0) + "mm", line.center);
10112
+ }
10113
+ function drawArc(pos, radius, startAngle, endAngle) {
10114
+ data.arcs.push([
10115
+ pos.x * s,
10116
+ pos.y * s,
10117
+ radius * s,
10118
+ startAngle,
10119
+ endAngle,
10120
+ color
10121
+ ]);
10122
+ }
10123
+ this.groups.forEach((group) => {
10124
+ const set2 = this._drawHandlerMap.get(group.type);
10125
+ if (!set2) return;
10126
+ const option = { group, drawArc, drawLine, drawDottedLine, drawText: drawText2, drawRulerLine, setColor(c) {
10127
+ color = c;
10128
+ } };
10129
+ set2.forEach((fun) => fun.handler(option));
10130
+ });
10131
+ this._cachedDrawDataMap.set(unit, data);
10132
+ return data;
10133
+ }
10134
+ async function toDxfImageBlob(data, type = "image/jpeg", background = "#000") {
10135
+ const margin = 0 * data.scale;
10136
+ let canvas;
10137
+ if (typeof window !== "undefined") {
10138
+ canvas = document.createElement("canvas");
10139
+ } else if (typeof global !== "undefined") {
10140
+ const { createCanvas } = await include("canvas");
10141
+ canvas = createCanvas(data.width + margin * 2, data.height + margin * 2);
10142
+ } else {
10143
+ throw new Error("创建画布失败");
10144
+ }
10145
+ const colors = {
10146
+ cyan: "cyan",
10147
+ yellow: "yellow",
10148
+ white: "white"
10149
+ };
10150
+ canvas.width = data.width + margin * 2;
10151
+ canvas.height = data.height + margin * 2;
10152
+ const ctx = canvas.getContext("2d");
10153
+ if (background) {
10154
+ ctx.fillStyle = background;
10155
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
10156
+ }
10157
+ ctx.translate(-data.center.x + data.width * 0.5 + margin, data.center.y + data.height * 0.5 + margin);
10158
+ ctx.scale(1, -1);
10159
+ data.lines.forEach(([p1x, p1y, p2x, p2y, color]) => {
10160
+ ctx.strokeStyle = colors[color] ?? color;
10161
+ ctx.beginPath();
10162
+ ctx.moveTo(p1x, p1y);
10163
+ ctx.lineTo(p2x, p2y);
10164
+ ctx.closePath();
10165
+ ctx.stroke();
10166
+ });
10167
+ data.lines2.forEach(([p1x, p1y, p2x, p2y, color]) => {
10168
+ ctx.strokeStyle = colors[color] ?? color;
10169
+ ctx.beginPath();
10170
+ ctx.moveTo(p1x, p1y);
10171
+ ctx.lineTo(p2x, p2y);
10172
+ ctx.closePath();
10173
+ ctx.stroke();
10174
+ });
10175
+ data.arcs.forEach(([x, y, radius, startAngle, endAngle, color]) => {
10176
+ ctx.strokeStyle = colors[color];
10177
+ ctx.beginPath();
10178
+ ctx.arc(x, y, radius, startAngle * (Math.PI / 180), endAngle * (Math.PI / 180));
10179
+ ctx.stroke();
10180
+ });
10181
+ data.texts.forEach(([str, x, y, color]) => {
10182
+ ctx.fillStyle = colors[color] ?? color ?? "#fff";
10183
+ ctx.font = `${0.15 * data.scale}px Arial`;
10184
+ ctx.textAlign = "center";
10185
+ ctx.textBaseline = "middle";
10186
+ ctx.save();
10187
+ ctx.translate(x, y);
10188
+ ctx.scale(1, -1);
10189
+ ctx.fillText(str, 0, 0);
10190
+ ctx.restore();
10191
+ });
10192
+ if ("toBlob" in canvas) {
10193
+ return new Promise((resolve) => {
10194
+ canvas.toBlob((b4) => {
10195
+ resolve(b4);
10196
+ }, type, 1);
10197
+ });
10198
+ } else {
10199
+ const buffer = canvas.toBuffer(type, { quality: 1 });
10200
+ return buffer;
10201
+ }
10202
+ }
10203
+ function drawDxfString(data, unit = "Millimeters") {
10204
+ const d2 = new Drawing();
10205
+ d2.setUnits(unit);
10206
+ d2.addLayer("cyan", Drawing.ACI.CYAN, "DOTTED");
10207
+ d2.addLayer("yellow", Drawing.ACI.YELLOW, "DOTTED");
10208
+ d2.addLayer("white", Drawing.ACI.WHITE, "DOTTED");
10209
+ d2.addLayer("blue", Drawing.ACI.BLUE, "DOTTED");
10210
+ d2.addLayer("green", Drawing.ACI.GREEN, "DOTTED");
10211
+ d2.addLayer("layer", Drawing.ACI.LAYER, "DOTTED");
10212
+ d2.addLayer("magenta", Drawing.ACI.MAGENTA, "DOTTED");
10213
+ d2.addLayer("red", Drawing.ACI.RED, "DOTTED");
10214
+ data.lines.forEach((item) => {
10215
+ let [p1x, p1y, p2x, p2y, color] = item;
10216
+ d2.setActiveLayer(color);
10217
+ d2.drawLine(p1x, p1y, p2x, p2y);
10218
+ });
10219
+ data.arcs.forEach((item) => {
10220
+ const [x, y, r2, startAngle, endAngle, color] = item;
10221
+ d2.setActiveLayer(color);
10222
+ d2.drawArc(x, y, r2, startAngle, endAngle);
10223
+ });
10224
+ return d2.toDxfString();
10225
+ }
10226
+ class Group {
10227
+ type = "";
10228
+ userData = { color: "#fff" };
10229
+ constructor(lines = [], type = "", userData = {}) {
10230
+ this.type = type;
10231
+ this.addLine(...lines);
10232
+ Object.assign(this.userData, userData);
10233
+ }
10234
+ lines = [];
10235
+ /** 添加线段
10236
+ * @param arg
10237
+ */
10238
+ addLine(...arg) {
10239
+ this.lines.push(...arg);
10240
+ }
10241
+ removeLine(...lines) {
10242
+ if (lines.length === 0) return;
10243
+ if (lines.length === 1) {
10244
+ const index2 = this.lines.indexOf(lines[0]);
10245
+ this.lines.splice(index2, 1);
10246
+ return;
10247
+ }
10248
+ const set2 = new Set(lines);
10249
+ this.lines = this.lines.filter((line) => !set2.has(line));
10250
+ }
10251
+ clone() {
10252
+ const group = new this.constructor();
10253
+ group.type = this.type;
10254
+ group.lines = this.lines.map((line) => line.clone());
10255
+ Object.assign(group.userData, this.userData);
10256
+ return group;
10257
+ }
10258
+ }
10057
10259
  class CAD {
10058
10260
  groups = [];
10059
10261
  _drawHandlerMap = new SetMap();
@@ -10199,169 +10401,14 @@ class CAD {
10199
10401
  */
10200
10402
  _cachedDrawDataMap = /* @__PURE__ */ new Map();
10201
10403
  toDrawData(unit = "Centimeters") {
10202
- if (!this.needUpdate && this._cachedDrawDataMap.has(unit)) return this._cachedDrawDataMap.get(unit);
10203
- this._cachedDrawDataMap.clear();
10204
- this.needUpdate = false;
10205
- const lines = this.groups.flatMap((group) => group.lines), s = units[unit], expansionWidth = 2, box = Box2.fromByLineSegment(...lines).expansion(expansionWidth), center = box.center, data = {
10206
- unit,
10207
- lines: [],
10208
- lines2: [],
10209
- arcs: [],
10210
- texts: [],
10211
- center: center.clone().multiplyScalar(s).toJson(),
10212
- width: box.width * s,
10213
- height: box.height * s,
10214
- scale: s
10215
- };
10216
- let color = "white";
10217
- function drawText2(str, p2) {
10218
- data.texts.push([str, p2.x * s, p2.y * s, color]);
10219
- }
10220
- function drawLine(p1, p2) {
10221
- data.lines.push([p1.x * s, p1.y * s, p2.x * s, p2.y * s, color]);
10222
- }
10223
- function drawLine2(p1, p2) {
10224
- data.lines2.push([p1.x * s, p1.y * s, p2.x * s, p2.y * s, color]);
10225
- }
10226
- function drawDottedLine(p1, p2, dash = 0.04, gap = 0.05, mode = "line") {
10227
- const distance2 = dash + gap;
10228
- let current = 0;
10229
- const direction = p2.directionFrom(p1);
10230
- const length = p1.distance(p2);
10231
- while (current < length) {
10232
- const dashEnd = Math.min(current + dash, length);
10233
- const start = p1.clone().add(direction.clone().multiplyScalar(current));
10234
- const end = p1.clone().add(direction.clone().multiplyScalar(dashEnd));
10235
- if (mode === "line") drawLine(start, end);
10236
- else drawLine2(start, end);
10237
- current += distance2;
10238
- }
10239
- }
10240
- const line = new LineSegment();
10241
- function drawRulerLine(p1, p2) {
10242
- line.set(p1, p2);
10243
- const length = line.length();
10244
- const angle = line.direction().angle(new Point(0, 1), { unit: "degree", range: "180" });
10245
- const p1C = p1.clone();
10246
- const p2C = p2.clone();
10247
- const offset = expansionWidth * 0.4;
10248
- if (Math.min(angle, 180 - angle) < 1) {
10249
- if (p1.x < center.x) {
10250
- p1C.x = box.minX + offset;
10251
- p2C.x = box.minX + offset;
10252
- } else {
10253
- p1C.x = box.maxX - offset;
10254
- p2C.x = box.maxX - offset;
10255
- }
10256
- } else {
10257
- if (p1.y < center.y) {
10258
- p1C.y = box.minY + offset;
10259
- p2C.y = box.minY + offset;
10260
- } else {
10261
- p1C.y = box.maxY - offset;
10262
- p2C.y = box.maxY - offset;
10263
- }
10264
- }
10265
- line.set(p1C, p2C);
10266
- drawDottedLine(p1C, p1, 0.04, 0.05, "line2");
10267
- drawDottedLine(p2C, p2, 0.04, 0.05, "line2");
10268
- drawLine2(p1C, p2C);
10269
- color = "white";
10270
- drawText2((length * 1e3).toFixed(0) + "mm", line.center);
10271
- }
10272
- function drawArc(pos, radius, startAngle, endAngle) {
10273
- data.arcs.push([
10274
- pos.x * s,
10275
- pos.y * s,
10276
- radius * s,
10277
- startAngle,
10278
- endAngle,
10279
- color
10280
- ]);
10281
- }
10282
- this.groups.forEach((group) => {
10283
- const set2 = this._drawHandlerMap.get(group.type);
10284
- if (!set2) return;
10285
- const option = { group, drawArc, drawLine, drawDottedLine, drawRulerLine, setColor(c) {
10286
- color = c;
10287
- } };
10288
- set2.forEach((fun) => fun.handler(option));
10289
- });
10290
- this._cachedDrawDataMap.set(unit, data);
10291
- return data;
10404
+ return toDrawData.call(this, unit);
10292
10405
  }
10293
10406
  /** 转为图片
10294
10407
  * @param type
10295
10408
  */
10296
10409
  async toDxfImageBlob(unit = "Centimeters", type = "image/jpeg", background = "#000") {
10297
10410
  const data = this.toDrawData(unit);
10298
- const margin = 0 * data.scale;
10299
- let canvas;
10300
- if (typeof window !== "undefined") {
10301
- canvas = document.createElement("canvas");
10302
- } else if (typeof global !== "undefined") {
10303
- const { createCanvas } = await include("canvas");
10304
- canvas = createCanvas(data.width + margin * 2, data.height + margin * 2);
10305
- } else {
10306
- throw new Error("创建画布失败");
10307
- }
10308
- const colors = {
10309
- cyan: "cyan",
10310
- yellow: "yellow",
10311
- white: "white"
10312
- };
10313
- canvas.width = data.width + margin * 2;
10314
- canvas.height = data.height + margin * 2;
10315
- const ctx = canvas.getContext("2d");
10316
- if (background) {
10317
- ctx.fillStyle = background;
10318
- ctx.fillRect(0, 0, canvas.width, canvas.height);
10319
- }
10320
- ctx.translate(-data.center.x + data.width * 0.5 + margin, data.center.y + data.height * 0.5 + margin);
10321
- ctx.scale(1, -1);
10322
- data.lines.forEach(([p1x, p1y, p2x, p2y, color]) => {
10323
- ctx.strokeStyle = colors[color] ?? color;
10324
- ctx.beginPath();
10325
- ctx.moveTo(p1x, p1y);
10326
- ctx.lineTo(p2x, p2y);
10327
- ctx.closePath();
10328
- ctx.stroke();
10329
- });
10330
- data.lines2.forEach(([p1x, p1y, p2x, p2y, color]) => {
10331
- ctx.strokeStyle = colors[color] ?? color;
10332
- ctx.beginPath();
10333
- ctx.moveTo(p1x, p1y);
10334
- ctx.lineTo(p2x, p2y);
10335
- ctx.closePath();
10336
- ctx.stroke();
10337
- });
10338
- data.arcs.forEach(([x, y, radius, startAngle, endAngle, color]) => {
10339
- ctx.strokeStyle = colors[color];
10340
- ctx.beginPath();
10341
- ctx.arc(x, y, radius, startAngle * (Math.PI / 180), endAngle * (Math.PI / 180));
10342
- ctx.stroke();
10343
- });
10344
- data.texts.forEach(([str, x, y, color]) => {
10345
- ctx.fillStyle = colors[color] ?? color ?? "#fff";
10346
- ctx.font = `${0.15 * data.scale}px Arial`;
10347
- ctx.textAlign = "center";
10348
- ctx.textBaseline = "middle";
10349
- ctx.save();
10350
- ctx.translate(x, y);
10351
- ctx.scale(1, -1);
10352
- ctx.fillText(str, 0, 0);
10353
- ctx.restore();
10354
- });
10355
- if ("toBlob" in canvas) {
10356
- return new Promise((resolve) => {
10357
- canvas.toBlob((b4) => {
10358
- resolve(b4);
10359
- }, type, 1);
10360
- });
10361
- } else {
10362
- const buffer = canvas.toBuffer(type, { quality: 1 });
10363
- return buffer;
10364
- }
10411
+ return toDxfImageBlob(data, type, background);
10365
10412
  }
10366
10413
  /** 下载为图片
10367
10414
  * @param filename
@@ -10389,28 +10436,8 @@ class CAD {
10389
10436
  * 将点json结构转换为Dxf string
10390
10437
  */
10391
10438
  toDxfString(unit = "Millimeters") {
10392
- const d2 = new Drawing();
10393
- d2.setUnits(unit);
10394
- d2.addLayer("cyan", Drawing.ACI.CYAN, "DOTTED");
10395
- d2.addLayer("yellow", Drawing.ACI.YELLOW, "DOTTED");
10396
- d2.addLayer("white", Drawing.ACI.WHITE, "DOTTED");
10397
- d2.addLayer("blue", Drawing.ACI.BLUE, "DOTTED");
10398
- d2.addLayer("green", Drawing.ACI.GREEN, "DOTTED");
10399
- d2.addLayer("layer", Drawing.ACI.LAYER, "DOTTED");
10400
- d2.addLayer("magenta", Drawing.ACI.MAGENTA, "DOTTED");
10401
- d2.addLayer("red", Drawing.ACI.RED, "DOTTED");
10402
10439
  const data = this.toDrawData(unit);
10403
- data.lines.forEach((item) => {
10404
- let [p1x, p1y, p2x, p2y, color] = item;
10405
- d2.setActiveLayer(color);
10406
- d2.drawLine(p1x, p1y, p2x, p2y);
10407
- });
10408
- data.arcs.forEach((item) => {
10409
- const [x, y, r2, startAngle, endAngle, color] = item;
10410
- d2.setActiveLayer(color);
10411
- d2.drawArc(x, y, r2, startAngle, endAngle);
10412
- });
10413
- return d2.toDxfString();
10440
+ return drawDxfString(data, unit);
10414
10441
  }
10415
10442
  /**
10416
10443
  * 将点云结构转换为DXF格式
@@ -10560,15 +10587,6 @@ class DxfDrawPlugin {
10560
10587
  });
10561
10588
  }
10562
10589
  });
10563
- cad.addDrawHandler({
10564
- type: ["ruler"],
10565
- handler({ drawRulerLine, setColor, group }) {
10566
- setColor("cyan");
10567
- group.lines.forEach((line) => {
10568
- drawRulerLine(line.start, line.end);
10569
- });
10570
- }
10571
- });
10572
10590
  cad.addDrawHandler({
10573
10591
  type: ["balconyRailing"],
10574
10592
  handler({ group, setColor, drawLine }) {
@@ -10580,17 +10598,19 @@ class DxfDrawPlugin {
10580
10598
  });
10581
10599
  }
10582
10600
  }
10583
- class DxfDataPlugin extends Pipeline {
10601
+ class DxfDataPlugin {
10584
10602
  manager;
10585
10603
  lines = [];
10604
+ pipeline;
10586
10605
  constructor(lines) {
10587
- super();
10588
10606
  this.lines = lines;
10589
10607
  this.manager = WallGroupManager.fromByLines(lines);
10590
- this.init();
10591
- }
10592
- init() {
10593
- this.manager.forEach((group) => this.run(group.type, { lines: group.lines }));
10608
+ this.pipeline = new Pipeline();
10609
+ this.manager.forEach((group) => {
10610
+ const option = { lines: group.lines };
10611
+ this.pipeline.run(group.type, option);
10612
+ group.lines = option.lines;
10613
+ });
10594
10614
  }
10595
10615
  install(cad) {
10596
10616
  const wallGroupManager = this.manager, lines = this.lines;
@@ -10613,6 +10633,7 @@ class DxfDataPlugin extends Pipeline {
10613
10633
  cad.addGroupAndOffset([...untreatedWall], { type: "wall" });
10614
10634
  cad.addGroups(untreatedDoubleWallGroup, "doubleWall");
10615
10635
  cad.unionGroupAll("wall");
10636
+ cad.addGroup(cad.getAllLines(), "measurement");
10616
10637
  const offsetWidth = 0.05;
10617
10638
  cad.addGroupAndOffset(balconyRailingLines, {
10618
10639
  offsetHalfWidth: offsetWidth * 0.5,
@@ -11157,9 +11178,9 @@ class DoubleWallHelper {
11157
11178
  quadtree.insert(line);
11158
11179
  lines.push(line);
11159
11180
  });
11160
- lines = lineSegmentClipping(lines, 1e-9);
11161
11181
  quadtree.clear();
11162
11182
  lines.push(...otherLines);
11183
+ lines = lineSegmentClipping(lines, 1e-9);
11163
11184
  PointUtils.adsorb(lines.flatMap((line) => line.points), 1e-4);
11164
11185
  return lines.filter((line) => line.length() > 1e-9);
11165
11186
  }
@@ -11340,7 +11361,8 @@ function correction(lines, targettLine, option) {
11340
11361
  new WallInsertObject(newLines).recomputed().merge();
11341
11362
  newLines.push(...otherLines);
11342
11363
  newLines = removeDangline(newLines, 0.15, true);
11343
- return newLines.filter((line) => line.length() > 1e-9);
11364
+ newLines = newLines.filter((line) => line.length() > 1e-9);
11365
+ return newLines;
11344
11366
  }
11345
11367
  function axisAlignCorr(lines, option, verticalReferenceLine) {
11346
11368
  verticalReferenceLine = verticalReferenceLine ?? LineSegmentUtils.findDominantDirectionLine(lines.filter((line) => !line.userData.isDoor));
@@ -71,20 +71,7 @@ export declare class Dxf<TEventMap extends {} = {}> extends Component<{
71
71
  downloadOriginalData(filename: string): Promise<void>;
72
72
  /** 获取绘制数据
73
73
  */
74
- toDrawData(unit?: Unit): {
75
- unit: Unit;
76
- lines: [number, number, number, number, string][];
77
- lines2: [number, number, number, number, string][];
78
- arcs: [number, number, number, number, number, string][];
79
- texts: [string, number, number, string][];
80
- center: {
81
- x: number;
82
- y: number;
83
- };
84
- width: number;
85
- height: number;
86
- scale: number;
87
- } | undefined;
74
+ toDrawData(unit?: Unit): import('../utils/CAD/drawData').DrawData | undefined;
88
75
  /** 获取 dxf 图片 二进制对象
89
76
  * @param type
90
77
  */
@@ -169,12 +169,12 @@ export declare class CommandFlowComponent<TEventMap extends {} = {}> extends Com
169
169
  }): {
170
170
  readonly ended: boolean;
171
171
  end: () => void;
172
- next: (mode_: "all" | "point" | "line" | "empty" | "line_point" | "line_empty" | "point_empty" | "null") => Promise<{
172
+ next: (mode_: "all" | "line" | "point" | "empty" | "line_point" | "line_empty" | "point_empty" | "null") => Promise<{
173
173
  point: Point;
174
174
  line?: LineSegment;
175
175
  } | null>;
176
176
  setBaseLine(line: LineSegment<Record<string, any>> | null, point: Point | null): void;
177
- points(mode_: "all" | "point" | "line" | "empty" | "line_point" | "line_empty" | "point_empty" | "null"): {
177
+ points(mode_: "all" | "line" | "point" | "empty" | "line_point" | "line_empty" | "point_empty" | "null"): {
178
178
  next(): Promise<{
179
179
  value: {
180
180
  point: Point;
@@ -190,15 +190,15 @@ export declare class CommandFlowComponent<TEventMap extends {} = {}> extends Com
190
190
  awaitEach(callBack: (result: {
191
191
  point: Point<Record<string, any>>;
192
192
  line?: LineSegment;
193
- } | null) => void, mode_?: "all" | "point" | "line" | "empty" | "line_point" | "line_empty" | "point_empty" | "null"): Promise<{
193
+ } | null) => void, mode_?: "all" | "line" | "point" | "empty" | "line_point" | "line_empty" | "point_empty" | "null"): Promise<{
194
194
  readonly ended: boolean;
195
195
  end: () => void;
196
- next: (mode_: "all" | "point" | "line" | "empty" | "line_point" | "line_empty" | "point_empty" | "null") => Promise<{
196
+ next: (mode_: "all" | "line" | "point" | "empty" | "line_point" | "line_empty" | "point_empty" | "null") => Promise<{
197
197
  point: Point;
198
198
  line?: LineSegment;
199
199
  } | null>;
200
200
  setBaseLine(line: LineSegment<Record<string, any>> | null, point: Point | null): void;
201
- points(mode_: "all" | "point" | "line" | "empty" | "line_point" | "line_empty" | "point_empty" | "null"): {
201
+ points(mode_: "all" | "line" | "point" | "empty" | "line_point" | "line_empty" | "point_empty" | "null"): {
202
202
  next(): Promise<{
203
203
  value: {
204
204
  point: Point;
@@ -214,7 +214,7 @@ export declare class CommandFlowComponent<TEventMap extends {} = {}> extends Com
214
214
  awaitEach(callBack: (result: {
215
215
  point: Point<Record<string, any>>;
216
216
  line?: LineSegment;
217
- } | null) => void, mode_?: "all" | "point" | "line" | "empty" | "line_point" | "line_empty" | "point_empty" | "null"): Promise</*elided*/ any>;
217
+ } | null) => void, mode_?: "all" | "line" | "point" | "empty" | "line_point" | "line_empty" | "point_empty" | "null"): Promise</*elided*/ any>;
218
218
  }>;
219
219
  };
220
220
  /**
@@ -103,19 +103,6 @@ export type OriginalDataItem = {
103
103
  * [开始点, 结束点, 相交点, 是否是门, 索引]
104
104
  */
105
105
  export type DataItem = [Point, Point, number[], boolean, number];
106
- export type DrawData = {
107
- unit: Unit;
108
- line: [number, number, number, number, string][];
109
- arc: [number, number, number, number, number, string][];
110
- dimensionLine: number[][];
111
- center: {
112
- x: number;
113
- y: number;
114
- };
115
- width: number;
116
- height: number;
117
- scale: number;
118
- };
119
106
  export type FittingMethodType = "average" | "max";
120
107
  export type SetDataOption = {
121
108
  /**
@@ -190,6 +177,11 @@ export type ItemInfo = {
190
177
  y: number;
191
178
  z: number;
192
179
  }[];
180
+ quadContour?: {
181
+ x: number;
182
+ y: number;
183
+ z: number;
184
+ }[];
193
185
  direction: {
194
186
  x: number;
195
187
  y: number;
@@ -0,0 +1,43 @@
1
+ import { Unit } from '../../type';
2
+ import { CAD } from '.';
3
+ export type DrawData = {
4
+ unit: Unit;
5
+ lines: [number, number, number, number, string][];
6
+ lines2: [number, number, number, number, string][];
7
+ arcs: [number, number, number, number, number, string][];
8
+ texts: [string, number, number, string][];
9
+ center: {
10
+ x: number;
11
+ y: number;
12
+ };
13
+ width: number;
14
+ height: number;
15
+ scale: number;
16
+ };
17
+ export declare const units: {
18
+ Unitless: number;
19
+ Inches: number;
20
+ Feet: number;
21
+ Miles: number;
22
+ Millimeters: number;
23
+ Centimeters: number;
24
+ Meters: number;
25
+ Kilometers: number;
26
+ Microinches: number;
27
+ Mils: number;
28
+ Yards: number;
29
+ Angstroms: number;
30
+ Nanometers: number;
31
+ Microns: number;
32
+ Decimeters: number;
33
+ Decameters: number;
34
+ Hectometers: number;
35
+ Gigameters: number;
36
+ "Astronomical units": number;
37
+ "Light years": number;
38
+ Parsecs: number;
39
+ };
40
+ /**
41
+ * 转为绘制数据
42
+ */
43
+ export declare function toDrawData(this: CAD, unit?: Unit): DrawData;
@@ -0,0 +1,2 @@
1
+ import { DrawData } from './drawData';
2
+ export declare function toDxfImageBlob(data: DrawData, type?: string, background?: string): Promise<any>;
@@ -0,0 +1,3 @@
1
+ import { Unit } from '../../type';
2
+ import { DrawData } from './drawData';
3
+ export declare function drawDxfString(data: DrawData, unit?: Unit): string;
@@ -1,8 +1,9 @@
1
- import { LineSegment } from '../../utils/algorithms/LineSegment';
2
- import { LineUserData, Unit } from '../type';
3
- import { Point } from '../../utils/algorithms/Point';
4
- import { WallGroupManager } from './WallGroupManager';
5
- import { Pipeline } from '../../utils/algorithms/Pipeline';
1
+ import { LineSegment } from '../../../utils/algorithms/LineSegment';
2
+ import { LineUserData, Unit } from '../../type';
3
+ import { SetMap } from '../../../utils/algorithms/Map';
4
+ import { Point } from '../../../utils/algorithms/Point';
5
+ import { WallGroupManager } from '../WallGroupManager';
6
+ import { Pipeline } from '../../../utils/algorithms/Pipeline';
6
7
  type LineSegmentType = LineSegment<LineUserData>;
7
8
  type JoinType = "jtMiter" | "jtSquare" | "jtRound";
8
9
  type EndType = "etOpenSquare" | "etOpenButt" | "etOpenRound";
@@ -26,6 +27,7 @@ export type CADDrawHandler = {
26
27
  drawArc(pos: Point, radius: number, startAngle: number, endAngle: number): void;
27
28
  drawDottedLine(p1: Point, p2: Point, dash?: number, gap?: number): void;
28
29
  drawRulerLine(p1: Point, p2: Point): void;
30
+ drawText(str: string, p: Point): void;
29
31
  group: Group;
30
32
  setColor: (color: string) => void;
31
33
  }) => void;
@@ -51,7 +53,7 @@ declare class Group {
51
53
  */
52
54
  export declare class CAD {
53
55
  groups: Group[];
54
- private _drawHandlerMap;
56
+ _drawHandlerMap: SetMap<string, CADDrawHandler>;
55
57
  needUpdate: boolean;
56
58
  getAllLines(): LineSegmentType[];
57
59
  /** 添加组
@@ -98,8 +100,8 @@ export declare class CAD {
98
100
  /**
99
101
  * 转为绘制数据
100
102
  */
101
- private _cachedDrawDataMap;
102
- toDrawData(unit?: Unit): DrawData;
103
+ _cachedDrawDataMap: Map<string, DrawData>;
104
+ toDrawData(unit?: Unit): import('./drawData').DrawData;
103
105
  /** 转为图片
104
106
  * @param type
105
107
  */
@@ -157,11 +159,11 @@ type DataOption = {
157
159
  };
158
160
  /** dxf 数据处理插件
159
161
  */
160
- export declare class DxfDataPlugin extends Pipeline<DataOption> implements ICADPlugin {
162
+ export declare class DxfDataPlugin implements ICADPlugin {
161
163
  manager: WallGroupManager;
162
164
  lines: LineSegment<LineUserData>[];
165
+ pipeline: Pipeline<DataOption>;
163
166
  constructor(lines: LineSegment<LineUserData>[]);
164
- init(): void;
165
167
  install(cad: CAD): void;
166
168
  }
167
169
  export {};
@@ -5,4 +5,4 @@ import { LineUserData } from '../type';
5
5
  * @param minLen
6
6
  * @returns
7
7
  */
8
- export declare function lineSegmentClipping(lines: LineSegment<LineUserData>[], minLen?: number, dedup?: boolean): LineSegment<Record<string, any>>[];
8
+ export declare function lineSegmentClipping(lines: LineSegment<LineUserData>[], minLen?: number, dedup?: boolean): LineSegment<Record<string, any>>[] | LineSegment<LineUserData>[];
@@ -4,16 +4,18 @@ import { Rectangle } from './Rectangle';
4
4
  * 非轴对称线段
5
5
  */
6
6
  export declare class LineSegment<T = Record<string, any>> {
7
- #private;
8
7
  static get LINE_SYMBOL(): symbol;
9
8
  points: Point[];
10
9
  userData: T;
11
10
  currentData: Record<string | number | symbol, any>;
12
11
  uuid: string;
12
+ private _length;
13
13
  get len(): number;
14
14
  get start(): Point<Record<string, any>>;
15
15
  get end(): Point<Record<string, any>>;
16
+ _center: Point<Record<string, any>>;
16
17
  get center(): Point<Record<string, any>>;
18
+ _direction: Point<Record<string, any>>;
17
19
  constructor(p1?: Point, p2?: Point);
18
20
  private _initLenListener;
19
21
  set(p1: Point, p2: Point): this;
@@ -41,25 +43,25 @@ export declare class LineSegment<T = Record<string, any>> {
41
43
  * @param line
42
44
  * @returns
43
45
  */
44
- isSameEndpoint(line: LineSegment): boolean;
46
+ isSameEndpoint(line: LineSegment, eps?: number): boolean;
45
47
  /**
46
48
  * 相同端点是否为开始
47
49
  * @param line
48
50
  * @returns
49
51
  */
50
- isSameEndpointAsStart(line: LineSegment): boolean;
52
+ isSameEndpointAsStart(line: LineSegment, eps?: number): boolean;
51
53
  /**
52
54
  * 相同端点是否为结束
53
55
  * @param line
54
56
  * @returns
55
57
  */
56
- isSameEndpointAsEnd(line: LineSegment): boolean;
58
+ isSameEndpointAsEnd(line: LineSegment, eps?: number): boolean;
57
59
  /**
58
60
  * 获取共线点
59
61
  * @param line
60
62
  * @returns
61
63
  */
62
- getSameEndpoint(line: LineSegment): Point<Record<string, any>>[] | null;
64
+ getSameEndpoint(line: LineSegment, eps?: number): Point<Record<string, any>>[] | null;
63
65
  /**
64
66
  * 判断一个点是否在当前线段上(包含端点)
65
67
  * @param point 要判断的点
@@ -113,6 +113,7 @@ export declare class LineSegmentUtils {
113
113
  * @returns
114
114
  */
115
115
  static flatPoints(lines: LineSegment[] | LineSegment): any[];
116
+ static resolveIntersection<T>(lines: LineSegment[], onClip?: (target: LineSegment<T>, newLines: LineSegment<T>[]) => void): LineSegment<T>[];
116
117
  /** 对线段组统计,找到主导方向线
117
118
  * @param lineSegments
118
119
  * @returns
@@ -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
@@ -85,4 +85,5 @@ export declare class Quadtree<T = any> {
85
85
  * @returns
86
86
  */
87
87
  boundsToArray(array?: number[], colors?: number[], recursion?: boolean): number[];
88
+ static from(lines: LineSegment[]): Quadtree<any>;
88
89
  }