build-dxf 0.0.20 → 0.0.21

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.
Files changed (41) hide show
  1. package/README.md +3 -0
  2. package/package.json +6 -4
  3. package/src/build.d.ts +6 -0
  4. package/src/build.js +1404 -1915
  5. package/src/index.css +1 -641
  6. package/src/index.js +7 -7
  7. package/src/index2.js +327 -528
  8. package/src/index3.js +1951 -1714
  9. package/src/selectLocalFile.js +1960 -3145
  10. package/src/utils/CommandManager/CommandFlow.d.ts +17 -0
  11. package/src/utils/CommandManager/CommandManager.d.ts +23 -0
  12. package/src/utils/DxfSystem/components/AngleCorrectionDxf.d.ts +10 -0
  13. package/src/utils/DxfSystem/components/Dxf.d.ts +36 -5
  14. package/src/utils/DxfSystem/components/LineAnalysis.d.ts +3 -1
  15. package/src/utils/DxfSystem/index.d.ts +2 -0
  16. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/ClippingLine.d.ts +45 -0
  17. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/CommandFlowComponent.d.ts +4 -1
  18. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/ConnectionLine.d.ts +33 -0
  19. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/Default.d.ts +0 -20
  20. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/DeleteSelectLine.d.ts +28 -0
  21. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/DeleteSelectWindow.d.ts +33 -0
  22. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/DrawDoorLine.d.ts +22 -4
  23. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/DrawLine.d.ts +20 -4
  24. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/DrawWindow.d.ts +25 -2
  25. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/IntersectionConnectionLine.d.ts +33 -0
  26. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/MergeLine.d.ts +33 -0
  27. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/PointDrag.d.ts +14 -1
  28. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/SelectAll.d.ts +30 -0
  29. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/VerticalCorrection copy.d.ts +82 -0
  30. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/VerticalCorrection.d.ts +75 -0
  31. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/VerticalReferenceLine.d.ts +21 -0
  32. package/src/utils/DxfSystem/plugin/Editor/components/CommandFlow/ViewAngle.d.ts +21 -0
  33. package/src/utils/DxfSystem/plugin/Editor/components/Editor.d.ts +4 -1
  34. package/src/utils/DxfSystem/plugin/Editor/components/RenderManager.d.ts +4 -1
  35. package/src/utils/DxfSystem/plugin/Editor/components/index.d.ts +1 -0
  36. package/src/utils/DxfSystem/plugin/RenderPlugin/components/Renderer.d.ts +3 -0
  37. package/src/utils/PointVirtualGrid/index.d.ts +8 -0
  38. package/src/utils/Quadtree/LineSegment.d.ts +34 -1
  39. package/src/utils/Quadtree/Point.d.ts +9 -2
  40. package/src/utils/Quadtree/Quadtree.d.ts +1 -1
  41. package/src/utils/deepClone.d.ts +6 -0
package/src/build.js CHANGED
@@ -1,70 +1,55 @@
1
- import * as THREE from "three";
2
- import { EventDispatcher as EventDispatcher$1 } from "three";
3
- import ClipperLib from "clipper-lib";
4
- import Drawing from "dxf-writer";
5
- import { OBJExporter } from "three/examples/jsm/exporters/OBJExporter.js";
6
- import { GLTFExporter } from "three/examples/jsm/exporters/GLTFExporter.js";
7
- function uuid() {
8
- return "xxxx-xxxx-4xxx-yxxx-xxxx".replace(/[xy]/g, function(c) {
9
- var r = Math.random() * 16 | 0, v = c == "x" ? r : r & 3 | 8;
10
- return v.toString(16);
1
+ import * as M from "three";
2
+ import { EventDispatcher as tt } from "three";
3
+ import F from "clipper-lib";
4
+ import R from "dxf-writer";
5
+ import { OBJExporter as et } from "three/examples/jsm/exporters/OBJExporter.js";
6
+ import { GLTFExporter as nt } from "three/examples/jsm/exporters/GLTFExporter.js";
7
+ function N() {
8
+ return "xxxx-xxxx-4xxx-yxxx-xxxx".replace(/[xy]/g, function(g) {
9
+ var t = Math.random() * 16 | 0, e = g == "x" ? t : t & 3 | 8;
10
+ return e.toString(16);
11
11
  });
12
12
  }
13
- class EventDispatcher extends EventDispatcher$1 {
14
- uuid = uuid();
15
- addEventListener(type, listener, option) {
16
- const { once = false } = option ?? {};
17
- const callBack = (event) => {
18
- listener(event);
19
- once && canceCallBack();
20
- };
21
- const canceCallBack = () => this.removeEventListener(type, callBack);
22
- super.addEventListener(type, callBack);
23
- return canceCallBack;
13
+ class $ extends tt {
14
+ uuid = N();
15
+ addEventListener(t, e, n) {
16
+ const { once: i = !1 } = n ?? {}, s = (r) => {
17
+ e(r), i && o();
18
+ }, o = () => this.removeEventListener(t, s);
19
+ return super.addEventListener(t, s), o;
24
20
  }
25
21
  eventRecordStack = /* @__PURE__ */ new Map();
26
- addEventRecord(name, ...cancels) {
27
- if (!this.eventRecordStack.has(name)) this.eventRecordStack.set(name, []);
28
- cancels.forEach((cancel) => {
29
- this.eventRecordStack.get(name)?.push(cancel);
22
+ addEventRecord(t, ...e) {
23
+ this.eventRecordStack.has(t) || this.eventRecordStack.set(t, []), e.forEach((i) => {
24
+ this.eventRecordStack.get(t)?.push(i);
30
25
  });
31
- const add = (cancel) => {
32
- this.addEventRecord(name, cancel);
33
- return { add };
34
- };
35
- return { add };
26
+ const n = (i) => (this.addEventRecord(t, i), { add: n });
27
+ return { add: n };
36
28
  }
37
- canceEventRecord(name) {
38
- const list = this.eventRecordStack.get(name);
39
- if (list) {
40
- list.forEach((cancel) => cancel());
41
- this.eventRecordStack.delete(name);
42
- }
29
+ canceEventRecord(t) {
30
+ const e = this.eventRecordStack.get(t);
31
+ e && (e.forEach((n) => n()), this.eventRecordStack.delete(t));
43
32
  }
44
33
  }
45
- class Component extends EventDispatcher {
34
+ class q extends $ {
46
35
  parent;
47
- destroyed = false;
48
- constructor(...arg) {
49
- super();
50
- this.addEventListener("addFromParent", (e) => {
51
- this.parent = e.parent;
52
- this.onAddFromParent(e.parent);
53
- });
54
- this.addEventListener("removeFromParent", (e) => {
55
- this.parent = void 0;
56
- this.onRemoveFromParent(e.parent);
36
+ destroyed = !1;
37
+ constructor(...t) {
38
+ super(), this.addEventListener("addFromParent", (e) => {
39
+ this.parent = e.parent, this.onAddFromParent(e.parent);
40
+ }), this.addEventListener("removeFromParent", (e) => {
41
+ this.parent = void 0, this.onRemoveFromParent(e.parent);
57
42
  });
58
43
  }
59
- onAddFromParent(parent) {
44
+ onAddFromParent(t) {
60
45
  }
61
- onRemoveFromParent(parent) {
46
+ onRemoveFromParent(t) {
62
47
  }
63
48
  destroy() {
64
- this.destroyed = true;
49
+ this.destroyed = !0;
65
50
  }
66
51
  }
67
- class ComponentManager extends EventDispatcher {
52
+ class it extends $ {
68
53
  static EventType = {
69
54
  ADD_COMPONENT: "addComponent"
70
55
  };
@@ -73,75 +58,66 @@ class ComponentManager extends EventDispatcher {
73
58
  * 添加组件
74
59
  * @param component
75
60
  */
76
- addComponent(component) {
77
- if (component) {
78
- this.components.push(component);
79
- this.dispatchEvent({
80
- type: "addComponent",
81
- component
82
- });
83
- component.dispatchEvent({
84
- type: "addFromParent",
85
- parent: this
86
- });
87
- }
88
- return this;
61
+ addComponent(t) {
62
+ return t && (this.components.push(t), this.dispatchEvent({
63
+ type: "addComponent",
64
+ component: t
65
+ }), t.dispatchEvent({
66
+ type: "addFromParent",
67
+ parent: this
68
+ })), this;
89
69
  }
90
70
  /**
91
71
  * 移除组件
92
72
  * @param component
93
73
  */
94
- removeComponent(component) {
95
- if (component instanceof Component) {
96
- const index2 = this.components.indexOf(component);
97
- if (index2 > -1) {
98
- this.components.splice(index2, 1);
99
- this.dispatchEvent({
100
- type: "removeComponent",
101
- component
102
- });
103
- component.dispatchEvent({
104
- type: "removeFromParent",
105
- parent: this
106
- });
107
- }
74
+ removeComponent(t) {
75
+ if (t instanceof q) {
76
+ const e = this.components.indexOf(t);
77
+ e > -1 && (this.components.splice(e, 1), this.dispatchEvent({
78
+ type: "removeComponent",
79
+ component: t
80
+ }), t.dispatchEvent({
81
+ type: "removeFromParent",
82
+ parent: this
83
+ }));
108
84
  }
109
85
  }
110
86
  /**
111
87
  * 查找符合条件的第一个组件
112
88
  * @param callBack
113
89
  */
114
- findComponent(predicate) {
115
- for (let i = 0; i < this.components.length; i++) {
116
- const component = this.components[i];
117
- if (predicate(component, i)) return component;
90
+ findComponent(t) {
91
+ for (let e = 0; e < this.components.length; e++) {
92
+ const n = this.components[e];
93
+ if (t(n, e)) return n;
118
94
  }
119
95
  }
120
96
  /**
121
97
  * 查找所有符合条件的组件
122
98
  * @param callBack
123
99
  */
124
- findComponents(predicate) {
125
- return this.components.filter(predicate);
100
+ findComponents(t) {
101
+ return this.components.filter(t);
126
102
  }
127
103
  /**
128
104
  *
129
105
  * @param type
130
106
  */
131
- findComponentByType(type) {
132
- const component = this.findComponent((c) => c instanceof type);
133
- return component ? component : null;
107
+ findComponentByType(t) {
108
+ const e = this.findComponent((n) => n instanceof t);
109
+ return e || null;
134
110
  }
135
111
  /**
136
112
  *
137
113
  * @param type
138
114
  */
139
- findComponentByName(name) {
140
- const component = this.findComponent((c) => c.constructor.name === name);
141
- return component ? component : null;
115
+ findComponentByName(t) {
116
+ const e = this.findComponent((n) => n.constructor.name === t);
117
+ return e || null;
142
118
  }
143
119
  }
144
- class Point {
120
+ class p {
145
121
  x;
146
122
  y;
147
123
  get X() {
@@ -156,39 +132,32 @@ class Point {
156
132
  * @param x
157
133
  * @param y
158
134
  */
159
- constructor(x = 0, y = 0) {
160
- this.x = x;
161
- this.y = y;
135
+ constructor(t = 0, e = 0) {
136
+ this.x = t, this.y = e;
162
137
  }
163
- set(x, y) {
164
- this.x = x;
165
- this.y = y;
166
- return this;
138
+ set(t, e) {
139
+ return this.x = t, this.y = e, this;
167
140
  }
168
- setX(x) {
169
- this.x = x;
170
- return this;
141
+ setX(t) {
142
+ return this.x = t, this;
171
143
  }
172
- setY(y) {
173
- this.y = y;
174
- return this;
144
+ setY(t) {
145
+ return this.y = t, this;
175
146
  }
176
147
  /**
177
148
  *
178
149
  * @param point
179
150
  * @returns
180
151
  */
181
- equal(point) {
182
- return point.x === this.x && point.y === this.y;
152
+ equal(t) {
153
+ return t.x === this.x && t.y === this.y;
183
154
  }
184
155
  /**
185
156
  *
186
157
  * @param arr
187
158
  */
188
- setByArray(arr) {
189
- this.x = arr[0];
190
- this.y = arr[1];
191
- return this;
159
+ setByArray(t) {
160
+ return this.x = t[0], this.y = t[1], this;
192
161
  }
193
162
  /**
194
163
  *
@@ -200,25 +169,19 @@ class Point {
200
169
  * multiplyScalar
201
170
  * @param scalar
202
171
  */
203
- mutiplyScalar(scalar) {
204
- this.x *= scalar;
205
- this.y *= scalar;
206
- return this;
172
+ mutiplyScalar(t) {
173
+ return this.x *= t, this.y *= t, this;
207
174
  }
208
- multiplyScalar(scalar) {
209
- this.x *= scalar;
210
- this.y *= scalar;
211
- return this;
175
+ multiplyScalar(t) {
176
+ return this.x *= t, this.y *= t, this;
212
177
  }
213
178
  /**
214
179
  *
215
180
  * @param scalar
216
181
  * @returns
217
182
  */
218
- divisionScalar(scalar) {
219
- this.x /= scalar;
220
- this.y /= scalar;
221
- return this;
183
+ divisionScalar(t) {
184
+ return this.x /= t, this.y /= t, this;
222
185
  }
223
186
  /**
224
187
  * 减法
@@ -226,10 +189,8 @@ class Point {
226
189
  * @param point
227
190
  * @returns
228
191
  */
229
- division(point) {
230
- this.x -= point.x;
231
- this.y -= point.y;
232
- return this;
192
+ division(t) {
193
+ return this.x -= t.x, this.y -= t.y, this;
233
194
  }
234
195
  /**
235
196
  * 加法
@@ -237,19 +198,24 @@ class Point {
237
198
  * @param point
238
199
  * @returns
239
200
  */
240
- add(point) {
241
- this.x += point.x;
242
- this.y += point.y;
243
- return this;
201
+ add(t) {
202
+ return this.x += t.x, this.y += t.y, this;
203
+ }
204
+ /**
205
+ * 绕point旋转angle
206
+ * @param point
207
+ * @param angle 旋转角度,单位为弧度
208
+ */
209
+ rotate(t, e) {
210
+ const n = this.x - t.x, i = this.y - t.y, s = Math.cos(e), o = Math.sin(e), r = n * s - i * o, a = n * o + i * s;
211
+ return this.x = r + t.x, this.y = a + t.y, this;
244
212
  }
245
213
  /**
246
214
  * 保留小数位数
247
215
  * @param count
248
216
  */
249
- fixed(count) {
250
- this.x = Number(this.x.toFixed(count));
251
- this.y = Number(this.y.toFixed(count));
252
- return this;
217
+ fixed(t) {
218
+ return this.x = Number(this.x.toFixed(t)), this.y = Number(this.y.toFixed(t)), this;
253
219
  }
254
220
  /**
255
221
  * 归一化
@@ -257,11 +223,8 @@ class Point {
257
223
  * @returns
258
224
  */
259
225
  normalize() {
260
- const length = Math.sqrt(this.x * this.x + this.y * this.y);
261
- if (length === 0) return this;
262
- this.x /= length;
263
- this.y /= length;
264
- return this;
226
+ const t = Math.sqrt(this.x * this.x + this.y * this.y);
227
+ return t === 0 ? this : (this.x /= t, this.y /= t, this);
265
228
  }
266
229
  /**
267
230
  * 获取单位法向量
@@ -269,13 +232,9 @@ class Point {
269
232
  * @param point
270
233
  * @returns
271
234
  */
272
- normal(point) {
273
- const dx = this.x - point.x;
274
- const dy = this.y - point.y;
275
- const length = Math.sqrt(dx * dx + dy * dy);
276
- const nx = -dy / length;
277
- const ny = dx / length;
278
- return new Point(nx, ny);
235
+ normal(t) {
236
+ const e = this.x - t.x, n = this.y - t.y, i = Math.sqrt(e * e + n * n), s = -n / i, o = e / i;
237
+ return new p(s, o);
279
238
  }
280
239
  /**
281
240
  * 获取由传入的点到该点的单位方向向量
@@ -283,12 +242,9 @@ class Point {
283
242
  * @param point
284
243
  * @returns
285
244
  */
286
- direction(point) {
287
- const dx = this.x - point.x;
288
- const dy = this.y - point.y;
289
- const length = Math.sqrt(dx * dx + dy * dy);
290
- if (length === 0) return new Point(0, 0);
291
- return new Point(dx / length, dy / length);
245
+ direction(t) {
246
+ const e = this.x - t.x, n = this.y - t.y, i = Math.sqrt(e * e + n * n);
247
+ return i === 0 ? new p(0, 0) : new p(e / i, n / i);
292
248
  }
293
249
  /**
294
250
  * 计算模长
@@ -302,8 +258,8 @@ class Point {
302
258
  * @param point
303
259
  * @returns
304
260
  */
305
- dot(point) {
306
- return this.x * point.x + this.y * point.y;
261
+ dot(t) {
262
+ return this.x * t.x + this.y * t.y;
307
263
  }
308
264
  /** 求两个点叉积
309
265
  * @description 如果叉积大于 0,a 到 b 为逆时针方向。
@@ -311,8 +267,8 @@ class Point {
311
267
  * @param point
312
268
  * @returns
313
269
  */
314
- cross(point) {
315
- return this.x * point.y - this.y * this.x;
270
+ cross(t) {
271
+ return this.x * t.y - this.y * this.x;
316
272
  }
317
273
  /** 计算两个向量夹角
318
274
  * @description 公式:a · b = |a| × |b| × cosθ
@@ -320,34 +276,25 @@ class Point {
320
276
  * @param point
321
277
  * @returns
322
278
  */
323
- angleBetween(point, type = "radian", angle = "180") {
324
- const dotProduct = this.dot(point);
325
- const magnitude1 = this.magnitude();
326
- const magnitude2 = point.magnitude();
327
- if (magnitude1 === 0 || magnitude2 === 0) return 0;
328
- const cosTheta = dotProduct / (magnitude1 * magnitude2);
329
- const clampedCosTheta = Math.max(-1, Math.min(1, cosTheta));
330
- if (type === "radian") return Math.acos(clampedCosTheta);
331
- if (type === "cos") return clampedCosTheta;
332
- if (angle === "180" || this.cross(point) < 0) return Math.acos(clampedCosTheta) / (Math.PI / 180);
333
- return 360 - Math.acos(clampedCosTheta) / (Math.PI / 180);
279
+ angleBetween(t, e = "radian", n = "180") {
280
+ const i = this.dot(t), s = this.magnitude(), o = t.magnitude();
281
+ if (s === 0 || o === 0) return 0;
282
+ const r = i / (s * o), a = Math.max(-1, Math.min(1, r));
283
+ return e === "radian" ? Math.acos(a) : e === "cos" ? a : n === "180" || this.cross(t) < 0 ? Math.acos(a) / (Math.PI / 180) : 360 - Math.acos(a) / (Math.PI / 180);
334
284
  }
335
285
  /** 获取向量长度
336
286
  */
337
287
  length() {
338
- const magnitude = Math.sqrt(this.x * this.x + this.y * this.y);
339
- if (Math.abs(magnitude - Math.round(magnitude)) < 1e-9) {
340
- return Math.round(magnitude);
341
- }
342
- return magnitude;
288
+ const t = Math.sqrt(this.x * this.x + this.y * this.y);
289
+ return Math.abs(t - Math.round(t)) < 1e-9 ? Math.round(t) : t;
343
290
  }
344
291
  /**
345
292
  * 获取两个点长度
346
293
  * @param point
347
294
  */
348
- distance(point) {
295
+ distance(t) {
349
296
  return Math.sqrt(
350
- (this.x - point.x) * (this.x - point.x) + (this.y - point.y) * (this.y - point.y)
297
+ (this.x - t.x) * (this.x - t.x) + (this.y - t.y) * (this.y - t.y)
351
298
  );
352
299
  }
353
300
  /**
@@ -355,47 +302,40 @@ class Point {
355
302
  * @returns
356
303
  */
357
304
  clone() {
358
- return new Point(this.x, this.y);
305
+ return new p(this.x, this.y);
359
306
  }
360
307
  /**
361
308
  * 克隆
362
309
  * @returns
363
310
  */
364
- copy(p) {
365
- this.x = p.x ?? 0;
366
- this.y = p.y ?? 0;
311
+ copy(t) {
312
+ return this.x = t.x ?? 0, this.y = t.y ?? 0, this;
367
313
  }
368
- toJson() {
314
+ toJson(t = 0) {
369
315
  return {
370
316
  x: this.x,
371
- y: this.y
317
+ y: this.y,
318
+ z: t
372
319
  };
373
320
  }
374
- static from(arr) {
375
- if (Array.isArray(arr)) {
376
- return new Point(arr[0], arr[1]);
377
- } else if ("x" in arr && "y" in arr) {
378
- return new Point(arr.x, arr.y);
379
- } else if ("X" in arr && "Y" in arr) {
380
- return new Point(arr.X, arr.Y);
381
- }
382
- return this.zero();
321
+ static from(t) {
322
+ return Array.isArray(t) ? new p(t[0], t[1]) : "x" in t && "y" in t ? new p(t.x, t.y) : "X" in t && "Y" in t ? new p(t.X, t.Y) : this.zero();
383
323
  }
384
324
  static zero() {
385
- return new Point(0, 0);
325
+ return new p(0, 0);
386
326
  }
387
327
  }
388
- class Box2 {
328
+ class v {
389
329
  minX = 0;
390
330
  maxX = 0;
391
331
  minY = 0;
392
332
  maxY = 0;
393
333
  get points() {
394
334
  return [
395
- new Point(this.minX, this.minY),
396
- new Point(this.maxX, this.minY),
397
- new Point(this.maxX, this.maxY),
398
- new Point(this.minX, this.maxY)
335
+ new p(this.minX, this.minY),
336
+ new p(this.maxX, this.minY),
337
+ new p(this.maxX, this.maxY),
338
+ new p(this.minX, this.maxY)
399
339
  ];
400
340
  }
401
341
  get width() {
@@ -405,163 +345,122 @@ class Box2 {
405
345
  return this.maxY - this.minY;
406
346
  }
407
347
  get center() {
408
- return new Point(
348
+ return new p(
409
349
  this.minX + (this.maxX - this.minX) * 0.5,
410
350
  this.minY + (this.maxY - this.minY) * 0.5
411
351
  );
412
352
  }
413
- constructor(minX = 0, maxX = 0, minY = 0, maxY = 0) {
414
- this.minX = minX;
415
- this.maxX = maxX;
416
- this.minY = minY;
417
- this.maxY = maxY;
353
+ constructor(t = 0, e = 0, n = 0, i = 0) {
354
+ this.minX = t, this.maxX = e, this.minY = n, this.maxY = i;
418
355
  }
419
356
  /**
420
357
  *
421
358
  * @param z
422
359
  * @returns
423
360
  */
424
- getPaths3D(z = 0) {
425
- const points = this.points, list = [];
426
- points.forEach((p, i) => {
427
- const nextP = points[(i + 1) % points.length];
428
- list.push(p.x, p.y, z);
429
- list.push(nextP.x, nextP.y, z);
430
- });
431
- return list;
361
+ getPaths3D(t = 0) {
362
+ const e = this.points, n = [];
363
+ return e.forEach((i, s) => {
364
+ const o = e[(s + 1) % e.length];
365
+ n.push(i.x, i.y, t), n.push(o.x, o.y, t);
366
+ }), n;
432
367
  }
433
368
  /**
434
369
  * 判断线段是与包围盒相交
435
370
  * @description Liang-Barsky算法的变种
436
371
  * @param line
437
372
  */
438
- intersectLineSegment(line) {
439
- const p1 = line.points[0];
440
- const p2 = line.points[1];
441
- const dx = p2.x - p1.x;
442
- const dy = p2.y - p1.y;
443
- if (dx === 0 && dy === 0) {
444
- return this.minX <= p1.x && p1.x <= this.maxX && this.minY <= p1.y && p1.y <= this.maxY;
445
- }
446
- let tNear = Number.NEGATIVE_INFINITY;
447
- let tFar = Number.POSITIVE_INFINITY;
448
- if (dx !== 0) {
449
- const tx1 = (this.minX - p1.x) / dx;
450
- const tx2 = (this.maxX - p1.x) / dx;
451
- tNear = Math.max(tNear, Math.min(tx1, tx2));
452
- tFar = Math.min(tFar, Math.max(tx1, tx2));
453
- } else if (p1.x < this.minX || p1.x > this.maxX) {
454
- return false;
455
- }
456
- if (dy !== 0) {
457
- const ty1 = (this.minY - p1.y) / dy;
458
- const ty2 = (this.maxY - p1.y) / dy;
459
- tNear = Math.max(tNear, Math.min(ty1, ty2));
460
- tFar = Math.min(tFar, Math.max(ty1, ty2));
461
- } else if (p1.y < this.minY || p1.y > this.maxY) {
462
- return false;
463
- }
464
- return tNear <= tFar && tNear <= 1 && tFar >= 0;
373
+ intersectLineSegment(t) {
374
+ const e = t.points[0], n = t.points[1], i = n.x - e.x, s = n.y - e.y;
375
+ if (i === 0 && s === 0)
376
+ return this.minX <= e.x && e.x <= this.maxX && this.minY <= e.y && e.y <= this.maxY;
377
+ let o = Number.NEGATIVE_INFINITY, r = Number.POSITIVE_INFINITY;
378
+ if (i !== 0) {
379
+ const a = (this.minX - e.x) / i, c = (this.maxX - e.x) / i;
380
+ o = Math.max(o, Math.min(a, c)), r = Math.min(r, Math.max(a, c));
381
+ } else if (e.x < this.minX || e.x > this.maxX)
382
+ return !1;
383
+ if (s !== 0) {
384
+ const a = (this.minY - e.y) / s, c = (this.maxY - e.y) / s;
385
+ o = Math.max(o, Math.min(a, c)), r = Math.min(r, Math.max(a, c));
386
+ } else if (e.y < this.minY || e.y > this.maxY)
387
+ return !1;
388
+ return o <= r && o <= 1 && r >= 0;
465
389
  }
466
390
  /**
467
391
  * 判断线段是在包围盒内
468
392
  * @param line
469
393
  */
470
- containsLineSegment(line) {
471
- const [p1, p2] = line.points;
472
- return this.minX <= p1.x && p1.x <= this.maxX && this.minY <= p1.y && p1.y <= this.maxY && this.minX <= p2.x && p2.x <= this.maxX && this.minY <= p2.y && p2.y <= this.maxY;
394
+ containsLineSegment(t) {
395
+ const [e, n] = t.points;
396
+ return this.minX <= e.x && e.x <= this.maxX && this.minY <= e.y && e.y <= this.maxY && this.minX <= n.x && n.x <= this.maxX && this.minY <= n.y && n.y <= this.maxY;
473
397
  }
474
398
  /**
475
399
  * 判断矩形与包围盒相交
476
400
  * @param rectangle
477
401
  */
478
- intersectRectangle(rectangle) {
479
- const isPointInBox = (p) => this.minX <= p.x && p.x <= this.maxX && this.minY <= p.y && p.y <= this.maxY;
480
- const isPointInRect = (point) => {
481
- let sign = 0;
482
- for (let i = 0; i < 4; i++) {
483
- const p1 = rectangle.points[i];
484
- const p2 = rectangle.points[(i + 1) % 4];
485
- const edge = { x: p2.x - p1.x, y: p2.y - p1.y };
486
- const toPoint = { x: point.x - p1.x, y: point.y - p1.y };
487
- const cross = edge.x * toPoint.y - edge.y * toPoint.x;
488
- if (cross === 0) {
489
- const t = edge.x !== 0 ? (point.x - p1.x) / edge.x : (point.y - p1.y) / edge.y;
490
- if (t >= 0 && t <= 1) return true;
402
+ intersectRectangle(t) {
403
+ const e = (o) => this.minX <= o.x && o.x <= this.maxX && this.minY <= o.y && o.y <= this.maxY, n = (o) => {
404
+ let r = 0;
405
+ for (let a = 0; a < 4; a++) {
406
+ const c = t.points[a], h = t.points[(a + 1) % 4], l = { x: h.x - c.x, y: h.y - c.y }, d = { x: o.x - c.x, y: o.y - c.y }, f = l.x * d.y - l.y * d.x;
407
+ if (f === 0) {
408
+ const m = l.x !== 0 ? (o.x - c.x) / l.x : (o.y - c.y) / l.y;
409
+ if (m >= 0 && m <= 1) return !0;
491
410
  } else {
492
- const currentSign = cross > 0 ? 1 : -1;
493
- if (sign === 0) sign = currentSign;
494
- if (sign !== currentSign) return false;
411
+ const m = f > 0 ? 1 : -1;
412
+ if (r === 0 && (r = m), r !== m) return !1;
495
413
  }
496
414
  }
497
- return true;
498
- };
499
- const doIntersect = (l1p1, l1p2, l2p1, l2p2) => {
500
- const orientation = (p, q, r) => {
501
- const val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
502
- if (val === 0) return 0;
503
- return val > 0 ? 1 : 2;
504
- };
505
- const onSegment = (p, q, r) => {
506
- return Math.min(p.x, r.x) <= q.x && q.x <= Math.max(p.x, r.x) && Math.min(p.y, r.y) <= q.y && q.y <= Math.max(p.y, r.y);
507
- };
508
- const o1 = orientation(l1p1, l1p2, l2p1);
509
- const o2 = orientation(l1p1, l1p2, l2p2);
510
- const o3 = orientation(l2p1, l2p2, l1p1);
511
- const o4 = orientation(l2p1, l2p2, l1p2);
512
- if (o1 !== o2 && o3 !== o4) return true;
513
- if (o1 === 0 && onSegment(l1p1, l2p1, l1p2)) return true;
514
- if (o2 === 0 && onSegment(l1p1, l2p2, l1p2)) return true;
515
- if (o3 === 0 && onSegment(l2p1, l1p1, l2p2)) return true;
516
- if (o4 === 0 && onSegment(l2p1, l1p2, l2p2)) return true;
517
- return false;
518
- };
519
- const boxPoints = this.points;
520
- for (let i = 0; i < 4; i++) {
521
- const bp1 = boxPoints[i];
522
- const bp2 = boxPoints[(i + 1) % 4];
523
- for (let j = 0; j < 4; j++) {
524
- const rp1 = rectangle.points[j];
525
- const rp2 = rectangle.points[(j + 1) % 4];
526
- if (doIntersect(bp1, bp2, rp1, rp2)) return true;
415
+ return !0;
416
+ }, i = (o, r, a, c) => {
417
+ const h = (u, x, w) => {
418
+ const S = (x.y - u.y) * (w.x - x.x) - (x.x - u.x) * (w.y - x.y);
419
+ return S === 0 ? 0 : S > 0 ? 1 : 2;
420
+ }, l = (u, x, w) => Math.min(u.x, w.x) <= x.x && x.x <= Math.max(u.x, w.x) && Math.min(u.y, w.y) <= x.y && x.y <= Math.max(u.y, w.y), d = h(o, r, a), f = h(o, r, c), m = h(a, c, o), y = h(a, c, r);
421
+ return !!(d !== f && m !== y || d === 0 && l(o, a, r) || f === 0 && l(o, c, r) || m === 0 && l(a, o, c) || y === 0 && l(a, r, c));
422
+ }, s = this.points;
423
+ for (let o = 0; o < 4; o++) {
424
+ const r = s[o], a = s[(o + 1) % 4];
425
+ for (let c = 0; c < 4; c++) {
426
+ const h = t.points[c], l = t.points[(c + 1) % 4];
427
+ if (i(r, a, h, l)) return !0;
527
428
  }
528
429
  }
529
- for (let p of rectangle.points) {
530
- if (isPointInBox(p)) return true;
531
- }
532
- for (let p of boxPoints) {
533
- if (isPointInRect(p)) return true;
534
- }
535
- return false;
430
+ for (let o of t.points)
431
+ if (e(o)) return !0;
432
+ for (let o of s)
433
+ if (n(o)) return !0;
434
+ return !1;
536
435
  }
537
436
  /**
538
437
  * 判断矩形是在包围盒内
539
438
  * @param rectangle
540
439
  */
541
- containsRectangle(rectangle) {
542
- return rectangle.points.every(
543
- (p) => this.minX <= p.x && p.x <= this.maxX && this.minY <= p.y && p.y <= this.maxY
440
+ containsRectangle(t) {
441
+ return t.points.every(
442
+ (e) => this.minX <= e.x && e.x <= this.maxX && this.minY <= e.y && e.y <= this.maxY
544
443
  );
545
444
  }
546
445
  /**
547
446
  * 判断包围盒与包围盒相交
548
447
  * @param box
549
448
  */
550
- intersectBox(box) {
551
- return !(this.maxX < box.minX || this.minX > box.maxX || this.maxY < box.minY || this.minY > box.maxY);
449
+ intersectBox(t) {
450
+ return !(this.maxX < t.minX || this.minX > t.maxX || this.maxY < t.minY || this.minY > t.maxY);
552
451
  }
553
452
  /**
554
453
  * 判断包围盒是在包围盒内
555
454
  * @param box
556
455
  */
557
- containsBox(box) {
558
- return this.minX <= box.minX && box.maxX <= this.maxX && this.minY <= box.minY && box.maxY <= this.maxY;
456
+ containsBox(t) {
457
+ return this.minX <= t.minX && t.maxX <= this.maxX && this.minY <= t.minY && t.maxY <= this.maxY;
559
458
  }
560
459
  /** 判断点是在包围盒内
561
460
  * @param point
562
461
  */
563
- containsPoint(point) {
564
- return point.x >= this.minX && point.x <= this.maxX && point.y >= this.minY && point.y <= this.maxY;
462
+ containsPoint(t) {
463
+ return t.x >= this.minX && t.x <= this.maxX && t.y >= this.minY && t.y <= this.maxY;
565
464
  }
566
465
  /**
567
466
  *
@@ -571,12 +470,8 @@ class Box2 {
571
470
  * @param maxY
572
471
  * @returns
573
472
  */
574
- set(minX, minY, maxX, maxY) {
575
- this.minX = minX;
576
- this.minY = minY;
577
- this.maxX = maxX;
578
- this.maxY = maxY;
579
- return this;
473
+ set(t, e, n, i) {
474
+ return this.minX = t, this.minY = e, this.maxX = n, this.maxY = i, this;
580
475
  }
581
476
  /**
582
477
  *
@@ -585,57 +480,46 @@ class Box2 {
585
480
  * @param mode
586
481
  * @returns
587
482
  */
588
- scaleSize(maxWidth, maxHeight, mode = "min") {
589
- const scaleX = maxWidth / this.width;
590
- const scaleY = maxHeight / this.height;
591
- return Math[mode](scaleX, scaleY);
483
+ scaleSize(t, e, n = "min") {
484
+ const i = t / this.width, s = e / this.height;
485
+ return Math[n](i, s);
592
486
  }
593
487
  /**
594
488
  *
595
489
  * @param scalar
596
490
  * @returns
597
491
  */
598
- multiplyScalar(scalar) {
599
- this.minX *= scalar;
600
- this.minY *= scalar;
601
- this.maxX *= scalar;
602
- this.maxY *= scalar;
603
- return this;
492
+ multiplyScalar(t) {
493
+ return this.minX *= t, this.minY *= t, this.maxX *= t, this.maxY *= t, this;
604
494
  }
605
- expansion(w) {
606
- this.minX -= w;
607
- this.minY -= w;
608
- this.maxX += w;
609
- this.maxY += w;
610
- return this;
495
+ expansion(t) {
496
+ return this.minX -= t, this.minY -= t, this.maxX += t, this.maxY += t, this;
611
497
  }
612
498
  /**
613
499
  *
614
500
  * @returns
615
501
  */
616
502
  clone() {
617
- return new Box2(this.minX, this.maxX, this.minY, this.maxY);
503
+ return new v(this.minX, this.maxX, this.minY, this.maxY);
618
504
  }
619
505
  /**
620
506
  *
621
507
  * @param points
622
508
  * @returns
623
509
  */
624
- static fromByPoints(...points) {
625
- const xList = [], yList = [];
626
- points.forEach((p) => {
627
- xList.push(p.x);
628
- yList.push(p.y);
629
- });
630
- return new Box2(
631
- Math.min(...xList),
632
- Math.max(...xList),
633
- Math.min(...yList),
634
- Math.max(...yList)
510
+ static fromByPoints(...t) {
511
+ const e = [], n = [];
512
+ return t.forEach((i) => {
513
+ e.push(i.x), n.push(i.y);
514
+ }), new v(
515
+ Math.min(...e),
516
+ Math.max(...e),
517
+ Math.min(...n),
518
+ Math.max(...n)
635
519
  );
636
520
  }
637
521
  }
638
- class Rectangle {
522
+ class O {
639
523
  points;
640
524
  get p0() {
641
525
  return this.points[0];
@@ -650,16 +534,15 @@ class Rectangle {
650
534
  return this.points[3];
651
535
  }
652
536
  get path() {
653
- return this.points.flatMap((p, i) => {
654
- const np = this.points[(i + 1) % this.points.length];
655
- return [p.x, p.y, 0, np.x, np.y, 0];
537
+ return this.points.flatMap((t, e) => {
538
+ const n = this.points[(e + 1) % this.points.length];
539
+ return [t.x, t.y, 0, n.x, n.y, 0];
656
540
  });
657
541
  }
658
- path2D(callback) {
659
- return this.points.flatMap((p, i) => {
660
- const np = this.points[(i + 1) % this.points.length];
661
- callback && callback(new Point(p.x, p.y), new Point(np.x, np.y));
662
- return [p.x, p.y, np.x, np.y];
542
+ path2D(t) {
543
+ return this.points.flatMap((e, n) => {
544
+ const i = this.points[(n + 1) % this.points.length];
545
+ return t && t(new p(e.x, e.y), new p(i.x, i.y)), [e.x, e.y, i.x, i.y];
663
546
  });
664
547
  }
665
548
  createGeometry() {
@@ -670,85 +553,58 @@ class Rectangle {
670
553
  this.p2,
671
554
  this.p0,
672
555
  this.p3
673
- ].flatMap((p) => [p.x, p.y, 0]);
556
+ ].flatMap((t) => [t.x, t.y, 0]);
674
557
  }
675
- constructor(points) {
676
- if (points.length !== 4) {
558
+ constructor(t) {
559
+ if (t.length !== 4)
677
560
  throw new Error("Rectangle must be defined by exactly 4 points");
678
- }
679
- this.points = points;
561
+ this.points = t;
680
562
  }
681
563
  /**
682
564
  * 判断线段是否与矩形相交
683
565
  * @param line 线段
684
566
  * @returns 是否与矩形相交
685
567
  */
686
- intersectLineSegment(line) {
687
- if (line.points.length !== 2) {
568
+ intersectLineSegment(t) {
569
+ if (t.points.length !== 2)
688
570
  throw new Error("LineSegment must have exactly 2 points");
689
- }
690
- const [p1, p2] = line.points;
691
- const doIntersect = (l1p1, l1p2, l2p1, l2p2) => {
692
- const orientation = (p, q, r) => {
693
- const val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
694
- if (val === 0) return 0;
695
- return val > 0 ? 1 : 2;
696
- };
697
- const onSegment = (p, q, r) => {
698
- return Math.min(p.x, r.x) <= q.x && q.x <= Math.max(p.x, r.x) && Math.min(p.y, r.y) <= q.y && q.y <= Math.max(p.y, r.y);
699
- };
700
- const o1 = orientation(l1p1, l1p2, l2p1);
701
- const o2 = orientation(l1p1, l1p2, l2p2);
702
- const o3 = orientation(l2p1, l2p2, l1p1);
703
- const o4 = orientation(l2p1, l2p2, l1p2);
704
- if (o1 !== o2 && o3 !== o4) return true;
705
- if (o1 === 0 && onSegment(l1p1, l2p1, l1p2)) return true;
706
- if (o2 === 0 && onSegment(l1p1, l2p2, l1p2)) return true;
707
- if (o3 === 0 && onSegment(l2p1, l1p1, l2p2)) return true;
708
- if (o4 === 0 && onSegment(l2p1, l1p2, l2p2)) return true;
709
- return false;
571
+ const [e, n] = t.points, i = (s, o, r, a) => {
572
+ const c = (y, u, x) => {
573
+ const w = (u.y - y.y) * (x.x - u.x) - (u.x - y.x) * (x.y - u.y);
574
+ return w === 0 ? 0 : w > 0 ? 1 : 2;
575
+ }, h = (y, u, x) => Math.min(y.x, x.x) <= u.x && u.x <= Math.max(y.x, x.x) && Math.min(y.y, x.y) <= u.y && u.y <= Math.max(y.y, x.y), l = c(s, o, r), d = c(s, o, a), f = c(r, a, s), m = c(r, a, o);
576
+ return !!(l !== d && f !== m || l === 0 && h(s, r, o) || d === 0 && h(s, a, o) || f === 0 && h(r, s, a) || m === 0 && h(r, o, a));
710
577
  };
711
- for (let i = 0; i < 4; i++) {
712
- const rectP1 = this.points[i];
713
- const rectP2 = this.points[(i + 1) % 4];
714
- if (doIntersect(p1, p2, rectP1, rectP2)) {
715
- return true;
716
- }
717
- }
718
- if (this.containsLineSegment(line)) {
719
- return true;
578
+ for (let s = 0; s < 4; s++) {
579
+ const o = this.points[s], r = this.points[(s + 1) % 4];
580
+ if (i(e, n, o, r))
581
+ return !0;
720
582
  }
721
- return false;
583
+ return !!this.containsLineSegment(t);
722
584
  }
723
585
  /**
724
586
  * 判断线段是否完全位于矩形内部
725
587
  * @param line 线段
726
588
  * @returns 是否完全在矩形内部
727
589
  */
728
- containsLineSegment(line) {
729
- if (line.points.length !== 2) {
590
+ containsLineSegment(t) {
591
+ if (t.points.length !== 2)
730
592
  throw new Error("LineSegment must have exactly 2 points");
731
- }
732
- const isPointInRectangle = (point) => {
733
- let sign = 0;
734
- for (let i = 0; i < 4; i++) {
735
- const p1 = this.points[i];
736
- const p2 = this.points[(i + 1) % 4];
737
- const edge = { x: p2.x - p1.x, y: p2.y - p1.y };
738
- const toPoint = { x: point.x - p1.x, y: point.y - p1.y };
739
- const cross = edge.x * toPoint.y - edge.y * toPoint.x;
740
- if (cross === 0) {
741
- const t = edge.x !== 0 ? (point.x - p1.x) / edge.x : (point.y - p1.y) / edge.y;
742
- if (t >= 0 && t <= 1) return true;
593
+ const e = (n) => {
594
+ let i = 0;
595
+ for (let s = 0; s < 4; s++) {
596
+ const o = this.points[s], r = this.points[(s + 1) % 4], a = { x: r.x - o.x, y: r.y - o.y }, c = { x: n.x - o.x, y: n.y - o.y }, h = a.x * c.y - a.y * c.x;
597
+ if (h === 0) {
598
+ const l = a.x !== 0 ? (n.x - o.x) / a.x : (n.y - o.y) / a.y;
599
+ if (l >= 0 && l <= 1) return !0;
743
600
  } else {
744
- const currentSign = cross > 0 ? 1 : -1;
745
- if (sign === 0) sign = currentSign;
746
- if (sign !== currentSign) return false;
601
+ const l = h > 0 ? 1 : -1;
602
+ if (i === 0 && (i = l), i !== l) return !1;
747
603
  }
748
604
  }
749
- return true;
605
+ return !0;
750
606
  };
751
- return isPointInRectangle(line.points[0]) && isPointInRectangle(line.points[1]);
607
+ return e(t.points[0]) && e(t.points[1]);
752
608
  }
753
609
  /**
754
610
  * 判断矩形是否与矩形相交
@@ -756,64 +612,53 @@ class Rectangle {
756
612
  * @param rectangle 矩形
757
613
  * @returns 是否与矩形相交
758
614
  */
759
- intersectRectangle(rectangle) {
760
- const axes = [];
761
- for (let i = 0; i < 4; i++) {
762
- const p1 = this.points[i];
763
- const p2 = this.points[(i + 1) % 4];
764
- axes.push(p1.normal(p2));
615
+ intersectRectangle(t) {
616
+ const e = [];
617
+ for (let s = 0; s < 4; s++) {
618
+ const o = this.points[s], r = this.points[(s + 1) % 4];
619
+ e.push(o.normal(r));
765
620
  }
766
- for (let i = 0; i < 4; i++) {
767
- const p1 = rectangle.points[i];
768
- const p2 = rectangle.points[(i + 1) % 4];
769
- axes.push(p1.normal(p2));
621
+ for (let s = 0; s < 4; s++) {
622
+ const o = t.points[s], r = t.points[(s + 1) % 4];
623
+ e.push(o.normal(r));
770
624
  }
771
- function projectRectangle(rect, axis) {
772
- const projections = rect.points.map((point) => point.dot(axis));
773
- return [Math.min(...projections), Math.max(...projections)];
625
+ function n(s, o) {
626
+ const r = s.points.map((a) => a.dot(o));
627
+ return [Math.min(...r), Math.max(...r)];
774
628
  }
775
- function isProjectionOverlap(proj1, proj2) {
776
- return proj1[0] < proj2[1] && proj2[0] < proj1[1];
629
+ function i(s, o) {
630
+ return s[0] < o[1] && o[0] < s[1];
777
631
  }
778
- for (const axis of axes) {
779
- const proj1 = projectRectangle(this, axis);
780
- const proj2 = projectRectangle(rectangle, axis);
781
- if (!isProjectionOverlap(proj1, proj2)) {
782
- return false;
783
- }
632
+ for (const s of e) {
633
+ const o = n(this, s), r = n(t, s);
634
+ if (!i(o, r))
635
+ return !1;
784
636
  }
785
- return true;
637
+ return !0;
786
638
  }
787
639
  /**
788
640
  * 判断点是否完全位于矩形内部
789
641
  * @param point
790
642
  */
791
- containsPoint(point) {
792
- let positiveCount = 0;
793
- let negativeCount = 0;
643
+ containsPoint(t) {
644
+ let e = 0, n = 0;
794
645
  for (let i = 0; i < 4; i++) {
795
- const p1 = this.points[i];
796
- const p2 = this.points[(i + 1) % 4];
797
- const cross = (p2.x - p1.x) * (point.y - p1.y) - (p2.y - p1.y) * (point.x - p1.x);
798
- if (cross > 0) positiveCount++;
799
- else if (cross < 0) negativeCount++;
800
- else return false;
646
+ const s = this.points[i], o = this.points[(i + 1) % 4], r = (o.x - s.x) * (t.y - s.y) - (o.y - s.y) * (t.x - s.x);
647
+ if (r > 0) e++;
648
+ else if (r < 0) n++;
649
+ else return !1;
801
650
  }
802
- return positiveCount === 4 || negativeCount === 4;
651
+ return e === 4 || n === 4;
803
652
  }
804
653
  /**
805
654
  *
806
655
  * @returns
807
656
  */
808
657
  toBox() {
809
- let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
810
- this.points.forEach((p) => {
811
- maxX = Math.max(p.x, maxX);
812
- minX = Math.min(p.x, minX);
813
- maxY = Math.max(p.x, maxY);
814
- minY = Math.min(p.x, minY);
815
- });
816
- return new Box2(minX, maxX, minY, maxY);
658
+ let t = 1 / 0, e = -1 / 0, n = 1 / 0, i = -1 / 0;
659
+ return this.points.forEach((s) => {
660
+ e = Math.max(s.x, e), t = Math.min(s.x, t), i = Math.max(s.x, i), n = Math.min(s.x, n);
661
+ }), new v(t, e, n, i);
817
662
  }
818
663
  /**
819
664
  *
@@ -821,24 +666,22 @@ class Rectangle {
821
666
  * @param width
822
667
  * @returns
823
668
  */
824
- static fromByLineSegment(line, width = 0.1, horizontal = false, hScale = 0.5) {
825
- const p1 = line.points[0], p2 = line.points[1], normal = p2.normal(p1), pDirect = horizontal ? p2.direction(p1).mutiplyScalar(width * hScale) : Point.zero(), nDirect = horizontal ? p1.direction(p2).mutiplyScalar(width * hScale) : Point.zero();
826
- const offsetX = normal.x * width * 0.5;
827
- const offsetY = normal.y * width * 0.5;
828
- return new Rectangle([
829
- new Point(p1.x + offsetX, p1.y + offsetY).add(nDirect),
830
- new Point(p2.x + offsetX, p2.y + offsetY).add(pDirect),
831
- new Point(p2.x - offsetX, p2.y - offsetY).add(pDirect),
832
- new Point(p1.x - offsetX, p1.y - offsetY).add(nDirect)
669
+ static fromByLineSegment(t, e = 0.1, n = !1, i = 0.5) {
670
+ const s = t.points[0], o = t.points[1], r = o.normal(s), a = n ? o.direction(s).mutiplyScalar(e * i) : p.zero(), c = n ? s.direction(o).mutiplyScalar(e * i) : p.zero(), h = r.x * e * 0.5, l = r.y * e * 0.5;
671
+ return new O([
672
+ new p(s.x + h, s.y + l).add(c),
673
+ new p(o.x + h, o.y + l).add(a),
674
+ new p(o.x - h, o.y - l).add(a),
675
+ new p(s.x - h, s.y - l).add(c)
833
676
  ]);
834
677
  }
835
678
  }
836
- class LineSegment {
837
- points = [new Point(), new Point()];
679
+ class L {
680
+ points = [new p(), new p()];
838
681
  userData = {};
839
682
  line;
840
683
  get center() {
841
- return new Point(
684
+ return new p(
842
685
  this.points[0].x + (this.points[1].x - this.points[0].x) * 0.5,
843
686
  this.points[0].y + (this.points[1].y - this.points[0].y) * 0.5
844
687
  );
@@ -849,71 +692,92 @@ class LineSegment {
849
692
  get end() {
850
693
  return this.points[1];
851
694
  }
852
- constructor(p1 = new Point(), p2 = new Point()) {
853
- this.points = [p1, p2];
695
+ constructor(t = new p(), e = new p()) {
696
+ this.points = [t, e];
697
+ }
698
+ set(t, e) {
699
+ return this.start.copy(t), this.end.copy(e), this;
700
+ }
701
+ /**
702
+ * 是否有相同端点
703
+ * @param line
704
+ * @returns
705
+ */
706
+ sameEndpoint(t) {
707
+ return this.start.equal(t.start) || this.start.equal(t.end) || this.end.equal(t.start) || this.end.equal(t.end);
708
+ }
709
+ /**
710
+ * 相同端点是否为开始
711
+ * @param line
712
+ * @returns
713
+ */
714
+ sameEndpointAsStart(t) {
715
+ return this.start.equal(t.start) || this.start.equal(t.end);
716
+ }
717
+ /**
718
+ * 获取共线点
719
+ * @param line
720
+ * @returns
721
+ */
722
+ getSameEndpoint(t) {
723
+ return this.start.equal(t.start) ? [this.start, t.start] : this.start.equal(t.end) ? [this.start, t.end] : this.end.equal(t.start) ? [this.end, t.start] : this.end.equal(t.end) ? [this.end, t.end] : null;
724
+ }
725
+ /**
726
+ * 相同端点是否为结束
727
+ * @param line
728
+ * @returns
729
+ */
730
+ sameEndpointAsEnd(t) {
731
+ return this.end.equal(t.start) || this.end.equal(t.end);
854
732
  }
855
733
  /** 膨胀
856
734
  * @description 向线段的两个端点分别膨胀 width
857
735
  * @param width
858
736
  */
859
- expansion(width, direction = "all") {
860
- const step = this.direction().multiplyScalar(width);
861
- if (direction === "end" || direction === "all") this.end.add(step);
862
- if (direction === "start" || direction === "all") this.start.add(step.multiplyScalar(-1));
863
- return this;
737
+ expansion(t, e = "all") {
738
+ const n = this.direction().multiplyScalar(t);
739
+ return (e === "end" || e === "all") && this.end.add(n), (e === "start" || e === "all") && this.start.add(n.multiplyScalar(-1)), this;
864
740
  }
865
741
  /** 向前
866
742
  * @description 向前移动 width
867
743
  * @param width
868
744
  */
869
- forward(width) {
870
- const step = this.direction().multiplyScalar(width);
871
- this.start.add(step);
872
- this.end.add(step);
873
- return this;
745
+ forward(t) {
746
+ const e = this.direction().multiplyScalar(t);
747
+ return this.start.add(e), this.end.add(e), this;
874
748
  }
875
749
  /** 向前
876
750
  * @description 向前移动 width
877
751
  * @param width
878
752
  */
879
- backward(width) {
880
- const step = this.direction().multiplyScalar(-width);
881
- this.start.add(step);
882
- this.end.add(step);
883
- return this;
753
+ backward(t) {
754
+ const e = this.direction().multiplyScalar(-t);
755
+ return this.start.add(e), this.end.add(e), this;
884
756
  }
885
757
  /**
886
758
  * 向指定方向平移
887
759
  * @param direct
888
760
  * @param size
889
761
  */
890
- directionMove(direct, size) {
891
- const step = direct.clone().multiplyScalar(size);
892
- this.start.add(step);
893
- this.end.add(step);
894
- return this;
762
+ directionMove(t, e) {
763
+ const n = t.clone().multiplyScalar(e);
764
+ return this.start.add(n), this.end.add(n), this;
895
765
  }
896
766
  /** 膨胀为矩形
897
767
  *
898
768
  * @param width
899
769
  * @returns {Rectangle}
900
770
  */
901
- expandToRectangle(width = 0.1, direct = "all") {
902
- const p1 = this.start, p2 = this.end;
903
- const normal = p2.normal(p1);
904
- const pDirect = direct === "bothSides" ? Point.zero() : p2.direction(p1).mutiplyScalar(width * 0.5);
905
- const nDirect = direct === "bothSides" ? Point.zero() : p1.direction(p2).mutiplyScalar(width * 0.5);
906
- const offsetX = normal.x * width * 0.5;
907
- const offsetY = normal.y * width * 0.5;
908
- const point = [
771
+ expandToRectangle(t = 0.1, e = "all") {
772
+ const n = this.start, i = this.end, s = i.normal(n), o = e === "bothSides" ? p.zero() : i.direction(n).mutiplyScalar(t * 0.5), r = e === "bothSides" ? p.zero() : n.direction(i).mutiplyScalar(t * 0.5), a = s.x * t * 0.5, c = s.y * t * 0.5, h = [
909
773
  // 第一条线
910
- new Point(p1.x + offsetX, p1.y + offsetY).add(nDirect),
911
- new Point(p2.x + offsetX, p2.y + offsetY).add(pDirect),
774
+ new p(n.x + a, n.y + c).add(r),
775
+ new p(i.x + a, i.y + c).add(o),
912
776
  // 第二条线
913
- new Point(p1.x - offsetX, p1.y - offsetY).add(nDirect),
914
- new Point(p2.x - offsetX, p2.y - offsetY).add(pDirect)
777
+ new p(n.x - a, n.y - c).add(r),
778
+ new p(i.x - a, i.y - c).add(o)
915
779
  ];
916
- return new Rectangle([0, 1, 3, 2].map((i) => point[i]));
780
+ return new O([0, 1, 3, 2].map((l) => h[l]));
917
781
  }
918
782
  /**
919
783
  * 计算线段的长度
@@ -947,50 +811,27 @@ class LineSegment {
947
811
  * @param line 要投影的线段
948
812
  * @returns 投影并裁剪后的线段
949
813
  */
950
- projectLineSegment(line) {
951
- if (line.points.length !== 2 || this.points.length !== 2) {
814
+ projectLineSegment(t) {
815
+ if (t.points.length !== 2 || this.points.length !== 2)
952
816
  throw new Error("每条线段必须由两个点定义");
953
- }
954
- const [p1, p2] = line.points;
955
- const [q1, q2] = this.points;
956
- const dir = new Point(q2.x - q1.x, q2.y - q1.y);
957
- if (dir.x === 0 && dir.y === 0) {
817
+ const [e, n] = t.points, [i, s] = this.points, o = new p(s.x - i.x, s.y - i.y);
818
+ if (o.x === 0 && o.y === 0)
958
819
  throw new Error("投影目标线段的两个点不能重合");
959
- }
960
- const projectPoint = (point) => {
961
- const pq = new Point(point.x - q1.x, point.y - q1.y);
962
- const dirLengthSquared = dir.x * dir.x + dir.y * dir.y;
963
- const dotProduct = pq.x * dir.x + pq.y * dir.y;
964
- const t = dotProduct / dirLengthSquared;
965
- const projX = q1.x + t * dir.x;
966
- const projY = q1.y + t * dir.y;
967
- return new Point(projX, projY);
820
+ const r = (m) => {
821
+ const y = new p(m.x - i.x, m.y - i.y), u = o.x * o.x + o.y * o.y, w = (y.x * o.x + y.y * o.y) / u, S = i.x + w * o.x, b = i.y + w * o.y;
822
+ return new p(S, b);
968
823
  };
969
- let projP1 = projectPoint(p1);
970
- let projP2 = projectPoint(p2);
971
- const getT = (point) => {
972
- const pq = new Point(point.x - q1.x, point.y - q1.y);
973
- const dirLengthSquared = dir.x * dir.x + dir.y * dir.y;
974
- return (pq.x * dir.x + pq.y * dir.y) / dirLengthSquared;
824
+ let a = r(e), c = r(n);
825
+ const h = (m) => {
826
+ const y = new p(m.x - i.x, m.y - i.y), u = o.x * o.x + o.y * o.y;
827
+ return (y.x * o.x + y.y * o.y) / u;
975
828
  };
976
- let t1 = getT(projP1);
977
- let t2 = getT(projP2);
978
- const clampPoint = (t) => {
979
- const clampedT = Math.max(0, Math.min(1, t));
980
- const x = q1.x + clampedT * dir.x;
981
- const y = q1.y + clampedT * dir.y;
982
- return new Point(x, y);
829
+ let l = h(a), d = h(c);
830
+ const f = (m) => {
831
+ const y = Math.max(0, Math.min(1, m)), u = i.x + y * o.x, x = i.y + y * o.y;
832
+ return new p(u, x);
983
833
  };
984
- if (t1 < 0 || t1 > 1) {
985
- projP1 = clampPoint(t1);
986
- }
987
- if (t2 < 0 || t2 > 1) {
988
- projP2 = clampPoint(t2);
989
- }
990
- if (projP1.x === projP2.x && projP1.y === projP2.y) {
991
- return new LineSegment(projP1, projP1);
992
- }
993
- return new LineSegment(projP1, projP2);
834
+ return (l < 0 || l > 1) && (a = f(l)), (d < 0 || d > 1) && (c = f(d)), a.x === c.x && a.y === c.y ? new L(a, a) : new L(a, c);
994
835
  }
995
836
  /**
996
837
  * 计算一条线段在另一条直线上的投影
@@ -998,155 +839,118 @@ class LineSegment {
998
839
  * @param clip 是否裁剪超出目标线段的部分,默认裁剪
999
840
  * @returns 投影并裁剪后的线段
1000
841
  */
1001
- projectPoint(p1, clip = true) {
1002
- const [q1, q2] = this.points;
1003
- const dir = new Point(q2.x - q1.x, q2.y - q1.y);
1004
- if (dir.x === 0 && dir.y === 0) {
842
+ projectPoint(t, e = !0) {
843
+ const [n, i] = this.points, s = new p(i.x - n.x, i.y - n.y);
844
+ if (s.x === 0 && s.y === 0)
1005
845
  throw new Error("投影目标线段的两个点不能重合");
1006
- }
1007
- const projectPoint = (point) => {
1008
- const pq = new Point(point.x - q1.x, point.y - q1.y);
1009
- const dirLengthSquared = dir.x * dir.x + dir.y * dir.y;
1010
- const dotProduct = pq.x * dir.x + pq.y * dir.y;
1011
- const t = dotProduct / dirLengthSquared;
1012
- const projX = q1.x + t * dir.x;
1013
- const projY = q1.y + t * dir.y;
1014
- return new Point(projX, projY);
1015
- };
1016
- let projP1 = projectPoint(p1);
1017
- if (!clip) return projP1;
1018
- const getT = (point) => {
1019
- const pq = new Point(point.x - q1.x, point.y - q1.y);
1020
- const dirLengthSquared = dir.x * dir.x + dir.y * dir.y;
1021
- return (pq.x * dir.x + pq.y * dir.y) / dirLengthSquared;
1022
- };
1023
- let t1 = getT(projP1);
1024
- if (t1 < 0 || t1 > 1) {
1025
- return null;
1026
- }
1027
- return projP1;
846
+ let r = ((h) => {
847
+ const l = new p(h.x - n.x, h.y - n.y), d = s.x * s.x + s.y * s.y, m = (l.x * s.x + l.y * s.y) / d, y = n.x + m * s.x, u = n.y + m * s.y;
848
+ return new p(y, u);
849
+ })(t);
850
+ if (!e) return r;
851
+ let c = ((h) => {
852
+ const l = new p(h.x - n.x, h.y - n.y), d = s.x * s.x + s.y * s.y;
853
+ return (l.x * s.x + l.y * s.y) / d;
854
+ })(r);
855
+ return c < 0 || c > 1 ? null : r;
1028
856
  }
1029
857
  /**
1030
858
  * 判断线段是否与另一条线段相交(包含共用端点或部分重合的情况)
1031
859
  * @param line
860
+ * @param endpoint 是否包含端点相交
861
+ * @returns
1032
862
  */
1033
- intersectLineSegment(line) {
1034
- const p1 = this.start;
1035
- const p2 = this.end;
1036
- const p3 = line.start;
1037
- const p4 = line.end;
1038
- function crossProduct(a, b, c) {
1039
- return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
863
+ intersectLineSegment(t, e = !0) {
864
+ const n = this.start, i = this.end, s = t.start, o = t.end;
865
+ function r(f, m, y) {
866
+ return (m.x - f.x) * (y.y - f.y) - (m.y - f.y) * (y.x - f.x);
1040
867
  }
1041
- function isPointOnSegment(pt, segStart, segEnd) {
1042
- return Math.min(segStart.x, segEnd.x) - 1e-10 <= pt.x && pt.x <= Math.max(segStart.x, segEnd.x) + 1e-10 && Math.min(segStart.y, segEnd.y) - 1e-10 <= pt.y && pt.y <= Math.max(segStart.y, segEnd.y) + 1e-10;
868
+ function a(f, m, y) {
869
+ return Math.min(m.x, y.x) - 1e-10 <= f.x && f.x <= Math.max(m.x, y.x) + 1e-10 && Math.min(m.y, y.y) - 1e-10 <= f.y && f.y <= Math.max(m.y, y.y) + 1e-10;
1043
870
  }
1044
- const d1 = crossProduct(p1, p2, p3);
1045
- const d2 = crossProduct(p1, p2, p4);
1046
- const d3 = crossProduct(p3, p4, p1);
1047
- const d4 = crossProduct(p3, p4, p2);
1048
- if (d1 * d2 < 0 && d3 * d4 < 0) {
1049
- return true;
1050
- }
1051
- if (Math.abs(d1) < 1e-10 && isPointOnSegment(p3, p1, p2)) {
1052
- return true;
1053
- }
1054
- if (Math.abs(d2) < 1e-10 && isPointOnSegment(p4, p1, p2)) {
1055
- return true;
1056
- }
1057
- if (Math.abs(d3) < 1e-10 && isPointOnSegment(p1, p3, p4)) {
1058
- return true;
1059
- }
1060
- if (Math.abs(d4) < 1e-10 && isPointOnSegment(p2, p3, p4)) {
1061
- return true;
1062
- }
1063
- return false;
871
+ const c = r(n, i, s), h = r(n, i, o), l = r(s, o, n), d = r(s, o, i);
872
+ return !!(c * h < 0 && l * d < 0 || e && (Math.abs(c) < 1e-10 && a(s, n, i) || Math.abs(h) < 1e-10 && a(o, n, i) || Math.abs(l) < 1e-10 && a(n, s, o) || Math.abs(d) < 1e-10 && a(i, s, o)));
873
+ }
874
+ /**
875
+ * 判断一个点是否在线段上(含端点)
876
+ * @param pt 要判断的点
877
+ * @returns 如果点在当前线段上返回 true,否则返回 false
878
+ */
879
+ containsPoint(t) {
880
+ const e = t.distance(this.start), n = t.distance(this.end), i = this.getLength();
881
+ return Math.abs(e + n - i) < 1e-10;
1064
882
  }
1065
883
  /**
1066
884
  * 获取交点
1067
885
  * @param line
1068
886
  * @returns
1069
887
  */
1070
- getIntersection(line) {
1071
- const p1 = this.start;
1072
- const p2 = this.end;
1073
- const p3 = line.start;
1074
- const p4 = line.end;
1075
- const denom = (p1.x - p2.x) * (p3.y - p4.y) - (p1.y - p2.y) * (p3.x - p4.x);
1076
- if (Math.abs(denom) < 1e-10) {
888
+ getIntersection(t) {
889
+ const e = this.start, n = this.end, i = t.start, s = t.end, o = (e.x - n.x) * (i.y - s.y) - (e.y - n.y) * (i.x - s.x);
890
+ if (Math.abs(o) < 1e-10)
1077
891
  return null;
1078
- }
1079
- const t = ((p1.x - p3.x) * (p3.y - p4.y) - (p1.y - p3.y) * (p3.x - p4.x)) / denom;
1080
- const x = p1.x + t * (p2.x - p1.x);
1081
- const y = p1.y + t * (p2.y - p1.y);
1082
- return new Point(x, y);
892
+ const r = ((e.x - i.x) * (i.y - s.y) - (e.y - i.y) * (i.x - s.x)) / o, a = e.x + r * (n.x - e.x), c = e.y + r * (n.y - e.y);
893
+ return new p(a, c);
1083
894
  }
1084
895
  /**
1085
896
  * 获取两条线段夹角
1086
897
  * @param line
1087
898
  */
1088
- includedAngle(line) {
1089
- const d1 = this.direction(), d2 = line.direction();
1090
- return d1.angleBetween(d2) / (Math.PI / 180);
899
+ includedAngle(t) {
900
+ const e = this.direction(), n = t.direction();
901
+ return e.angleBetween(n) / (Math.PI / 180);
1091
902
  }
1092
903
  /**
1093
904
  * 两条线段方向是否一致
1094
905
  * @param line
1095
906
  */
1096
- directionEqual(line, errAngle = 0.1) {
1097
- return this.includedAngle(line) < errAngle;
907
+ directionEqual(t, e = 0.1) {
908
+ return this.includedAngle(t) < e;
1098
909
  }
1099
910
  /**
1100
911
  * 两条线段方向相反否一致
1101
912
  * @param line
1102
913
  */
1103
- directionOpposite(line, errAngle = 0.1) {
1104
- return 180 - this.includedAngle(line) < errAngle;
914
+ directionOpposite(t, e = 0.1) {
915
+ return 180 - this.includedAngle(t) < e;
1105
916
  }
1106
917
  /**
1107
918
  * 判断两条线是否平行
1108
919
  * @param line
1109
920
  */
1110
- isParallel(line, errAngle = 4) {
1111
- const angle = this.includedAngle(line);
1112
- return angle < errAngle || angle > 180 - errAngle;
921
+ isParallel(t, e = 4) {
922
+ const n = this.includedAngle(t);
923
+ return n < e || n > 180 - e;
1113
924
  }
1114
925
  /**
1115
926
  * 判断两条直线是否重合
1116
927
  * @param line
1117
928
  * @returns
1118
929
  */
1119
- areLinesCoincident(line) {
1120
- const p1 = this.start, p2 = this.end, p3 = line.start, p4 = line.end;
1121
- const m1 = (p2.y - p1.y) / (p2.x - p1.x);
1122
- const b1 = p1.y - m1 * p1.x;
1123
- const m2 = (p4.y - p3.y) / (p4.x - p3.x);
1124
- const b2 = p3.y - m2 * p3.x;
1125
- if (!isFinite(m1) && !isFinite(m2)) {
1126
- return p1.x === p3.x && p2.x === p3.x;
1127
- }
1128
- return Math.abs(m1 - m2) < 1e-3 && Math.abs(b1 - b2) < 1e-3;
930
+ areLinesCoincident(t) {
931
+ const e = this.start, n = this.end, i = t.start, s = t.end, o = (n.y - e.y) / (n.x - e.x), r = e.y - o * e.x, a = (s.y - i.y) / (s.x - i.x), c = i.y - a * i.x;
932
+ return !isFinite(o) && !isFinite(a) ? e.x === i.x && n.x === i.x : Math.abs(o - a) < 1e-3 && Math.abs(r - c) < 1e-3;
1129
933
  }
1130
934
  clone() {
1131
- return new LineSegment(
935
+ const t = new L(
1132
936
  this.points[0].clone(),
1133
937
  this.points[1].clone()
1134
938
  );
939
+ return t.userData = { ...this.userData }, t;
1135
940
  }
1136
941
  }
1137
- async function include(path, exportDefault = true) {
1138
- if (typeof global !== "undefined" && typeof require !== "undefined") {
1139
- return require(path);
1140
- } else {
1141
- let pack = await import(
942
+ async function G(g, t = !0) {
943
+ if (typeof global < "u" && typeof require < "u")
944
+ return require(g);
945
+ {
946
+ let e = await import(
1142
947
  /* @vite-ignore */
1143
- path
948
+ g
1144
949
  );
1145
- if (exportDefault) pack = pack.default;
1146
- return pack;
950
+ return t && (e = e.default), e;
1147
951
  }
1148
952
  }
1149
- const units = {
953
+ const st = {
1150
954
  Unitless: 1,
1151
955
  // 无单位,1米 = 1(无单位)
1152
956
  Inches: 39.37007874015748,
@@ -1190,31 +994,27 @@ const units = {
1190
994
  Parsecs: 3240779289666404e-32
1191
995
  // 秒差距,1米 ≈ 0.00000000000000003240779289666404秒差距
1192
996
  };
1193
- function pathToLines(path) {
1194
- const lineSegments = [];
1195
- for (let i = 0; i < path.length; i++) {
1196
- lineSegments.push(new LineSegment(
1197
- path[i].clone(),
1198
- path[(i + 1) % path.length].clone()
997
+ function k(g) {
998
+ const t = [];
999
+ for (let e = 0; e < g.length; e++)
1000
+ t.push(new L(
1001
+ g[e].clone(),
1002
+ g[(e + 1) % g.length].clone()
1199
1003
  ));
1200
- }
1201
- return lineSegments;
1004
+ return t;
1202
1005
  }
1203
- function linesToPath(lineSegments) {
1204
- return lineSegments.flatMap((line, index2) => {
1205
- if (index2 === lineSegments.length - 1) [...line.points, lineSegments[0].points[0]];
1206
- return [line.points[0]];
1207
- });
1006
+ function J(g) {
1007
+ return g.flatMap((t, e) => (e === g.length - 1 && [...t.points, g[0].points[0]], [t.points[0]]));
1208
1008
  }
1209
- class Dxf extends Component {
1009
+ class X extends q {
1210
1010
  static name = "Dxf";
1211
1011
  shortLine = 0.04;
1212
1012
  width = 0.04;
1213
1013
  scale = 1;
1214
1014
  originalData = [];
1215
1015
  data = [];
1216
- originalBox = new Box2(0, 0, 0, 0);
1217
- box = new Box2(0, 0, 0, 0);
1016
+ originalBox = new v(0, 0, 0, 0);
1017
+ box = new v(0, 0, 0, 0);
1218
1018
  pointsGroups = [];
1219
1019
  wallsGroup = [];
1220
1020
  doors = [];
@@ -1243,11 +1043,8 @@ class Dxf extends Component {
1243
1043
  * @param width 墙体宽度
1244
1044
  * @param scale 缩放比例
1245
1045
  */
1246
- constructor(width = 0.04, scale = 1) {
1247
- super();
1248
- this.width = width;
1249
- this.scale = scale;
1250
- this.shortLine = width * 0.4;
1046
+ constructor(t = 0.04, e = 1) {
1047
+ super(), this.width = t, this.scale = e, this.shortLine = t * 0.4;
1251
1048
  }
1252
1049
  /**
1253
1050
  * 设置
@@ -1255,52 +1052,36 @@ class Dxf extends Component {
1255
1052
  * @param width
1256
1053
  * @param scale
1257
1054
  */
1258
- async set(data, width = this.width, scale = this.scale) {
1259
- if (typeof data === "string") {
1260
- if (typeof global !== "undefined") {
1261
- const packageName = "fs";
1262
- const { default: fs } = await import(
1055
+ async set(t, e = this.width, n = this.scale) {
1056
+ if (typeof t == "string")
1057
+ if (typeof global < "u") {
1058
+ const { default: o } = await import(
1263
1059
  /* @vite-ignore */
1264
- packageName
1265
- );
1266
- const buffer = fs.readFileSync(data);
1267
- const json = JSON.parse(buffer.toString("utf-8"));
1268
- return this.set(json, width, scale);
1269
- } else {
1060
+ "fs"
1061
+ ), r = o.readFileSync(t), a = JSON.parse(r.toString("utf-8"));
1062
+ return this.set(a, e, n);
1063
+ } else
1270
1064
  throw new Error("非node环境不允许使用路径");
1271
- }
1272
- }
1273
- this.scale = scale;
1274
- this.width = width;
1275
- this.originalData = data;
1276
- this.lineSegments.length = 0;
1277
- const zList = [];
1278
- this.data = data.map(({ start, end, insetionArr, isDoor = false, isWindow, drawDoorData }, index2) => {
1279
- zList.push(start.z ?? 0, end.z ?? 0);
1280
- const lineSegment = new LineSegment(
1281
- Point.from(start).mutiplyScalar(scale),
1282
- Point.from(end).mutiplyScalar(scale)
1065
+ this.scale = n, this.width = e, this.originalData = t, this.lineSegments.length = 0;
1066
+ const i = [];
1067
+ this.data = t.map(({ start: s, end: o, insetionArr: r, isDoor: a = !1, ...c }, h) => {
1068
+ i.push(s.z ?? 0, o.z ?? 0);
1069
+ const l = new L(
1070
+ p.from(s).mutiplyScalar(n),
1071
+ p.from(o).mutiplyScalar(n)
1283
1072
  );
1284
- lineSegment.userData = { isDoor, isWindow, drawDoorData };
1285
- this.lineSegments.push(lineSegment);
1286
- return [
1287
- lineSegment.points[0],
1288
- lineSegment.points[1],
1289
- (insetionArr ?? []).map((i) => i.index),
1290
- isDoor,
1291
- index2
1073
+ return l.userData = { isDoor: a, ...c }, this.lineSegments.push(l), [
1074
+ l.points[0],
1075
+ l.points[1],
1076
+ (r ?? []).map((d) => d.index),
1077
+ a,
1078
+ h
1292
1079
  ];
1293
- });
1294
- this.originalZAverage = zList.reduce((count, num) => count + num, 0) / zList.length;
1295
- this.computedOriginalSize(data, this.originalBox);
1296
- this.dispatchEvent({
1080
+ }), this.originalZAverage = i.reduce((s, o) => s + o, 0) / i.length, this.computedOriginalSize(t, this.originalBox), this.dispatchEvent({
1297
1081
  type: "setDta",
1298
1082
  originalData: this.originalData,
1299
1083
  data: this.data
1300
- });
1301
- this.createGroups();
1302
- this.computedSize();
1303
- this.dispatchEvent({
1084
+ }), this.createGroups(), this.computedSize(), this.dispatchEvent({
1304
1085
  type: "createGroup",
1305
1086
  groups: this.pointsGroups
1306
1087
  });
@@ -1310,32 +1091,20 @@ class Dxf extends Component {
1310
1091
  * @returns
1311
1092
  */
1312
1093
  createGroups() {
1313
- const groups = [], visited = /* @__PURE__ */ new Set(), doorSet = /* @__PURE__ */ new Set(), doorVisitedRecord = /* @__PURE__ */ new Map();
1314
- const dfs = (index2, group, preIndex = -1) => {
1315
- const [start, end, insetionArr, isDoor] = this.data[index2];
1316
- visited.add(index2);
1317
- if (isDoor) {
1318
- if (!doorVisitedRecord.has(index2)) doorVisitedRecord.set(index2, []);
1319
- doorVisitedRecord.get(index2)?.push(preIndex);
1320
- return doorSet.add(this.data[index2]);
1321
- }
1322
- group.push([start, end]);
1323
- insetionArr.forEach((i) => {
1324
- if (!visited.has(i)) {
1325
- dfs(i, group, index2);
1326
- }
1094
+ const t = [], e = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Map(), s = (o, r, a = -1) => {
1095
+ const [c, h, l, d] = this.data[o];
1096
+ if (e.add(o), d)
1097
+ return i.has(o) || i.set(o, []), i.get(o)?.push(a), n.add(this.data[o]);
1098
+ r.push([c, h]), l.forEach((f) => {
1099
+ e.has(f) || s(f, r, o);
1327
1100
  });
1328
1101
  };
1329
- this.data.forEach((_, index2) => {
1330
- if (!visited.has(index2)) {
1331
- const group = [];
1332
- dfs(index2, group);
1333
- groups.push(group);
1102
+ return this.data.forEach((o, r) => {
1103
+ if (!e.has(r)) {
1104
+ const a = [];
1105
+ s(r, a), t.push(a);
1334
1106
  }
1335
- });
1336
- this.doors = [...doorSet];
1337
- this.pointsGroups = groups;
1338
- return groups;
1107
+ }), this.doors = [...n], this.pointsGroups = t, t;
1339
1108
  }
1340
1109
  /** 计算当前墙体数据的边界框
1341
1110
  * @description 根据分组数据pointsGroups,计算包围盒, pointsGroups数据为缩放后数据。
@@ -1343,219 +1112,163 @@ class Dxf extends Component {
1343
1112
  * @returns
1344
1113
  */
1345
1114
  computedSize() {
1346
- const xArr = this.pointsGroups.flatMap((points) => points.flatMap((p) => [p[0].x, p[1].x]));
1347
- const yArr = this.pointsGroups.flatMap((points) => points.flatMap((p) => [p[0].y, p[1].y]));
1348
- const minX = Math.min(...xArr);
1349
- const minY = Math.min(...yArr);
1350
- const maxX = Math.max(...xArr);
1351
- const maxY = Math.max(...yArr);
1352
- this.box.set(minX, minY, maxX, maxY);
1353
- return this.box;
1115
+ const t = this.pointsGroups.flatMap((r) => r.flatMap((a) => [a[0].x, a[1].x])), e = this.pointsGroups.flatMap((r) => r.flatMap((a) => [a[0].y, a[1].y])), n = Math.min(...t), i = Math.min(...e), s = Math.max(...t), o = Math.max(...e);
1116
+ return this.box.set(n, i, s, o), this.box;
1354
1117
  }
1355
1118
  /** 线路拓扑
1356
1119
  * @description 处理线路拓扑,使线路有序链接,形成长路径
1357
1120
  * @param lines
1358
1121
  */
1359
- lineTopology(lines) {
1360
- const visited = [];
1361
- function dfs(index2, linePath) {
1362
- const [_0, a2] = lines[index2];
1363
- visited[index2] = true;
1364
- linePath.push(a2);
1365
- for (let i = 0; i < lines.length; i++) {
1366
- const [b1, _1] = lines[i];
1367
- if (!visited[i]) {
1368
- if (Math.abs(a2.x - b1.x) < 1e-6 && Math.abs(a2.y - b1.y) < 1e-6) {
1369
- return dfs(i, linePath);
1370
- }
1371
- }
1122
+ lineTopology(t) {
1123
+ const e = [];
1124
+ function n(s, o) {
1125
+ const [r, a] = t[s];
1126
+ e[s] = !0, o.push(a);
1127
+ for (let c = 0; c < t.length; c++) {
1128
+ const [h, l] = t[c];
1129
+ if (!e[c] && Math.abs(a.x - h.x) < 1e-6 && Math.abs(a.y - h.y) < 1e-6)
1130
+ return n(c, o);
1372
1131
  }
1373
1132
  }
1374
- const linePaths = [];
1375
- for (let i = 0; i < lines.length; i++) {
1376
- if (!visited[i]) {
1377
- const linePath = [lines[i][0]];
1378
- dfs(i, linePath);
1379
- linePaths.push(linePath);
1133
+ const i = [];
1134
+ for (let s = 0; s < t.length; s++)
1135
+ if (!e[s]) {
1136
+ const o = [t[s][0]];
1137
+ n(s, o), i.push(o);
1380
1138
  }
1381
- }
1382
- return linePaths;
1139
+ return i;
1383
1140
  }
1384
1141
  /** 合并方向相同的线段
1385
1142
  * @param lines
1386
1143
  * @param errAngle
1387
1144
  */
1388
- mergeSameDirectionLine(lines, errAngle = 3) {
1389
- if (lines[0].includedAngle(lines[lines.length - 1]) < 0.1) {
1390
- const line = lines.pop();
1391
- line.end.copy(lines[0].end);
1392
- lines.splice(0, 1, line);
1145
+ mergeSameDirectionLine(t, e = 3) {
1146
+ if (t[0].includedAngle(t[t.length - 1]) < 0.1) {
1147
+ const i = t.pop();
1148
+ i.end.copy(t[0].end), t.splice(0, 1, i);
1393
1149
  }
1394
- const filterLines = [lines[0]];
1395
- for (let i = 1; i < lines.length; i++) {
1396
- const line = lines[i];
1397
- const preLine = lines[i - 1];
1398
- if (preLine.includedAngle(line) < errAngle) {
1399
- preLine.end.copy(line.end);
1400
- } else {
1401
- filterLines.push(line);
1402
- }
1150
+ const n = [t[0]];
1151
+ for (let i = 1; i < t.length; i++) {
1152
+ const s = t[i], o = t[i - 1];
1153
+ o.includedAngle(s) < e ? o.end.copy(s.end) : n.push(s);
1403
1154
  }
1404
- return filterLines;
1155
+ return n;
1405
1156
  }
1406
1157
  /** etOpenRound 去除毛刺
1407
1158
  * @description 检查连续的短线段数量,去除合并后产生的毛刺
1408
1159
  */
1409
- squareRemoveBurr(path) {
1410
- if (path.length < 3) return path;
1411
- const filterLines = [path[0]];
1412
- for (let i = 1; i < path.length; i++) {
1413
- const prev = path[i - 1];
1414
- const curr = path[i];
1415
- const len = prev.distance(curr);
1416
- if (len < this.width * 0.5) {
1417
- let count = 0;
1418
- for (let j = i + 1; j < path.length; j++) {
1419
- const prev2 = path[j - 1];
1420
- const curr2 = path[j];
1421
- const len2 = prev2.distance(curr2);
1422
- if (len2 < this.width * 0.8) count++;
1160
+ squareRemoveBurr(t) {
1161
+ if (t.length < 3) return t;
1162
+ const e = [t[0]];
1163
+ for (let n = 1; n < t.length; n++) {
1164
+ const i = t[n - 1], s = t[n];
1165
+ if (i.distance(s) < this.width * 0.5) {
1166
+ let r = 0;
1167
+ for (let a = n + 1; a < t.length; a++) {
1168
+ const c = t[a - 1], h = t[a];
1169
+ if (c.distance(h) < this.width * 0.8) r++;
1423
1170
  else break;
1424
1171
  }
1425
- if (count === 0 && i + count === path.length - 1) ;
1426
- else if (i == 1 && count === 1) ;
1427
- else if (count === 3) {
1428
- filterLines.push(path[i + 1]);
1429
- i += count;
1430
- } else if (count === 5) {
1431
- filterLines.push(path[i + 2]);
1432
- i += count;
1433
- } else {
1434
- filterLines.push(curr);
1435
- }
1436
- } else {
1437
- filterLines.push(curr);
1438
- }
1172
+ r === 0 && n + r === t.length - 1 || n == 1 && r === 1 || (r === 3 ? (e.push(t[n + 1]), n += r) : r === 5 ? (e.push(t[n + 2]), n += r) : e.push(s));
1173
+ } else
1174
+ e.push(s);
1439
1175
  }
1440
- return filterLines;
1176
+ return e;
1441
1177
  }
1442
1178
  /**
1443
1179
  * 线段矫直, 线段中心突刺
1444
1180
  * @description 突变长度小于墙体宽度,该线段可能为突起线段,
1445
1181
  * @description 判断后续第2线段与上一条线段是否方向相同,相同就为突刺
1446
1182
  */
1447
- lineSegmentStraightening(path) {
1448
- for (let i = 0; i < path.length; i++) {
1449
- const p1 = path[i];
1450
- const p2 = path[(i + 1) % path.length];
1451
- if (p1.distance(p2) > this.shortLine) {
1452
- path.push(...path.slice(0, i + 1));
1453
- path.splice(0, i + 1);
1183
+ lineSegmentStraightening(t) {
1184
+ for (let i = 0; i < t.length; i++) {
1185
+ const s = t[i], o = t[(i + 1) % t.length];
1186
+ if (s.distance(o) > this.shortLine) {
1187
+ t.push(...t.slice(0, i + 1)), t.splice(0, i + 1);
1454
1188
  break;
1455
1189
  }
1456
1190
  }
1457
- const lines = this.mergeSameDirectionLine(pathToLines(path)), filterLines = [lines[0]];
1458
- for (let i = 1; i < lines.length; i++) {
1459
- const line = lines[i];
1460
- const preLine = lines[(lines.length + i - 1) % lines.length];
1461
- if (line.length() > this.width * 0.9) {
1462
- filterLines.push(line);
1191
+ const e = this.mergeSameDirectionLine(k(t)), n = [e[0]];
1192
+ for (let i = 1; i < e.length; i++) {
1193
+ const s = e[i], o = e[(e.length + i - 1) % e.length];
1194
+ if (s.length() > this.width * 0.9) {
1195
+ n.push(s);
1463
1196
  continue;
1464
1197
  }
1465
- const line1 = lines[i + 1];
1466
- if (line1 && line1.length() > this.width * 0.9) {
1467
- filterLines.push(line);
1468
- filterLines.push(line1);
1469
- i = i + 1;
1198
+ const r = e[i + 1];
1199
+ if (r && r.length() > this.width * 0.9) {
1200
+ n.push(s), n.push(r), i = i + 1;
1470
1201
  continue;
1471
1202
  }
1472
- const line2 = lines[i + 2];
1473
- if (line2 && preLine.includedAngle(line2) < 2) {
1474
- i = i + 2;
1475
- filterLines.push(line2);
1476
- } else filterLines.push(line);
1203
+ const a = e[i + 2];
1204
+ a && o.includedAngle(a) < 2 ? (i = i + 2, n.push(a)) : n.push(s);
1477
1205
  }
1478
- return filterLines.length > 2 ? linesToPath(this.mergeSameDirectionLine(filterLines)) : [];
1206
+ return n.length > 3 ? J(this.mergeSameDirectionLine(n)) : [];
1479
1207
  }
1480
1208
  /**
1481
1209
  * 移除短线段
1482
1210
  * @todo 根据线段两端线段长度,选取参照物_|▔▔
1483
1211
  * @param path
1484
1212
  */
1485
- removeShortLine(path, shortLine = this.shortLine) {
1486
- const lines = pathToLines(path), filterLines = [], PI_1 = Math.PI / 180;
1487
- for (let i = 0; i < lines.length; i++) {
1488
- const line = lines[i], len = line.length();
1489
- if (len > shortLine || filterLines.length === 0) {
1490
- filterLines.push(line);
1213
+ removeShortLine(t, e = this.shortLine) {
1214
+ const n = k(t), i = [], s = Math.PI / 180;
1215
+ for (let o = 0; o < n.length; o++) {
1216
+ const r = n[o], a = r.length(), c = o;
1217
+ if (a > e || i.length === 0) {
1218
+ i.push(r);
1491
1219
  continue;
1492
1220
  }
1493
- let nextline = lines[++i];
1494
- const preLine = filterLines[filterLines.length - 1], d1 = preLine.direction();
1495
- while (i < lines.length) {
1496
- const angle = d1.angleBetween(nextline.direction()) / PI_1;
1497
- if (nextline.length() <= shortLine || angle < 4 || angle > 180 - 4) {
1498
- nextline = lines[++i];
1499
- } else break;
1500
- }
1501
- if (!nextline) continue;
1502
- const intersectPoint = preLine.getIntersection(nextline);
1503
- if (intersectPoint) {
1504
- const p0 = preLine.points[1].clone(), p1 = nextline.points[0].clone();
1505
- preLine.points[1].copy(intersectPoint);
1506
- nextline.points[0].copy(intersectPoint);
1507
- if (preLine.length() < this.width) {
1508
- preLine.points[1].copy(p0);
1509
- nextline.points[0].copy(p0);
1510
- } else if (nextline.length() < this.width) {
1511
- preLine.points[1].copy(p1);
1512
- nextline.points[0].copy(p1);
1513
- }
1514
- } else {
1515
- preLine.points[1].copy(nextline.points[0]);
1221
+ let h = n[++o];
1222
+ const l = i[i.length - 1], d = l.direction();
1223
+ for (; o < n.length; ) {
1224
+ const m = d.angleBetween(h.direction()) / s;
1225
+ if (h.length() <= e || m < 4 || m > 176)
1226
+ h = n[++o];
1227
+ else break;
1516
1228
  }
1517
- filterLines.push(nextline);
1518
- }
1519
- return filterLines.length > 2 ? linesToPath(filterLines) : [];
1229
+ if (!h) continue;
1230
+ const f = n[o - 1];
1231
+ if (l.length() > f.length()) {
1232
+ const m = l.getIntersection(h);
1233
+ if (m) {
1234
+ const y = l.points[1].clone(), u = h.points[0].clone();
1235
+ l.points[1].copy(m), h.points[0].copy(m), l.length() < this.width ? (l.points[1].copy(y), h.points[0].copy(y)) : h.length() < this.width && (l.points[1].copy(u), h.points[0].copy(u));
1236
+ } else
1237
+ l.points[1].copy(h.points[0]);
1238
+ i.push(h);
1239
+ } else
1240
+ o = c;
1241
+ }
1242
+ return i.length > 3 ? J(i) : [];
1520
1243
  }
1521
1244
  /** 线偏移
1522
1245
  * @description 使用 ClipperLib 对每个点组进行线偏移处理,生成具有指定宽度的墙体路径
1523
1246
  */
1524
- lineOffset(endType = Dxf.EndType.etOpenSquare, joinType = Dxf.JoinType.jtMiter, scale = 1e4) {
1525
- let solutions = new ClipperLib.Paths();
1526
- const offset = new ClipperLib.ClipperOffset(20, 0.25);
1527
- this.pointsGroups.forEach((points) => {
1528
- const linePaths = this.lineTopology(points).map((linePath) => linePath.map((p) => p.clone().mutiplyScalar(scale)));
1529
- offset.AddPaths(linePaths, joinType, endType);
1530
- });
1531
- offset.Execute(solutions, this.width / 2 * scale);
1532
- this.wallsGroup = solutions.map((ps) => {
1533
- let path = ps.map((p) => Point.from(p).divisionScalar(scale));
1534
- path = this.lineSegmentStraightening(path);
1535
- if (endType == Dxf.EndType.etOpenSquare) path = this.squareRemoveBurr(path);
1536
- path = this.removeShortLine(path);
1537
- return path;
1538
- });
1539
- this.dispatchEvent({
1247
+ lineOffset(t = X.EndType.etOpenSquare, e = X.JoinType.jtMiter, n = 1e4) {
1248
+ let i = new F.Paths();
1249
+ const s = new F.ClipperOffset(20, 0.25);
1250
+ return this.pointsGroups.forEach((o) => {
1251
+ const r = this.lineTopology(o).map((a) => a.map((c) => c.clone().mutiplyScalar(n)));
1252
+ s.AddPaths(r, e, t);
1253
+ }), s.Execute(i, this.width / 2 * n), this.wallsGroup = i.map((o) => {
1254
+ let r = o.map((a) => p.from(a).divisionScalar(n));
1255
+ return r = this.lineSegmentStraightening(r), t == X.EndType.etOpenSquare && (r = this.squareRemoveBurr(r)), r = this.removeShortLine(r), r;
1256
+ }), this.dispatchEvent({
1540
1257
  type: "lineOffset",
1541
1258
  wallsGroup: this.wallsGroup
1542
- });
1543
- return this.wallsGroup;
1259
+ }), this.wallsGroup;
1544
1260
  }
1545
1261
  /**
1546
1262
  * 将点云结构转换为Float32Array
1547
1263
  */
1548
- to3DArray(scale, z = this.originalZAverage) {
1549
- const array = [];
1550
- this.wallsGroup.forEach((points) => {
1551
- for (let i = 0; i < points.length; i++) {
1552
- const point1 = points[i];
1553
- const nextIndex = i === points.length - 1 ? 0 : i + 1;
1554
- const point2 = points[nextIndex];
1555
- array.push(point1.X * scale, point1.Y * scale, z, point2.X * scale, point2.Y * scale, z);
1264
+ to3DArray(t, e = this.originalZAverage) {
1265
+ const n = [];
1266
+ return this.wallsGroup.forEach((i) => {
1267
+ for (let s = 0; s < i.length; s++) {
1268
+ const o = i[s], r = s === i.length - 1 ? 0 : s + 1, a = i[r];
1269
+ n.push(o.X * t, o.Y * t, e, a.X * t, a.Y * t, e);
1556
1270
  }
1557
- });
1558
- return new Float32Array(array);
1271
+ }), new Float32Array(n);
1559
1272
  }
1560
1273
  /** 获取角度范围
1561
1274
  * @param center
@@ -1563,196 +1276,282 @@ class Dxf extends Component {
1563
1276
  * @param p2
1564
1277
  * @returns
1565
1278
  */
1566
- getArcAngleRange(center, p1, p2) {
1567
- const x1 = p1.x - center.x;
1568
- const y1 = p1.y - center.y;
1569
- const x2 = p2.x - center.x;
1570
- const y2 = p2.y - center.y;
1571
- let angle1 = Math.atan2(y1, x1);
1572
- let angle2 = Math.atan2(y2, x2);
1573
- angle1 = angle1 < 0 ? angle1 + 2 * Math.PI : angle1;
1574
- angle2 = angle2 < 0 ? angle2 + 2 * Math.PI : angle2;
1575
- let r1, r2;
1576
- const diff = Math.abs(angle2 - angle1);
1577
- if (diff <= Math.PI) {
1578
- r1 = Math.min(angle1, angle2);
1579
- r2 = Math.max(angle1, angle2);
1580
- } else {
1581
- r1 = Math.max(angle1, angle2);
1582
- r2 = Math.min(angle1, angle2) + 2 * Math.PI;
1583
- }
1584
- return [r1 / (Math.PI / 180), r2 / (Math.PI / 180)];
1585
- }
1586
- /**
1587
- * 将点云结构转换为string
1588
- */
1589
- toDxfString(unit = "Millimeters") {
1590
- const d = new Drawing();
1591
- d.setUnits("Millimeters");
1592
- const s = units[unit];
1593
- function drawLine(p1, p2) {
1594
- d.drawLine(p1.X * s, p1.Y * s, p2.X * s, p2.Y * s);
1279
+ getArcAngleRange(t, e, n) {
1280
+ const i = e.x - t.x, s = e.y - t.y, o = n.x - t.x, r = n.y - t.y;
1281
+ let a = Math.atan2(s, i), c = Math.atan2(r, o);
1282
+ a = a < 0 ? a + 2 * Math.PI : a, c = c < 0 ? c + 2 * Math.PI : c;
1283
+ let h, l;
1284
+ return Math.abs(c - a) <= Math.PI ? (h = Math.min(a, c), l = Math.max(a, c)) : (h = Math.max(a, c), l = Math.min(a, c) + 2 * Math.PI), [h / (Math.PI / 180), l / (Math.PI / 180)];
1285
+ }
1286
+ /**
1287
+ * 转为绘制数据
1288
+ */
1289
+ toDrawDataJson(t = "Millimeters") {
1290
+ const e = st[t], n = {
1291
+ unit: t,
1292
+ line: [],
1293
+ arc: [],
1294
+ dimensionLine: [],
1295
+ center: this.box.center.toJson(),
1296
+ width: this.box.width * e,
1297
+ height: this.box.height * e,
1298
+ scale: e
1299
+ };
1300
+ let i = "white";
1301
+ function s(c, h) {
1302
+ n.line.push([c.X * e, c.Y * e, h.X * e, h.Y * e, i]);
1303
+ }
1304
+ function o(c, h, l, d) {
1305
+ n.arc.push([
1306
+ c.x * e,
1307
+ c.y * e,
1308
+ h * e,
1309
+ l,
1310
+ d,
1311
+ i
1312
+ ]);
1313
+ }
1314
+ for (let c = 0; c < this.originalData.length; c++) {
1315
+ const h = this.originalData[c];
1316
+ if (h.isVerticalReferenceLine) {
1317
+ n.dimensionLine.push([h.start.x * e, h.start.y * e, h.end.x * e, h.end.y * e]);
1318
+ break;
1319
+ }
1595
1320
  }
1596
- this.wallsGroup.forEach((points) => {
1597
- for (let i = 0; i < points.length; i++) {
1598
- const point1 = points[i];
1599
- const nextIndex = i === points.length - 1 ? 0 : i + 1;
1600
- const point2 = points[nextIndex];
1601
- drawLine(point1, point2);
1321
+ this.wallsGroup.forEach((c) => {
1322
+ for (let h = 0; h < c.length; h++) {
1323
+ const l = c[h], d = h === c.length - 1 ? 0 : h + 1, f = c[d];
1324
+ s(l, f);
1602
1325
  }
1603
1326
  });
1604
- const doorThickness = this.width * 0.2;
1605
- const list = [];
1606
- d.addLayer("l_cyan", Drawing.ACI.CYAN, "DOTTED");
1607
- this.doorLineSegment.forEach((lineSegment) => {
1608
- if (lineSegment.length() < 0.4) return;
1609
- const line = lineSegment.clone().expansion(-this.width * 0.5);
1610
- d.setActiveLayer("l_cyan");
1611
- if (line.length() < 1.2) {
1612
- line.expansion(-doorThickness * 0.5);
1613
- const normal = lineSegment.normal();
1614
- let door = new LineSegment(
1615
- line.start.clone(),
1616
- line.start.clone().add(normal.clone().multiplyScalar(line.length()))
1327
+ const r = this.width * 0.2, a = [];
1328
+ return this.doorLineSegment.forEach((c) => {
1329
+ if (c.length() < 0.4) return;
1330
+ const h = c.clone().expansion(-this.width * 0.5);
1331
+ if (i = "cyan", h.length() < 1.2) {
1332
+ h.expansion(-r * 0.5);
1333
+ const l = c.normal();
1334
+ let d = new L(
1335
+ h.start.clone(),
1336
+ h.start.clone().add(l.clone().multiplyScalar(h.length()))
1617
1337
  );
1618
- const box = door.clone().directionMove(door.normal(), line.length() * -0.5).expandToRectangle(line.length(), "bothSides");
1619
- for (let j = 0; j < list.length; j++) {
1620
- if (list[j].intersectRectangle(box)) {
1621
- door = new LineSegment(
1622
- line.start.clone(),
1623
- line.start.clone().add(normal.clone().multiplyScalar(-line.length()))
1338
+ const f = d.clone().directionMove(d.normal(), h.length() * -0.5).expandToRectangle(h.length(), "bothSides");
1339
+ for (let b = 0; b < a.length; b++)
1340
+ if (a[b].intersectRectangle(f)) {
1341
+ d = new L(
1342
+ h.start.clone(),
1343
+ h.start.clone().add(l.clone().multiplyScalar(-h.length()))
1624
1344
  );
1625
1345
  break;
1626
1346
  }
1627
- }
1628
- door.expansion(-doorThickness * 0.5).expandToRectangle(this.width * 0.2, "bothSides").path2D((p1, p2) => drawLine(p1, p2));
1629
- const a = line.length(), b = door.length(), r = (a ** 2 + b ** 2) / (2 * b), center = door.end.clone().add(door.direction().multiplyScalar(-r)), [startAngle, endAngle] = this.getArcAngleRange(center, line.end, door.end);
1630
- d.drawArc(center.x * s, center.y * s, r * s, Math.min(startAngle, endAngle), Math.max(startAngle, endAngle));
1631
- list.push(box);
1632
- } else {
1633
- line.clone().expansion(-this.width * 0.5).expandToRectangle(this.width).path2D((p1, p2) => drawLine(p1, p2));
1634
- line.clone().directionMove(line.normal(), doorThickness * 0.5).directionMove(line.direction(), doorThickness * 0.5).expansion(-line.length() * 0.45, "end").forward(doorThickness * 0.5).expandToRectangle(doorThickness).path2D((p1, p2) => drawLine(p1, p2));
1635
- line.clone().directionMove(line.normal(), -doorThickness * 0.5).directionMove(line.direction(), -doorThickness * 0.5).expansion(-line.length() * 0.45, "start").forward(-doorThickness * 0.5).expandToRectangle(doorThickness).path2D((p1, p2) => drawLine(p1, p2));
1636
- }
1637
- });
1638
- d.addLayer("l_yellow", Drawing.ACI.YELLOW, "DOTTED");
1639
- d.setActiveLayer("l_yellow");
1640
- this.lineSegments.forEach((line) => {
1641
- if (!line.userData.isWindow) return false;
1642
- if (Array.isArray(line.userData.drawDoorData)) {
1643
- line.userData.drawDoorData.forEach((w) => {
1644
- const { p, width } = w;
1645
- const center = Point.from(p);
1646
- const start = center.clone().add(line.direction().multiplyScalar(width * 0.5));
1647
- const end = center.clone().add(line.direction().multiplyScalar(-width * 0.5));
1648
- const blinds = new LineSegment(start, end);
1649
- drawLine(blinds.start, blinds.end);
1650
- blinds.expandToRectangle(this.width, "bothSides").path2D((p1, p2) => drawLine(p1, p2));
1651
- });
1652
- }
1653
- });
1654
- return d.toDxfString();
1347
+ d.expansion(-r * 0.5).expandToRectangle(this.width * 0.2, "bothSides").path2D((b, P) => s(b, P));
1348
+ const m = h.length(), y = d.length(), u = (m ** 2 + y ** 2) / (2 * y), x = d.end.clone().add(d.direction().multiplyScalar(-u)), [w, S] = this.getArcAngleRange(x, h.end, d.end);
1349
+ o(x, u, Math.min(w, S), Math.max(w, S)), a.push(f);
1350
+ } else
1351
+ h.clone().expansion(-this.width * 0.5).expandToRectangle(this.width).path2D((l, d) => s(l, d)), h.clone().directionMove(h.normal(), r * 0.5).directionMove(h.direction(), r * 0.5).expansion(-h.length() * 0.45, "end").forward(r * 0.5).expandToRectangle(r).path2D((l, d) => s(l, d)), h.clone().directionMove(h.normal(), -r * 0.5).directionMove(h.direction(), -r * 0.5).expansion(-h.length() * 0.45, "start").forward(-r * 0.5).expandToRectangle(r).path2D((l, d) => s(l, d));
1352
+ }), i = "yellow", this.lineSegments.forEach((c) => {
1353
+ if (!c.userData.isWindow) return !1;
1354
+ Array.isArray(c.userData.drawWindow) && c.userData.drawWindow.forEach((h) => {
1355
+ const { p: l, width: d } = h, f = p.from(l), m = f.clone().add(c.direction().multiplyScalar(d * 0.5)), y = f.clone().add(c.direction().multiplyScalar(-d * 0.5)), u = new L(m, y);
1356
+ s(u.start, u.end), u.expandToRectangle(this.width, "bothSides").path2D((x, w) => s(x, w));
1357
+ });
1358
+ }), n;
1359
+ }
1360
+ /**
1361
+ *
1362
+ * @param type
1363
+ */
1364
+ async toDxfImageBlob(t = "Centimeters", e = "image/jpeg", n = "#000") {
1365
+ const i = this.toDrawDataJson(t);
1366
+ let s;
1367
+ if (typeof window < "u")
1368
+ s = document.createElement("canvas");
1369
+ else if (typeof global < "u") {
1370
+ const { createCanvas: c } = await G("canvas");
1371
+ s = c();
1372
+ } else
1373
+ throw new Error("创建画布失败");
1374
+ const o = 2 * i.scale, r = {
1375
+ cyan: "cyan",
1376
+ yellow: "yellow",
1377
+ white: "white"
1378
+ };
1379
+ s.width = i.width + o * 2, s.height = i.height + o * 2;
1380
+ const a = s.getContext("2d");
1381
+ return n && (a.fillStyle = n, a.fillRect(0, 0, s.width, s.height)), a.translate(i.width * 0.5 + o, i.height * 0.5 + o), i.line.forEach(([c, h, l, d, f]) => {
1382
+ a.strokeStyle = r[f], a.beginPath(), a.moveTo(c, h), a.lineTo(l, d), a.closePath(), a.stroke();
1383
+ }), i.arc.forEach(([c, h, l, d, f, m]) => {
1384
+ a.strokeStyle = r[m], a.beginPath(), a.arc(c, h, l, d * (Math.PI / 180), f * (Math.PI / 180)), a.stroke();
1385
+ }), a.beginPath(), i.dimensionLine.forEach((c) => {
1386
+ let [h, l, d, f] = c;
1387
+ const m = Math.min(l, f), y = Math.max(l, f), u = (s.width * 0.5 - 0.4 * i.scale) * (h < 0 ? -1 : 1), x = (y - m) * 0.45;
1388
+ a.fillStyle = "#fff", a.font = `${0.15 * i.scale}px Arial`, a.textAlign = "center", a.textBaseline = "middle", a.fillText((y - m).toFixed(2) + "cm", u, m + (y - m) * 0.5), a.moveTo(u - 0.1 * i.scale, m), a.lineTo(u + 0.1 * i.scale, m), a.moveTo(u, m), a.lineTo(u, x + m), a.moveTo(u, y), a.lineTo(u, y - x), a.moveTo(u - 0.1 * i.scale, y), a.lineTo(u + 0.1 * i.scale, y);
1389
+ }), a.closePath(), a.strokeStyle = "#fff", a.stroke(), "toBlob" in s ? new Promise((c) => {
1390
+ s.toBlob((h) => {
1391
+ c(h);
1392
+ }, e, 1);
1393
+ }) : s.toBuffer(e, { quality: 1 });
1394
+ }
1395
+ /**
1396
+ * 将点json结构转换为Dxf string
1397
+ */
1398
+ toDxfString(t = "Millimeters") {
1399
+ const e = new R();
1400
+ e.setUnits(t), e.addLayer("cyan", R.ACI.CYAN, "DOTTED"), e.addLayer("yellow", R.ACI.YELLOW, "DOTTED"), e.addLayer("white", R.ACI.WHITE, "DOTTED");
1401
+ const n = this.toDrawDataJson();
1402
+ return n.line.forEach((i) => {
1403
+ let [s, o, r, a, c] = i;
1404
+ e.setActiveLayer(c), e.drawLine(s, o, r, a);
1405
+ }), n.arc.forEach((i) => {
1406
+ const [s, o, r, a, c, h] = i;
1407
+ e.setActiveLayer(h), e.drawArc(s, o, r, a, c);
1408
+ }), e.toDxfString();
1655
1409
  }
1656
1410
  /**
1657
1411
  * 将点云结构转换为DXF格式
1658
1412
  * @returns
1659
1413
  */
1660
- toDxfBlob(unit = "Millimeters") {
1661
- const blob = new Blob([this.toDxfString(unit)]);
1662
- return blob;
1414
+ toDxfBlob(t = "Millimeters") {
1415
+ return new Blob([this.toDxfString(t)]);
1663
1416
  }
1664
1417
  /**
1665
1418
  * 下载
1666
1419
  * @param filename
1667
1420
  */
1668
- async download(filename, unit = "Millimeters") {
1669
- if (typeof window !== "undefined") {
1670
- const blob = this.toDxfBlob(unit);
1671
- const a = document.createElement("a");
1672
- a.href = URL.createObjectURL(blob);
1673
- a.download = filename + ".dxf";
1674
- a.click();
1675
- } else if (typeof global !== "undefined") {
1676
- const fs = await include("fs", false);
1677
- fs.writeFileSync(filename, this.toDxfString(unit));
1678
- }
1421
+ async download(t, e = "Millimeters") {
1422
+ if (typeof window < "u") {
1423
+ const n = this.toDxfBlob(e), i = document.createElement("a");
1424
+ i.href = URL.createObjectURL(n), i.download = t + ".dxf", i.click();
1425
+ } else typeof global < "u" && (await G("fs", !1)).writeFileSync(t, this.toDxfString(e));
1426
+ }
1427
+ /**
1428
+ * 下载
1429
+ * @param filename
1430
+ */
1431
+ async downloadImage(t, e = "Centimeters", n = "image/jpeg") {
1432
+ const i = await this.toDxfImageBlob(e, n);
1433
+ if (!i) return !1;
1434
+ if (typeof window < "u") {
1435
+ const s = document.createElement("a");
1436
+ s.href = URL.createObjectURL(i), s.download = t, s.click();
1437
+ } else typeof global < "u" ? (await G("fs", !1)).writeFileSync(t, i) : console.error("图片下载失败");
1438
+ return !0;
1679
1439
  }
1680
1440
  /**
1681
1441
  * 计算原始数据的边界框
1682
1442
  * @description 计算所有线段的起点和终点的最小最大值,形成一个边界框
1683
1443
  * @returns
1684
1444
  */
1685
- computedOriginalSize(data, originalBox = new Box2(0, 0, 0, 0)) {
1686
- const xArr = data.flatMap((item) => [item.start.x, item.end.x]);
1687
- const yArr = data.flatMap((item) => [item.start.y, item.end.y]);
1688
- const minX = Math.min(...xArr);
1689
- const minY = Math.min(...yArr);
1690
- const maxX = Math.max(...xArr);
1691
- const maxY = Math.max(...yArr);
1692
- originalBox.set(minX, minY, maxX, maxY);
1693
- return originalBox;
1445
+ computedOriginalSize(t, e = new v(0, 0, 0, 0)) {
1446
+ const n = t.flatMap((c) => [c.start.x, c.end.x]), i = t.flatMap((c) => [c.start.y, c.end.y]), s = Math.min(...n), o = Math.min(...i), r = Math.max(...n), a = Math.max(...i);
1447
+ return e.set(s, o, r, a), e;
1694
1448
  }
1695
1449
  /**
1696
1450
  * 创建数据
1697
1451
  * @param pointsGroups
1698
1452
  * @returns
1699
1453
  */
1700
- static createData(pointsGroups, sealed = true) {
1701
- let count = 0;
1702
- const data = pointsGroups.flatMap((points) => {
1703
- const lines = points.map((point, index2) => {
1704
- const nextIndex = index2 === points.length - 1 ? 0 : index2 + 1;
1705
- const nextPoint = points[nextIndex];
1454
+ static createData(t, e = !0) {
1455
+ let n = 0;
1456
+ return t.flatMap((s) => {
1457
+ const o = s.map((r, a) => {
1458
+ const c = a === s.length - 1 ? 0 : a + 1, h = s[c];
1706
1459
  return {
1707
- start: { x: point.x, y: point.y },
1708
- end: { x: nextPoint.x, y: nextPoint.y },
1460
+ start: { x: r.x, y: r.y },
1461
+ end: { x: h.x, y: h.y },
1709
1462
  insetionArr: [
1710
1463
  {
1711
- index: nextIndex + count
1464
+ index: c + n
1712
1465
  }
1713
1466
  ]
1714
1467
  };
1715
1468
  });
1716
- count += points.length;
1717
- if (!sealed) {
1718
- lines.pop();
1719
- lines[lines.length - 1].insetionArr.length = 0;
1720
- count--;
1469
+ return n += s.length, e || (o.pop(), o[o.length - 1].insetionArr.length = 0, n--), o;
1470
+ });
1471
+ }
1472
+ }
1473
+ function V(g) {
1474
+ if (g === null || typeof g != "object") return g;
1475
+ if (g instanceof Date) return new Date(g.getTime());
1476
+ if (Array.isArray(g)) return g.map(V);
1477
+ const t = {};
1478
+ for (const e in g)
1479
+ Object.prototype.hasOwnProperty.call(g, e) && (t[e] = V(g[e]));
1480
+ return t;
1481
+ }
1482
+ const I = new L();
1483
+ class ot extends X {
1484
+ static name = "AngleCorrectionDxf";
1485
+ onAddFromParent(t) {
1486
+ t.findComponentByName("LineAnalysis").addEventListener("analysisCompleted", async () => this.update());
1487
+ }
1488
+ async update() {
1489
+ const t = this.parent, e = t.findComponentByName("Dxf"), n = t.findComponentByName("LineAnalysis");
1490
+ let i = 0, s = null;
1491
+ for (let c = 0; c < e.originalData.length; c++) {
1492
+ const h = e.originalData[c];
1493
+ if (I.start.copy(h.start), I.end.copy(h.end), h.isVerticalReferenceLine) {
1494
+ const [l, d] = h.start.y < h.end.y ? [I.start, I.end] : [I.end, I.start];
1495
+ i = -new L(l, d).direction().angleBetween(new p(0, 1), "angle", "360"), s = null;
1496
+ break;
1721
1497
  }
1722
- return lines;
1498
+ (!s || I.length() > s.length()) && (s = I.clone(), s.userData.index = c);
1499
+ }
1500
+ if (s) {
1501
+ e.originalData[s.userData.index].isVerticalReferenceLine = !0;
1502
+ const [c, h] = s.start.y < s.end.y ? [s.start, s.end] : [s.end, s.start];
1503
+ i = -new L(c, h).direction().angleBetween(new p(0, 1), "angle", "360");
1504
+ }
1505
+ const o = e.originalBox.center, r = p.zero(), a = e.originalData.map((c) => {
1506
+ const h = r.copy(c.start).division(o).rotate(p.zero(), i * (Math.PI / 180)).toJson(c.start.z), l = r.copy(c.end).division(o).rotate(p.zero(), i * (Math.PI / 180)).toJson(c.end.z), d = Object.assign(V(c), { start: h, end: l });
1507
+ return d.drawWindow && d.drawWindow.forEach((f) => {
1508
+ f.p = r.copy(f.p).division(o).rotate(p.zero(), i * (Math.PI / 180)).toJson(f.p.z), f.p.y = -f.p.y;
1509
+ }), d;
1510
+ });
1511
+ n.appendLineSegmentList.forEach((c) => {
1512
+ const h = c.clone();
1513
+ h.start.division(o).rotate(p.zero(), i * (Math.PI / 180)), h.end.division(o).rotate(p.zero(), i * (Math.PI / 180)), a.push({
1514
+ start: h.start.toJson(e.originalZAverage),
1515
+ end: h.end.toJson(e.originalZAverage),
1516
+ insetionArr: [],
1517
+ length: h.length()
1518
+ });
1519
+ }), a.forEach((c) => {
1520
+ c.start.y = -c.start.y, c.end.y = -c.end.y;
1521
+ }), await this.set(a, e.width, e.scale), this.lineOffset(), this.doorLineSegment = e.doorLineSegment.map((c) => {
1522
+ const h = c.clone();
1523
+ return h.start.division(o).rotate(p.zero(), i * (Math.PI / 180)), h.end.division(o).rotate(p.zero(), i * (Math.PI / 180)), h.start.y = -h.start.y, h.end.y = -h.end.y, h;
1723
1524
  });
1724
- return data;
1725
1525
  }
1726
1526
  }
1727
- class Variable extends Component {
1527
+ class _ extends q {
1728
1528
  static name = "Variable";
1729
- originalLineVisible = true;
1730
- dxfVisible = true;
1731
- whiteModelVisible = true;
1732
- isLook = false;
1529
+ originalLineVisible = !0;
1530
+ dxfVisible = !0;
1531
+ whiteModelVisible = !0;
1532
+ isLook = !1;
1733
1533
  currentWheel = 0;
1734
1534
  pointerMove = { x: 0, y: 0 };
1735
1535
  currentKeyUp = "";
1736
1536
  currentKeyDown = "";
1737
1537
  currentMouseUp = "";
1738
1538
  currentMouseDown = "";
1739
- focus = false;
1740
- set(key, value) {
1741
- if (key in this) {
1742
- const oldValue = this[key];
1743
- this[key] = value;
1744
- this.dispatchEvent({
1745
- type: key,
1746
- value,
1747
- oldValue
1539
+ focus = !1;
1540
+ set(t, e) {
1541
+ if (t in this) {
1542
+ const n = this[t];
1543
+ this[t] = e, this.dispatchEvent({
1544
+ type: t,
1545
+ value: e,
1546
+ oldValue: n
1748
1547
  });
1749
1548
  }
1750
1549
  }
1751
- get(key) {
1752
- if (key in this) return this[key];
1550
+ get(t) {
1551
+ if (t in this) return this[t];
1753
1552
  }
1754
1553
  }
1755
- class Quadtree {
1554
+ class j {
1756
1555
  bounds;
1757
1556
  // 包围盒
1758
1557
  capacity;
@@ -1761,7 +1560,7 @@ class Quadtree {
1761
1560
  // 最大深度
1762
1561
  depth;
1763
1562
  // 当前深度
1764
- isLeaf = true;
1563
+ isLeaf = !0;
1765
1564
  // 是否为叶子节点
1766
1565
  children = null;
1767
1566
  // 子节点数组
@@ -1769,110 +1568,72 @@ class Quadtree {
1769
1568
  // 存储的节点
1770
1569
  color = [Math.random(), Math.random(), Math.random()];
1771
1570
  // 颜色
1772
- constructor(bounds, capacity = 8, maxDepth = 10, depth = 1) {
1773
- this.bounds = bounds;
1774
- this.capacity = capacity;
1775
- this.depth = depth;
1776
- this.maxDepth = maxDepth;
1571
+ constructor(t, e = 8, n = 10, i = 1) {
1572
+ this.bounds = t, this.capacity = e, this.depth = i, this.maxDepth = n;
1777
1573
  }
1778
1574
  /**
1779
1575
  * 插入线段节点
1780
1576
  * @param node 线段节点
1781
1577
  */
1782
- insert(node) {
1578
+ insert(t) {
1783
1579
  if (!this.isLeaf) {
1784
- const quadrant = this.getQuadrant(node.line);
1785
- if (quadrant !== -1) {
1786
- this.children[quadrant].insert(node);
1580
+ const e = this.getQuadrant(t.line);
1581
+ if (e !== -1) {
1582
+ this.children[e].insert(t);
1787
1583
  return;
1788
1584
  }
1789
1585
  }
1790
- this.nodes.push(node);
1791
- node.parent = this;
1792
- if (this.isLeaf && this.nodes.length > this.capacity && this.depth < this.maxDepth) {
1586
+ if (this.nodes.push(t), t.parent = this, this.isLeaf && this.nodes.length > this.capacity && this.depth < this.maxDepth) {
1793
1587
  this.subdivide();
1794
- const nodes = this.nodes;
1588
+ const e = this.nodes;
1795
1589
  this.nodes = [];
1796
- for (const n of nodes) {
1797
- const quadrant = this.getQuadrant(n.line);
1798
- if (quadrant !== -1) {
1799
- this.children[quadrant].insert(n);
1800
- } else {
1801
- n.parent = this;
1802
- this.nodes.push(n);
1803
- }
1590
+ for (const n of e) {
1591
+ const i = this.getQuadrant(n.line);
1592
+ i !== -1 ? this.children[i].insert(n) : (n.parent = this, this.nodes.push(n));
1804
1593
  }
1805
1594
  }
1806
1595
  }
1807
1596
  /** 移除
1808
1597
  * @param node
1809
1598
  */
1810
- remove(node) {
1811
- const index2 = node.parent?.nodes.indexOf(node);
1812
- if (index2 > -1) {
1813
- node.parent?.nodes.splice(index2, 1);
1814
- }
1599
+ remove(t) {
1600
+ const e = t.parent?.nodes.indexOf(t);
1601
+ e > -1 && t.parent?.nodes.splice(e, 1);
1815
1602
  }
1816
1603
  /**
1817
1604
  * 获取线段所属的象限
1818
1605
  * @param line 线段
1819
1606
  * @returns 象限索引(0:西北,1:东北,2:西南,3:东南)或-1(跨多个象限)
1820
1607
  */
1821
- getQuadrant(line) {
1822
- const intersectsNW = this.children[0].bounds.intersectLineSegment(line);
1823
- const intersectsNE = this.children[1].bounds.intersectLineSegment(line);
1824
- const intersectsSW = this.children[2].bounds.intersectLineSegment(line);
1825
- const intersectsSE = this.children[3].bounds.intersectLineSegment(line);
1826
- let count = 0;
1827
- let quadrant = -1;
1828
- if (intersectsNW) {
1829
- count++;
1830
- quadrant = 0;
1831
- }
1832
- if (intersectsNE) {
1833
- count++;
1834
- quadrant = 1;
1835
- }
1836
- if (intersectsSW) {
1837
- count++;
1838
- quadrant = 2;
1839
- }
1840
- if (intersectsSE) {
1841
- count++;
1842
- quadrant = 3;
1843
- }
1844
- if (count === 1) return quadrant;
1845
- return -1;
1608
+ getQuadrant(t) {
1609
+ const e = this.children[0].bounds.intersectLineSegment(t), n = this.children[1].bounds.intersectLineSegment(t), i = this.children[2].bounds.intersectLineSegment(t), s = this.children[3].bounds.intersectLineSegment(t);
1610
+ let o = 0, r = -1;
1611
+ return e && (o++, r = 0), n && (o++, r = 1), i && (o++, r = 2), s && (o++, r = 3), o === 1 ? r : -1;
1846
1612
  }
1847
1613
  /**
1848
1614
  * 细分当前节点为四个子节点
1849
1615
  */
1850
1616
  subdivide() {
1851
1617
  if (!this.isLeaf) return;
1852
- this.isLeaf = false;
1853
- this.children = [];
1854
- const midX = (this.bounds.minX + this.bounds.maxX) / 2;
1855
- const midY = (this.bounds.minY + this.bounds.maxY) / 2;
1856
- this.children[0] = new Quadtree(
1857
- new Box2(this.bounds.minX, midX, this.bounds.minY, midY),
1618
+ this.isLeaf = !1, this.children = [];
1619
+ const t = (this.bounds.minX + this.bounds.maxX) / 2, e = (this.bounds.minY + this.bounds.maxY) / 2;
1620
+ this.children[0] = new j(
1621
+ new v(this.bounds.minX, t, this.bounds.minY, e),
1858
1622
  this.capacity,
1859
1623
  this.maxDepth,
1860
1624
  this.depth + 1
1861
- );
1862
- this.children[1] = new Quadtree(
1863
- new Box2(midX, this.bounds.maxX, this.bounds.minY, midY),
1625
+ ), this.children[1] = new j(
1626
+ new v(t, this.bounds.maxX, this.bounds.minY, e),
1864
1627
  this.capacity,
1865
1628
  this.maxDepth,
1866
1629
  this.depth + 1
1867
- );
1868
- this.children[2] = new Quadtree(
1869
- new Box2(this.bounds.minX, midX, midY, this.bounds.maxY),
1630
+ ), this.children[2] = new j(
1631
+ new v(this.bounds.minX, t, e, this.bounds.maxY),
1870
1632
  this.capacity,
1871
1633
  this.maxDepth,
1872
1634
  this.depth + 1
1873
- );
1874
- this.children[3] = new Quadtree(
1875
- new Box2(midX, this.bounds.maxX, midY, this.bounds.maxY),
1635
+ ), this.children[3] = new j(
1636
+ new v(t, this.bounds.maxX, e, this.bounds.maxY),
1876
1637
  this.capacity,
1877
1638
  this.maxDepth,
1878
1639
  this.depth + 1
@@ -1883,22 +1644,16 @@ class Quadtree {
1883
1644
  * @param box2 包围盒
1884
1645
  * @returns 相交的节点数组
1885
1646
  */
1886
- queryBox(box2) {
1887
- const result = [];
1888
- if (!this.bounds.intersectBox(box2)) {
1889
- return result;
1890
- }
1891
- for (const node of this.nodes) {
1892
- if (box2.intersectLineSegment(node.line)) {
1893
- result.push(node);
1894
- }
1895
- }
1896
- if (!this.isLeaf) {
1897
- for (const child of this.children) {
1898
- result.push(...child.queryBox(box2));
1899
- }
1900
- }
1901
- return result;
1647
+ queryBox(t) {
1648
+ const e = [];
1649
+ if (!this.bounds.intersectBox(t))
1650
+ return e;
1651
+ for (const n of this.nodes)
1652
+ t.intersectLineSegment(n.line) && e.push(n);
1653
+ if (!this.isLeaf)
1654
+ for (const n of this.children)
1655
+ e.push(...n.queryBox(t));
1656
+ return e;
1902
1657
  }
1903
1658
  /**
1904
1659
  * 查询与圆形区域相交的线段节点
@@ -1906,81 +1661,58 @@ class Quadtree {
1906
1661
  * @param radius 半径
1907
1662
  * @returns 相交的节点数组
1908
1663
  */
1909
- queryCircle(pos, radius) {
1910
- const result = [];
1911
- const circleBox = new Box2(
1912
- pos.x - radius,
1913
- pos.x + radius,
1914
- pos.y - radius,
1915
- pos.y + radius
1664
+ queryCircle(t, e) {
1665
+ const n = [], i = new v(
1666
+ t.x - e,
1667
+ t.x + e,
1668
+ t.y - e,
1669
+ t.y + e
1916
1670
  );
1917
- if (!this.bounds.intersectBox(circleBox)) {
1918
- return result;
1671
+ if (!this.bounds.intersectBox(i))
1672
+ return n;
1673
+ for (const s of this.nodes) {
1674
+ const [o, r] = s.line.points, a = r.x - o.x, c = r.y - o.y, h = a * a + c * c;
1675
+ let l = ((t.x - o.x) * a + (t.y - o.y) * c) / h;
1676
+ l = Math.max(0, Math.min(1, l));
1677
+ const d = o.x + l * a, f = o.y + l * c;
1678
+ t.distance(new p(d, f)) <= e && n.push(s);
1919
1679
  }
1920
- for (const node of this.nodes) {
1921
- const [p1, p2] = node.line.points;
1922
- const dx = p2.x - p1.x;
1923
- const dy = p2.y - p1.y;
1924
- const l2 = dx * dx + dy * dy;
1925
- let t = ((pos.x - p1.x) * dx + (pos.y - p1.y) * dy) / l2;
1926
- t = Math.max(0, Math.min(1, t));
1927
- const closestX = p1.x + t * dx;
1928
- const closestY = p1.y + t * dy;
1929
- const distance = pos.distance(new Point(closestX, closestY));
1930
- if (distance <= radius) {
1931
- result.push(node);
1932
- }
1933
- }
1934
- if (!this.isLeaf) {
1935
- for (const child of this.children) {
1936
- result.push(...child.queryCircle(pos, radius));
1937
- }
1938
- }
1939
- return result;
1680
+ if (!this.isLeaf)
1681
+ for (const s of this.children)
1682
+ n.push(...s.queryCircle(t, e));
1683
+ return n.sort((s) => s.line.length()), n;
1940
1684
  }
1941
1685
  /**
1942
1686
  * 查询与矩形相交的线段节点
1943
1687
  * @param rectangle 矩形
1944
1688
  * @returns 相交的节点数组
1945
1689
  */
1946
- queryRect(rectangle) {
1947
- const result = [];
1948
- if (!this.bounds.intersectRectangle(rectangle)) {
1949
- return result;
1950
- }
1951
- for (const node of this.nodes) {
1952
- if (rectangle.intersectLineSegment(node.line)) {
1953
- result.push(node);
1954
- }
1955
- }
1956
- if (!this.isLeaf) {
1957
- for (const child of this.children) {
1958
- result.push(...child.queryRect(rectangle));
1959
- }
1960
- }
1961
- return result;
1690
+ queryRect(t) {
1691
+ const e = [];
1692
+ if (!this.bounds.intersectRectangle(t))
1693
+ return e;
1694
+ for (const n of this.nodes)
1695
+ t.intersectLineSegment(n.line) && e.push(n);
1696
+ if (!this.isLeaf)
1697
+ for (const n of this.children)
1698
+ e.push(...n.queryRect(t));
1699
+ return e;
1962
1700
  }
1963
1701
  /**
1964
1702
  * 查询与线段相交的线段节点
1965
1703
  * @param lineSegment 线段
1966
1704
  * @returns 相交的节点数组
1967
1705
  */
1968
- queryLineSegment(lineSegment) {
1969
- const result = [];
1970
- if (!this.bounds.intersectLineSegment(lineSegment)) {
1971
- return result;
1972
- }
1973
- for (const node of this.nodes) {
1974
- if (lineSegment.intersectLineSegment(node.line)) {
1975
- result.push(node);
1976
- }
1977
- }
1978
- if (!this.isLeaf) {
1979
- for (const child of this.children) {
1980
- result.push(...child.queryLineSegment(lineSegment));
1981
- }
1982
- }
1983
- return result;
1706
+ queryLineSegment(t, e = !0) {
1707
+ const n = [];
1708
+ if (!this.bounds.intersectLineSegment(t))
1709
+ return n;
1710
+ for (const i of this.nodes)
1711
+ t.intersectLineSegment(i.line, e) && n.push(i);
1712
+ if (!this.isLeaf)
1713
+ for (const i of this.children)
1714
+ n.push(...i.queryLineSegment(t));
1715
+ return n;
1984
1716
  }
1985
1717
  /**
1986
1718
  * 包围盒转换为数组
@@ -1988,96 +1720,80 @@ class Quadtree {
1988
1720
  * @param colors
1989
1721
  * @returns
1990
1722
  */
1991
- boundsToArray(array = [], colors, recursion = true) {
1992
- if (!this.isLeaf && recursion) {
1993
- this.children?.forEach((child) => child.boundsToArray(array, colors));
1994
- }
1995
- array.push(...this.bounds.points.flatMap((p, i, array2) => {
1996
- const np = array2[(i + 1) % array2.length];
1997
- colors?.push(...this.color);
1998
- colors?.push(...this.color);
1999
- return [p.x, p.y, 0, np.x, np.y, 0];
2000
- }));
2001
- return array;
1723
+ boundsToArray(t = [], e, n = !0) {
1724
+ return !this.isLeaf && n && this.children?.forEach((i) => i.boundsToArray(t, e)), t.push(...this.bounds.points.flatMap((i, s, o) => {
1725
+ const r = o[(s + 1) % o.length];
1726
+ return e?.push(...this.color), e?.push(...this.color), [i.x, i.y, 0, r.x, r.y, 0];
1727
+ })), t;
2002
1728
  }
2003
1729
  }
2004
- class PointVirtualGrid {
1730
+ class U {
2005
1731
  map = /* @__PURE__ */ new Map();
2006
1732
  gridSize;
2007
- constructor(gridSize = 2) {
2008
- this.gridSize = gridSize;
1733
+ constructor(t = 2) {
1734
+ this.gridSize = t;
2009
1735
  }
2010
1736
  /**
2011
1737
  * 插入
2012
1738
  * @param point
2013
1739
  * @param userData
2014
1740
  */
2015
- insert(point, userData) {
2016
- if (!point || isNaN(point.x) || isNaN(point.y)) {
1741
+ insert(t, e) {
1742
+ if (!t || isNaN(t.x) || isNaN(t.y))
2017
1743
  throw new Error("无效的点坐标");
2018
- }
2019
- const id = this.getGridId(point);
2020
- if (!this.map.has(id)) this.map.set(id, /* @__PURE__ */ new Set());
2021
- const set = this.map.get(id);
2022
- const target = { point, userData };
2023
- set.add(target);
2024
- point.userData.pointVirtualGrid = { set, target };
1744
+ const n = this.getGridId(t);
1745
+ this.map.has(n) || this.map.set(n, /* @__PURE__ */ new Set());
1746
+ const i = this.map.get(n), s = { point: t, userData: e };
1747
+ i.add(s), t.userData.pointVirtualGrid = { set: i, target: s };
2025
1748
  }
2026
1749
  /**
2027
1750
  * 批量加入
2028
1751
  * @param points
2029
1752
  */
2030
- insertBatch(points) {
2031
- for (const { point, userData } of points) {
2032
- this.insert(point, userData);
2033
- }
1753
+ insertBatch(t) {
1754
+ for (const { point: e, userData: n } of t)
1755
+ this.insert(e, n);
2034
1756
  }
2035
1757
  /** 移除点
2036
1758
  * @param point
2037
1759
  */
2038
- remove(point) {
2039
- const { set, target } = point?.userData?.pointVirtualGrid;
2040
- if (set) {
2041
- set.delete(target);
2042
- delete point?.userData?.pointVirtualGridMap;
2043
- }
1760
+ remove(t) {
1761
+ const { set: e, target: n } = t?.userData?.pointVirtualGrid;
1762
+ e && (e.delete(n), delete t?.userData?.pointVirtualGridMap);
2044
1763
  }
2045
1764
  /**
2046
1765
  * 获取通过坐标,获取唯一网格索引
2047
1766
  * @param point
2048
1767
  * @returns
2049
1768
  */
2050
- getGridId(point) {
2051
- const i = Math.ceil(point.x / this.gridSize), j = Math.ceil(point.y / this.gridSize);
2052
- return `${i}.${j}`;
1769
+ getGridId(t) {
1770
+ const e = Math.ceil(t.x / this.gridSize), n = Math.ceil(t.y / this.gridSize);
1771
+ return `${e}.${n}`;
2053
1772
  }
2054
1773
  /**
2055
1774
  *
2056
1775
  * @param gridId
2057
1776
  * @returns
2058
1777
  */
2059
- decodeGridId(gridId) {
2060
- const [i, j] = gridId.split(".").map(Number);
2061
- return new Point(i, j);
1778
+ decodeGridId(t) {
1779
+ const [e, n] = t.split(".").map(Number);
1780
+ return new p(e, n);
2062
1781
  }
2063
1782
  /**
2064
1783
  * 查询与矩形相交的点
2065
1784
  * @param rectangle 矩形
2066
1785
  * @returns 相交的节点数组
2067
1786
  */
2068
- queryRect(rectangle) {
2069
- const box2 = rectangle.toBox();
2070
- const minI = Math.ceil(box2.minX / this.gridSize), maxI = Math.ceil(box2.maxX / this.gridSize), minJ = Math.ceil(box2.minY / this.gridSize), maxJ = Math.ceil(box2.maxY / this.gridSize);
2071
- for (let i = minI; i <= maxI; i++) {
2072
- for (let j = minJ; j <= maxJ; j++) {
2073
- const id = `${i}.${j}`;
2074
- if (!this.map.has(id)) continue;
2075
- const set = this.map.get(id);
2076
- set?.forEach((item) => {
2077
- if (rectangle.containsPoint(item.point)) ;
1787
+ queryRect(t) {
1788
+ const e = t.toBox(), n = Math.ceil(e.minX / this.gridSize), i = Math.ceil(e.maxX / this.gridSize), s = Math.ceil(e.minY / this.gridSize), o = Math.ceil(e.maxY / this.gridSize);
1789
+ for (let r = n; r <= i; r++)
1790
+ for (let a = s; a <= o; a++) {
1791
+ const c = `${r}.${a}`;
1792
+ if (!this.map.has(c)) continue;
1793
+ this.map.get(c)?.forEach((l) => {
1794
+ t.containsPoint(l.point);
2078
1795
  });
2079
1796
  }
2080
- }
2081
1797
  }
2082
1798
  /**
2083
1799
  * 查询与圆形区域相交的点
@@ -2085,62 +1801,60 @@ class PointVirtualGrid {
2085
1801
  * @param radius 半径
2086
1802
  * @returns 相交的节点数组
2087
1803
  */
2088
- queryCircle(pos, radius) {
2089
- const box2 = new Box2(pos.x - radius, pos.x + radius, pos.y - radius, pos.y + radius);
2090
- const minI = Math.ceil(box2.minX / this.gridSize), maxI = Math.ceil(box2.maxX / this.gridSize), minJ = Math.ceil(box2.minY / this.gridSize), maxJ = Math.ceil(box2.maxY / this.gridSize), list = [];
2091
- for (let i = minI; i <= maxI; i++) {
2092
- for (let j = minJ; j <= maxJ; j++) {
2093
- const id = `${i}.${j}`;
2094
- if (!this.map.has(id)) continue;
2095
- const set = this.map.get(id);
2096
- set?.forEach((item) => {
2097
- if (pos.distance(item.point) <= radius) list.push(item);
1804
+ queryCircle(t, e) {
1805
+ const n = new v(t.x - e, t.x + e, t.y - e, t.y + e), i = Math.ceil(n.minX / this.gridSize), s = Math.ceil(n.maxX / this.gridSize), o = Math.ceil(n.minY / this.gridSize), r = Math.ceil(n.maxY / this.gridSize), a = [];
1806
+ for (let c = i; c <= s; c++)
1807
+ for (let h = o; h <= r; h++) {
1808
+ const l = `${c}.${h}`;
1809
+ if (!this.map.has(l)) continue;
1810
+ this.map.get(l)?.forEach((f) => {
1811
+ t.distance(f.point) <= e && a.push(f);
2098
1812
  });
2099
1813
  }
2100
- }
2101
- return list;
1814
+ return a;
2102
1815
  }
2103
1816
  /**
2104
1817
  * 查询与包围盒相交的点
2105
1818
  * @param box2 包围盒
2106
1819
  * @returns 相交的节点数组
2107
1820
  */
2108
- queryBox(box2) {
2109
- const minI = Math.ceil(box2.minX / this.gridSize), maxI = Math.ceil(box2.maxX / this.gridSize), minJ = Math.ceil(box2.minY / this.gridSize), maxJ = Math.ceil(box2.maxY / this.gridSize), list = [];
2110
- for (let i = minI; i <= maxI; i++) {
2111
- for (let j = minJ; j <= maxJ; j++) {
2112
- const id = `${i}.${j}`;
2113
- if (!this.map.has(id)) continue;
2114
- const set = this.map.get(id);
2115
- set?.forEach((item) => {
2116
- if (box2.containsPoint(item.point)) list.push(item);
1821
+ queryBox(t) {
1822
+ const e = Math.ceil(t.minX / this.gridSize), n = Math.ceil(t.maxX / this.gridSize), i = Math.ceil(t.minY / this.gridSize), s = Math.ceil(t.maxY / this.gridSize), o = [];
1823
+ for (let r = e; r <= n; r++)
1824
+ for (let a = i; a <= s; a++) {
1825
+ const c = `${r}.${a}`;
1826
+ if (!this.map.has(c)) continue;
1827
+ this.map.get(c)?.forEach((l) => {
1828
+ t.containsPoint(l.point) && o.push(l);
2117
1829
  });
2118
1830
  }
2119
- }
2120
- return list;
1831
+ return o;
2121
1832
  }
2122
1833
  /**
2123
1834
  * 查找相同点
2124
1835
  * @param point
2125
1836
  */
2126
- queryPoint(point) {
2127
- const id = this.getGridId(point), list = [];
2128
- if (this.map.has(id)) {
2129
- const set = this.map.get(id);
2130
- set?.forEach((item) => {
2131
- if (point.equal(item.point)) list.push(item);
2132
- });
2133
- }
2134
- return list;
1837
+ queryPoint(t) {
1838
+ const e = this.getGridId(t), n = [];
1839
+ return this.map.has(e) && this.map.get(e)?.forEach((s) => {
1840
+ t.equal(s.point) && n.push(s);
1841
+ }), n;
1842
+ }
1843
+ /**
1844
+ * 查找点自己
1845
+ * @param point
1846
+ */
1847
+ queryPointSelf(t) {
1848
+ return t.userData.pointVirtualGrid && t.userData.pointVirtualGrid.target ? t.userData.pointVirtualGrid.target : null;
2135
1849
  }
2136
1850
  }
2137
- class DoorsAnalysis {
1851
+ class rt {
2138
1852
  // 所有可查找的点位
2139
1853
  possibleDoorPoints = [];
2140
1854
  doorPoint = [];
2141
1855
  dxf;
2142
1856
  // 包含所有点的虚拟网格
2143
- pointVirtualGrid = new PointVirtualGrid();
1857
+ pointVirtualGrid = new U();
2144
1858
  // 只包含可查找点的虚拟网格
2145
1859
  findPointVirtualGrid;
2146
1860
  quadtree;
@@ -2151,158 +1865,111 @@ class DoorsAnalysis {
2151
1865
  doorSearchDistance = 2;
2152
1866
  doors = [];
2153
1867
  lineAnalysis;
2154
- continueFind = true;
2155
- constructor(lineAnalysis) {
2156
- this.lineAnalysis = lineAnalysis;
2157
- this.dxf = lineAnalysis.Dxf;
2158
- this.findPointVirtualGrid = new PointVirtualGrid();
2159
- this.quadtree = lineAnalysis.quadtree;
2160
- this.resultList = lineAnalysis.resultList;
2161
- this.lineSegments = lineAnalysis.lineSegmentList;
2162
- this.dxf.doorLineSegment.length = 0;
2163
- this.lineSegments.forEach((line) => {
2164
- this.pointVirtualGrid.insert(line.start, line);
2165
- this.pointVirtualGrid.insert(line.end, line);
2166
- });
2167
- this.doorPoint = this.getDoorPoint();
2168
- if (!this.continueFind) return;
2169
- const excludeIndexMap = this.searchDoubleLinePoint();
2170
- this.addPointsExcludeRule((line, _2, pointIndex) => {
2171
- const index2 = this.lineSegments.indexOf(line);
2172
- const excludeMode = excludeIndexMap.get(index2);
2173
- if (typeof excludeMode === "number") {
2174
- return excludeMode === -1 || excludeMode === pointIndex;
2175
- }
2176
- return false;
2177
- });
2178
- this.addPointsExcludeRule((_1, point) => {
2179
- return !!this.doorPoint.find((p1) => p1.point.equal(point));
2180
- });
2181
- this.possibleDoorPoints = this.getPossiblePoints();
2182
- this.possibleDoorPoints.forEach((p) => this.findPointVirtualGrid.insert(p.point, p.line));
2183
- this.handle();
1868
+ continueFind = !0;
1869
+ constructor(t) {
1870
+ if (this.lineAnalysis = t, this.dxf = t.Dxf, this.findPointVirtualGrid = new U(), this.quadtree = t.quadtree, this.resultList = t.resultList, this.lineSegments = t.lineSegmentList, this.dxf.doorLineSegment.length = 0, this.lineSegments.forEach((n) => {
1871
+ this.pointVirtualGrid.insert(n.start, n), this.pointVirtualGrid.insert(n.end, n);
1872
+ }), this.doorPoint = this.getDoorPoint(), !this.continueFind) return;
1873
+ const e = this.searchDoubleLinePoint();
1874
+ this.addPointsExcludeRule((n, i, s) => {
1875
+ const o = this.lineSegments.indexOf(n), r = e.get(o);
1876
+ return typeof r == "number" ? r === -1 || r === s : !1;
1877
+ }), this.addPointsExcludeRule((n, i) => !!this.doorPoint.find((s) => s.point.equal(i))), this.possibleDoorPoints = this.getPossiblePoints(), this.possibleDoorPoints.forEach((n) => this.findPointVirtualGrid.insert(n.point, n.line)), this.handle();
2184
1878
  }
2185
1879
  handle() {
2186
- this.dxf.doorLineSegment.push(...this.search(this.doorPoint, this.possibleDoorPoints, 0.5));
2187
- if (this.doorPoint.length < 2) this.dxf.doorLineSegment.push(...this.search(this.possibleDoorPoints, this.possibleDoorPoints, 0.6));
2188
- }
2189
- search(doorPoints, possibleDoorPoints = [], minDoorWidth = 0.6, doorSearchDistance = this.doorSearchDistance, doorSearchNearAngle = this.doorSearchNearAngle) {
2190
- const dxf = this.dxf;
2191
- const doors = this.searchNearby(doorPoints, possibleDoorPoints, doorSearchDistance, doorSearchNearAngle);
2192
- doors.push(
2193
- ...doorPoints.map((item) => {
2194
- const res2 = this.searchAlongDirection(item, doorSearchDistance);
2195
- if (res2) return {
2196
- start: item.point,
2197
- end: res2.point
1880
+ this.dxf.doorLineSegment.push(...this.search(this.doorPoint, this.possibleDoorPoints, 0.5)), this.doorPoint.length < 2 && this.dxf.doorLineSegment.push(...this.search(this.possibleDoorPoints, this.possibleDoorPoints, 0.6));
1881
+ }
1882
+ search(t, e = [], n = 0.6, i = this.doorSearchDistance, s = this.doorSearchNearAngle) {
1883
+ const o = this.dxf, r = this.searchNearby(t, e, i, s);
1884
+ r.push(
1885
+ ...t.map((c) => {
1886
+ const h = this.searchAlongDirection(c, i);
1887
+ if (h) return {
1888
+ start: c.point,
1889
+ end: h.point
2198
1890
  };
2199
- const res3 = this.searchAlongNormalDirection(item, doorSearchDistance);
2200
- if (res3) return {
2201
- start: item.point,
2202
- end: res3.point
1891
+ const l = this.searchAlongNormalDirection(c, i);
1892
+ if (l) return {
1893
+ start: c.point,
1894
+ end: l.point
2203
1895
  };
2204
- }).filter((i) => !!i && i.start.distance(i.end) < doorSearchDistance)
1896
+ }).filter((c) => !!c && c.start.distance(c.end) < i)
2205
1897
  );
2206
- const doorLineSegment = [];
2207
- doors.forEach((p) => {
2208
- const line = new LineSegment(p?.start, p?.end);
2209
- const len = line.length();
2210
- if (len < minDoorWidth) return;
2211
- const normal = line.normal(), direction = line.direction(), step = (len - dxf.width * 2) / 2;
2212
- for (let i = 0; i < 3; i++) {
2213
- const point = line.start.clone().add(direction.clone().multiplyScalar(dxf.width + step * i));
2214
- const rLine = new LineSegment(
2215
- point,
2216
- point.clone().add(normal.clone().multiplyScalar(1))
1898
+ const a = [];
1899
+ return r.forEach((c) => {
1900
+ const h = new L(c?.start, c?.end), l = h.length();
1901
+ if (l < n) return;
1902
+ const d = h.normal(), f = h.direction(), m = (l - o.width * 2) / 2;
1903
+ for (let y = 0; y < 3; y++) {
1904
+ const u = h.start.clone().add(f.clone().multiplyScalar(o.width + m * y)), x = new L(
1905
+ u,
1906
+ u.clone().add(d.clone().multiplyScalar(1))
2217
1907
  );
2218
- rLine.directionMove(normal, -0.5);
2219
- const res = this.quadtree.queryLineSegment(rLine);
2220
- if (res.length) return;
1908
+ if (x.directionMove(d, -0.5), this.quadtree.queryLineSegment(x).length) return;
2221
1909
  }
2222
- doorLineSegment.push(line);
2223
- });
2224
- return doorLineSegment;
1910
+ a.push(h);
1911
+ }), a;
2225
1912
  }
2226
1913
  /** 添加可查找点的过滤规则
2227
1914
  * @param rule
2228
1915
  */
2229
- addPointsExcludeRule(rule) {
2230
- this._pointsExcludeRule.push(rule);
1916
+ addPointsExcludeRule(t) {
1917
+ this._pointsExcludeRule.push(t);
2231
1918
  }
2232
1919
  _pointsExcludeRule = [];
2233
1920
  /**
2234
1921
  * 查找所有可能为门的点位
2235
1922
  */
2236
1923
  getPossiblePoints() {
2237
- const doorPoints = [];
2238
- this.lineSegments.forEach((line) => {
2239
- line.points.forEach((p, j) => {
2240
- for (let i = 0; i < this._pointsExcludeRule.length; i++) if (this._pointsExcludeRule[i](line, p, j)) return;
2241
- const res = this.pointVirtualGrid.queryPoint(p).filter((d) => d.userData !== line);
2242
- if (res.length === 0) {
2243
- doorPoints.push({ line, point: p, uuid: uuid() });
2244
- }
1924
+ const t = [];
1925
+ return this.lineSegments.forEach((e) => {
1926
+ e.points.forEach((n, i) => {
1927
+ for (let o = 0; o < this._pointsExcludeRule.length; o++) if (this._pointsExcludeRule[o](e, n, i)) return;
1928
+ this.pointVirtualGrid.queryPoint(n).filter((o) => o.userData !== e).length === 0 && t.push({ line: e, point: n, uuid: N() });
2245
1929
  });
2246
- });
2247
- return doorPoints;
1930
+ }), t;
2248
1931
  }
2249
1932
  /**
2250
1933
  * 查找已知为门的点位
2251
1934
  */
2252
1935
  getDoorPoint() {
2253
- const doorPoints = [], dxf = this.dxf, pointVirtualGrid = this.pointVirtualGrid;
2254
- dxf.doors.forEach((item) => {
2255
- const doorLine = dxf.lineSegments[item[4]];
2256
- const doorData = dxf.originalData[item[4]];
2257
- if (doorData.drawDoorData) {
2258
- const point = Point.from(doorData.drawDoorData.start);
2259
- const direct = Point.from(doorData.drawDoorData.n);
2260
- const resList = pointVirtualGrid.queryPoint(point).filter((res) => {
2261
- if (res.userData === doorLine) return false;
2262
- const line = res.userData;
2263
- const direct2 = line.direction();
2264
- if (line.start.equal(point)) direct2.multiplyScalar(-1);
2265
- const angle = direct.angleBetween(direct2, "angle");
2266
- return angle > 80 || angle < 10;
1936
+ const t = [], e = this.dxf, n = this.pointVirtualGrid;
1937
+ return e.doors.forEach((i) => {
1938
+ const s = e.lineSegments[i[4]], o = e.originalData[i[4]];
1939
+ if (o.drawDoorData) {
1940
+ const r = p.from(o.drawDoorData.start), a = p.from(o.drawDoorData.n), c = n.queryPoint(r).filter((h) => {
1941
+ if (h.userData === s) return !1;
1942
+ const l = h.userData, d = l.direction();
1943
+ l.start.equal(r) && d.multiplyScalar(-1);
1944
+ const f = a.angleBetween(d, "angle");
1945
+ return f > 80 || f < 10;
2267
1946
  });
2268
- if (resList.length) {
2269
- doorPoints.push({
2270
- line: resList[0].userData,
2271
- point,
2272
- uuid: uuid()
2273
- });
2274
- }
2275
- } else if (doorData.doorDirectConnection) {
2276
- this.continueFind = false;
2277
- const line = new LineSegment(Point.from(doorData.start), Point.from(doorData.end));
2278
- line.userData = {
2279
- doorDirectConnection: true,
2280
- isDoor: true
2281
- };
2282
- this.dxf.doorLineSegment.push(line);
2283
- } else {
2284
- console.warn(`门的线段顺序${item[4]} 没有drawDoorData属性`);
2285
- }
2286
- });
2287
- console.log("门点位数量:", doorPoints.length);
2288
- return doorPoints;
1947
+ c.length && t.push({
1948
+ line: c[0].userData,
1949
+ point: r,
1950
+ uuid: N()
1951
+ });
1952
+ } else if (o.doorDirectConnection) {
1953
+ this.continueFind = !1;
1954
+ const r = new L(p.from(o.start), p.from(o.end));
1955
+ r.userData = {
1956
+ doorDirectConnection: !0,
1957
+ isDoor: !0
1958
+ }, this.dxf.doorLineSegment.push(r);
1959
+ } else
1960
+ console.warn(`门的线段顺序${i[4]} 没有drawDoorData属性`);
1961
+ }), t;
2289
1962
  }
2290
1963
  /**
2291
1964
  * 查找双线墙的点位
2292
1965
  * @returns
2293
1966
  */
2294
1967
  searchDoubleLinePoint() {
2295
- const excludeIndexMap = /* @__PURE__ */ new Map();
2296
- this.resultList.flatMap((p) => {
2297
- const line0 = this.lineSegments[p.sourceIndex], line1 = this.lineSegments[p.targetIndex], start0 = line1.projectPoint(line0.start), end0 = line1.projectPoint(line0.end), start1 = line0.projectPoint(line1.start), end1 = line0.projectPoint(line1.end), mode0 = start0 && end0 ? -1 : start0 ? 0 : end0 ? 1 : -1, mode1 = start1 && end1 ? -1 : start1 ? 0 : end1 ? 1 : -1;
2298
- if (excludeIndexMap.has(p.sourceIndex)) {
2299
- if (excludeIndexMap.get(p.sourceIndex) != mode0) excludeIndexMap.set(p.sourceIndex, -1);
2300
- } else excludeIndexMap.set(p.sourceIndex, mode0);
2301
- if (excludeIndexMap.has(p.targetIndex)) {
2302
- if (excludeIndexMap.get(p.targetIndex) != mode1) excludeIndexMap.set(p.targetIndex, -1);
2303
- } else excludeIndexMap.set(p.targetIndex, mode1);
2304
- });
2305
- return excludeIndexMap;
1968
+ const t = /* @__PURE__ */ new Map();
1969
+ return this.resultList.flatMap((e) => {
1970
+ const n = this.lineSegments[e.sourceIndex], i = this.lineSegments[e.targetIndex], s = i.projectPoint(n.start), o = i.projectPoint(n.end), r = n.projectPoint(i.start), a = n.projectPoint(i.end), c = s && o ? -1 : s ? 0 : o ? 1 : -1, h = r && a ? -1 : r ? 0 : a ? 1 : -1;
1971
+ t.has(e.sourceIndex) ? t.get(e.sourceIndex) != c && t.set(e.sourceIndex, -1) : t.set(e.sourceIndex, c), t.has(e.targetIndex) ? t.get(e.targetIndex) != h && t.set(e.targetIndex, -1) : t.set(e.targetIndex, h);
1972
+ }), t;
2306
1973
  }
2307
1974
  /** 查找方案一:最近点查找
2308
1975
  * @description 以点为圆心,查找半径内符合角度的点
@@ -2312,160 +1979,113 @@ class DoorsAnalysis {
2312
1979
  * @param doorSearchNearAngle 查找的角度
2313
1980
  * @returns
2314
1981
  */
2315
- searchNearby(doorPoints, possibleDoorPoints = [], doorSearchDistance = this.doorSearchDistance, doorSearchNearAngle = this.doorSearchNearAngle) {
2316
- const findPointVirtualGrid = this.findPointVirtualGrid, quadtree = this.quadtree;
2317
- function find({ point, line }, doorIndex, record2) {
2318
- const direct = line.direction();
2319
- if (line.start === point) direct.multiplyScalar(-1);
2320
- const res = findPointVirtualGrid.queryCircle(point, doorSearchDistance).filter((r) => r.userData !== line).sort((a, b) => a.point.distance(point) - b.point.distance(point));
2321
- const list = [];
2322
- for (let i = 0; i < res.length; i++) {
2323
- const doorIndex2 = possibleDoorPoints.findIndex((p) => p.point === res[i].point);
2324
- const id1 = doorPoints[doorIndex].uuid, id2 = possibleDoorPoints[doorIndex2].uuid;
2325
- if (record2.has(`${id1}.${id2}`)) continue;
2326
- record2.add(`${id1}.${id2}`);
2327
- record2.add(`${id2}.${id1}`);
2328
- const targetPoint = res[i].point, line2 = new LineSegment(point.clone(), targetPoint.clone()), angle = line2.direction().angleBetween(direct, "angle");
2329
- if (angle < doorSearchNearAngle) {
2330
- const direct2 = doorPoints[doorIndex2].line.direction();
2331
- const line22 = res[i].userData;
2332
- if (line22.start.equal(res[i].point)) direct2.multiplyScalar(-1);
2333
- const angle2 = line2.direction().multiplyScalar(-1).angleBetween(direct2, "angle");
2334
- if (angle2 < doorSearchNearAngle) {
2335
- if (!quadtree.queryLineSegment(line2).length) {
2336
- list.push({
2337
- findData: res[i],
2338
- findUuid: id2,
2339
- doorLine: line2,
2340
- doorUuid: id1
2341
- });
2342
- }
2343
- }
1982
+ searchNearby(t, e = [], n = this.doorSearchDistance, i = this.doorSearchNearAngle) {
1983
+ const s = this.findPointVirtualGrid, o = this.quadtree;
1984
+ function r({ point: u, line: x }, w, S) {
1985
+ const b = x.direction();
1986
+ x.start === u && b.multiplyScalar(-1);
1987
+ const P = s.queryCircle(u, n).filter((D) => D.userData !== x).sort((D, E) => D.point.distance(u) - E.point.distance(u)), A = [];
1988
+ for (let D = 0; D < P.length; D++) {
1989
+ const E = e.findIndex((T) => T.point === P[D].point), B = t[w].uuid, Y = e[E].uuid;
1990
+ if (S.has(`${B}.${Y}`)) continue;
1991
+ S.add(`${B}.${Y}`), S.add(`${Y}.${B}`);
1992
+ const Q = P[D].point, C = new L(u.clone(), Q.clone());
1993
+ if (C.direction().angleBetween(b, "angle") < i) {
1994
+ const T = t[E].line.direction();
1995
+ P[D].userData.start.equal(P[D].point) && T.multiplyScalar(-1), C.direction().multiplyScalar(-1).angleBetween(T, "angle") < i && (o.queryLineSegment(C).length || A.push({
1996
+ findData: P[D],
1997
+ findUuid: Y,
1998
+ doorLine: C,
1999
+ doorUuid: B
2000
+ }));
2344
2001
  }
2345
2002
  }
2346
- return list;
2347
- }
2348
- function deepSearchNearHandle(uuid2, snFindRecord2, list, record2, other) {
2349
- record2.add(uuid2);
2350
- const newList = [];
2351
- if (other) newList.push(other);
2352
- for (let i = 0; i < list.length; i++) {
2353
- const item = list[i];
2354
- if (snFindRecord2.has(item.findUuid)) {
2355
- const list2 = snFindRecord2.get(item.findUuid);
2356
- if (deepSearchNearHandle(item.findUuid, snFindRecord2, list2, record2, item)) newList.push(item);
2357
- } else newList.push(item);
2003
+ return A;
2004
+ }
2005
+ function a(u, x, w, S, b) {
2006
+ S.add(u);
2007
+ const P = [];
2008
+ b && P.push(b);
2009
+ for (let A = 0; A < w.length; A++) {
2010
+ const D = w[A];
2011
+ if (x.has(D.findUuid)) {
2012
+ const E = x.get(D.findUuid);
2013
+ a(D.findUuid, x, E, S, D) && P.push(D);
2014
+ } else P.push(D);
2358
2015
  }
2359
- newList.sort((a, b) => a.doorLine.length() - b.doorLine.length());
2360
- if (other && newList[0] === other) {
2361
- list.splice(0);
2362
- return true;
2016
+ return P.sort((A, D) => A.doorLine.length() - D.doorLine.length()), b && P[0] === b ? (w.splice(0), !0) : (w.splice(1), !1);
2017
+ }
2018
+ const c = /* @__PURE__ */ new Set(), h = /* @__PURE__ */ new Map();
2019
+ t.map((u, x) => {
2020
+ const w = r(u, x, c);
2021
+ w.length && h.set(u.uuid, w);
2022
+ }), c.clear();
2023
+ const l = /* @__PURE__ */ new Map();
2024
+ h.forEach((u, x) => {
2025
+ if (!c.has(x) && u.length && a(x, h, u, c), u.length) {
2026
+ const w = u[0];
2027
+ l.has(w.doorUuid) || l.set(w.doorUuid, []), l.get(w.doorUuid)?.push(w), l.has(w.findUuid) || l.set(w.findUuid, []), l.get(w.findUuid)?.push(w);
2363
2028
  }
2364
- list.splice(1);
2365
- return false;
2366
- }
2367
- const record = /* @__PURE__ */ new Set();
2368
- const snFindRecord = /* @__PURE__ */ new Map();
2369
- doorPoints.map((p, index2) => {
2370
- const list = find(p, index2, record);
2371
- if (list.length) snFindRecord.set(p.uuid, list);
2372
2029
  });
2373
- record.clear();
2374
- const temMap = /* @__PURE__ */ new Map();
2375
- snFindRecord.forEach((list, key) => {
2376
- if (!record.has(key) && list.length) {
2377
- deepSearchNearHandle(key, snFindRecord, list, record);
2378
- }
2379
- if (list.length) {
2380
- const item = list[0];
2381
- if (!temMap.has(item.doorUuid)) temMap.set(item.doorUuid, []);
2382
- temMap.get(item.doorUuid)?.push(item);
2383
- if (!temMap.has(item.findUuid)) temMap.set(item.findUuid, []);
2384
- temMap.get(item.findUuid)?.push(item);
2030
+ const d = /* @__PURE__ */ new Set();
2031
+ l.forEach((u) => {
2032
+ if (u.length > 1) {
2033
+ u.sort((x, w) => x.doorLine.length() - w.doorLine.length());
2034
+ for (let x = 1; x < u.length; x++) d.add(u[x]);
2385
2035
  }
2386
2036
  });
2387
- const deleteSet = /* @__PURE__ */ new Set();
2388
- temMap.forEach((list) => {
2389
- if (list.length > 1) {
2390
- list.sort((a, b) => a.doorLine.length() - b.doorLine.length());
2391
- for (let i = 1; i < list.length; i++) deleteSet.add(list[i]);
2037
+ const f = [], m = [];
2038
+ h.forEach((u) => {
2039
+ if (u.length) {
2040
+ const x = u[0];
2041
+ d.has(x) || (f.push(x), m.push(x.doorUuid, x.findUuid));
2392
2042
  }
2393
2043
  });
2394
- const searchNearRasult = [], removeDoorPointsUuid = [];
2395
- snFindRecord.forEach((list) => {
2396
- if (list.length) {
2397
- const item = list[0];
2398
- if (!deleteSet.has(item)) {
2399
- searchNearRasult.push(item);
2400
- removeDoorPointsUuid.push(item.doorUuid, item.findUuid);
2401
- }
2402
- }
2403
- });
2404
- const doors = [];
2405
- searchNearRasult.forEach((item) => {
2406
- const doorIndex = doorPoints.findIndex((p2) => p2.uuid === item.doorUuid);
2407
- const findDoorIndex = possibleDoorPoints.findIndex((p2) => p2.uuid === item.findUuid);
2408
- const start = doorPoints[doorIndex].point.clone();
2409
- const end = possibleDoorPoints[findDoorIndex].point.clone();
2410
- const startLine = this.findLongLineSegment(doorPoints[doorIndex].line);
2411
- const endLine = this.findLongLineSegment(possibleDoorPoints[findDoorIndex].line);
2412
- const p = startLine.projectPoint(end);
2413
- if (p) {
2414
- start.copy(p);
2415
- const l = new LineSegment(start, end);
2416
- const angle = endLine.includedAngle(l);
2417
- if (angle < 10 || angle > 170 || Math.abs(90 - angle) < 10) {
2418
- doors.push({
2419
- start,
2420
- end
2421
- });
2422
- }
2044
+ const y = [];
2045
+ return f.forEach((u) => {
2046
+ const x = t.findIndex((E) => E.uuid === u.doorUuid), w = e.findIndex((E) => E.uuid === u.findUuid), S = t[x].point.clone(), b = e[w].point.clone(), P = this.findLongLineSegment(t[x].line), A = this.findLongLineSegment(e[w].line), D = P.projectPoint(b);
2047
+ if (D) {
2048
+ S.copy(D);
2049
+ const E = new L(S, b), B = A.includedAngle(E);
2050
+ (B < 10 || B > 170 || Math.abs(90 - B) < 10) && y.push({
2051
+ start: S,
2052
+ end: b
2053
+ });
2423
2054
  } else {
2424
- const p2 = endLine.projectPoint(start);
2425
- if (p2) end.copy(p2);
2426
- const l = new LineSegment(start, end);
2427
- const angle = startLine.includedAngle(l);
2428
- if (angle < 10 || angle > 170 || Math.abs(90 - angle) < 10) {
2429
- doors.push({
2430
- start,
2431
- end
2432
- });
2433
- }
2055
+ const E = A.projectPoint(S);
2056
+ E && b.copy(E);
2057
+ const B = new L(S, b), Y = P.includedAngle(B);
2058
+ (Y < 10 || Y > 170 || Math.abs(90 - Y) < 10) && y.push({
2059
+ start: S,
2060
+ end: b
2061
+ });
2434
2062
  }
2435
- });
2436
- possibleDoorPoints.splice(
2063
+ }), e.splice(
2437
2064
  0,
2438
- possibleDoorPoints.length,
2439
- ...possibleDoorPoints.filter((p) => removeDoorPointsUuid.indexOf(p.uuid) === -1)
2440
- );
2441
- doorPoints.splice(
2065
+ e.length,
2066
+ ...e.filter((u) => m.indexOf(u.uuid) === -1)
2067
+ ), t.splice(
2442
2068
  0,
2443
- doorPoints.length,
2444
- ...doorPoints.filter((p) => removeDoorPointsUuid.indexOf(p.uuid) === -1)
2445
- );
2446
- return doors;
2069
+ t.length,
2070
+ ...t.filter((u) => m.indexOf(u.uuid) === -1)
2071
+ ), y;
2447
2072
  }
2448
2073
  /** 方案二: 沿方向查找
2449
2074
  * @description
2450
2075
  * @param param0
2451
2076
  * @returns
2452
2077
  */
2453
- searchAlongDirection({ point, line }, doorSearchDistance = this.doorSearchDistance) {
2454
- const quadtree = this.quadtree;
2455
- const direct = line.direction();
2456
- if (line.start === point) direct.multiplyScalar(-1);
2457
- const endPoint = point.clone().add(direct.clone().multiplyScalar(doorSearchDistance)), rline = new LineSegment(point.clone(), endPoint), result = quadtree.queryLineSegment(rline).map((l) => {
2458
- const res = l.line.getIntersection(rline);
2459
- return {
2460
- point: res,
2461
- line: l.line
2462
- };
2463
- }).filter((i) => i.point).sort((a, b) => point.distance(a.point) - point.distance(b.point));
2464
- if (result.length) {
2465
- const item = result[0];
2466
- if (Math.abs(90 - item.line.direction().angleBetween(direct, "angle")) < 5) {
2467
- return item;
2468
- }
2078
+ searchAlongDirection({ point: t, line: e }, n = this.doorSearchDistance) {
2079
+ const i = this.quadtree, s = e.direction();
2080
+ e.start === t && s.multiplyScalar(-1);
2081
+ const o = t.clone().add(s.clone().multiplyScalar(n)), r = new L(t.clone(), o), a = i.queryLineSegment(r).map((c) => ({
2082
+ point: c.line.getIntersection(r),
2083
+ line: c.line
2084
+ })).filter((c) => c.point).sort((c, h) => t.distance(c.point) - t.distance(h.point));
2085
+ if (a.length) {
2086
+ const c = a[0];
2087
+ if (Math.abs(90 - c.line.direction().angleBetween(s, "angle")) < 5)
2088
+ return c;
2469
2089
  }
2470
2090
  }
2471
2091
  /** 方案三: 沿法线方向查找
@@ -2474,35 +2094,25 @@ class DoorsAnalysis {
2474
2094
  * @param doorSearchDistance
2475
2095
  * @returns
2476
2096
  */
2477
- searchAlongNormalDirection({ point, line }, doorSearchDistance = this.doorSearchDistance) {
2478
- const pointVirtualGrid = this.pointVirtualGrid, quadtree = this.quadtree, direct = line.direction(), normal = line.start.normal(line.end), prePoint = line.start.clone();
2479
- if (line.start === point) direct.multiplyScalar(-1);
2480
- if (line.start === point) prePoint.copy(line.end);
2481
- const result = pointVirtualGrid.queryPoint(prePoint).filter((r) => r.userData !== line);
2482
- for (let i = 0; i < result.length; i++) {
2483
- const element = result[i];
2484
- const l = element.userData;
2485
- const d1 = l.direction();
2486
- if (l.start === element.point) direct.multiplyScalar(-1);
2487
- const angle = d1.angleBetween(normal) / (Math.PI / 180);
2488
- if (angle > 90) {
2489
- normal.multiplyScalar(-1);
2097
+ searchAlongNormalDirection({ point: t, line: e }, n = this.doorSearchDistance) {
2098
+ const i = this.pointVirtualGrid, s = this.quadtree, o = e.direction(), r = e.start.normal(e.end), a = e.start.clone();
2099
+ e.start === t && o.multiplyScalar(-1), e.start === t && a.copy(e.end);
2100
+ const c = i.queryPoint(a).filter((d) => d.userData !== e);
2101
+ for (let d = 0; d < c.length; d++) {
2102
+ const f = c[d], m = f.userData, y = m.direction();
2103
+ if (m.start === f.point && o.multiplyScalar(-1), y.angleBetween(r) / (Math.PI / 180) > 90) {
2104
+ r.multiplyScalar(-1);
2490
2105
  break;
2491
2106
  }
2492
2107
  }
2493
- const rline3 = new LineSegment(point.clone(), point.clone().add(normal.multiplyScalar(doorSearchDistance)));
2494
- const r3 = quadtree.queryLineSegment(rline3).map((l) => {
2495
- const res = l.line.getIntersection(rline3);
2496
- return {
2497
- point: res,
2498
- line: l.line
2499
- };
2500
- }).filter((i) => i.point).sort((a, b) => point.distance(a.point) - point.distance(b.point));
2501
- if (r3.length) {
2502
- const item = r3[0];
2503
- if (Math.abs(90 - item.line.direction().angleBetween(normal, "angle")) < 5) {
2504
- return item;
2505
- }
2108
+ const h = new L(t.clone(), t.clone().add(r.multiplyScalar(n))), l = s.queryLineSegment(h).map((d) => ({
2109
+ point: d.line.getIntersection(h),
2110
+ line: d.line
2111
+ })).filter((d) => d.point).sort((d, f) => t.distance(d.point) - t.distance(f.point));
2112
+ if (l.length) {
2113
+ const d = l[0];
2114
+ if (Math.abs(90 - d.line.direction().angleBetween(r, "angle")) < 5)
2115
+ return d;
2506
2116
  }
2507
2117
  }
2508
2118
  /**
@@ -2510,37 +2120,31 @@ class DoorsAnalysis {
2510
2120
  * @param line
2511
2121
  * @returns
2512
2122
  */
2513
- findLongLineSegment(line) {
2514
- const resLine = line.clone();
2515
- const res1 = this.pointVirtualGrid.queryPoint(line.start);
2516
- const res2 = this.pointVirtualGrid.queryPoint(line.end);
2517
- for (let i = 0; i < res1.length; i++) {
2518
- const { userData: line2 } = res1[i];
2519
- if (line2 === line) continue;
2520
- if (line2 && line2.directionEqual(line)) {
2521
- if (line2.start.equal(line.start)) resLine.start.copy(line2.end);
2522
- else resLine.start.copy(line2.start);
2123
+ findLongLineSegment(t) {
2124
+ const e = t.clone(), n = this.pointVirtualGrid.queryPoint(t.start), i = this.pointVirtualGrid.queryPoint(t.end);
2125
+ for (let s = 0; s < n.length; s++) {
2126
+ const { userData: o } = n[s];
2127
+ if (o !== t && o && o.directionEqual(t)) {
2128
+ o.start.equal(t.start) ? e.start.copy(o.end) : e.start.copy(o.start);
2523
2129
  break;
2524
2130
  }
2525
2131
  }
2526
- for (let i = 0; i < res2.length; i++) {
2527
- const { userData: line2 } = res2[i];
2528
- if (line2 === line) continue;
2529
- if (line2 && line2.directionEqual(line)) {
2530
- if (line2.end.equal(line.end)) resLine.end.copy(line2.start);
2531
- else resLine.end.copy(line2.end);
2132
+ for (let s = 0; s < i.length; s++) {
2133
+ const { userData: o } = i[s];
2134
+ if (o !== t && o && o.directionEqual(t)) {
2135
+ o.end.equal(t.end) ? e.end.copy(o.start) : e.end.copy(o.end);
2532
2136
  break;
2533
2137
  }
2534
2138
  }
2535
- return resLine;
2139
+ return e;
2536
2140
  }
2537
2141
  }
2538
- class LineAnalysis extends Component {
2142
+ class at extends q {
2539
2143
  static name = "LineAnalysis";
2540
2144
  Dxf = null;
2541
2145
  Variable = null;
2542
2146
  lineSegmentList = [];
2543
- container = new THREE.Group();
2147
+ container = new M.Group();
2544
2148
  // 误差角度
2545
2149
  errorAngle = 4;
2546
2150
  width = 0.4;
@@ -2548,11 +2152,8 @@ class LineAnalysis extends Component {
2548
2152
  *
2549
2153
  * @param parent
2550
2154
  */
2551
- onAddFromParent(parent) {
2552
- this.Dxf = parent.findComponentByType(Dxf);
2553
- this.Variable = this.parent?.findComponentByType(Variable);
2554
- this.Dxf.addEventListener("setDta", this.lineAnalysis.bind(this));
2555
- this.Dxf.addEventListener("createGroup", this.doorsAnalysis.bind(this));
2155
+ onAddFromParent(t) {
2156
+ this.Dxf = t.findComponentByType(X), this.Variable = this.parent?.findComponentByType(_), this.Dxf.addEventListener("setDta", this.lineAnalysis.bind(this)), this.Dxf.addEventListener("createGroup", this.doorsAnalysis.bind(this));
2556
2157
  }
2557
2158
  /**
2558
2159
  *
@@ -2561,20 +2162,16 @@ class LineAnalysis extends Component {
2561
2162
  * @param width
2562
2163
  * @returns
2563
2164
  */
2564
- expandLineSegment(p1, p2, width = 0.1) {
2565
- const normal = p2.normal(p1);
2566
- const pDirect = p2.direction(p1).mutiplyScalar(width * 0.5);
2567
- const nDirect = p1.direction(p2).mutiplyScalar(width * 0.5);
2568
- const offsetX = normal.x * width * 0.5;
2569
- const offsetY = normal.y * width * 0.5;
2165
+ expandLineSegment(t, e, n = 0.1) {
2166
+ const i = e.normal(t), s = e.direction(t).mutiplyScalar(n * 0.5), o = t.direction(e).mutiplyScalar(n * 0.5), r = i.x * n * 0.5, a = i.y * n * 0.5;
2570
2167
  return {
2571
2168
  points: [
2572
2169
  // 第一条线
2573
- new Point(p1.x + offsetX, p1.y + offsetY).add(nDirect),
2574
- new Point(p2.x + offsetX, p2.y + offsetY).add(pDirect),
2170
+ new p(t.x + r, t.y + a).add(o),
2171
+ new p(e.x + r, e.y + a).add(s),
2575
2172
  // 第二条线
2576
- new Point(p1.x - offsetX, p1.y - offsetY).add(nDirect),
2577
- new Point(p2.x - offsetX, p2.y - offsetY).add(pDirect)
2173
+ new p(t.x - r, t.y - a).add(o),
2174
+ new p(e.x - r, e.y - a).add(s)
2578
2175
  ],
2579
2176
  indices: [0, 1, 1, 3, 3, 2, 2, 0],
2580
2177
  rectIndices: [0, 1, 3, 2, 0]
@@ -2586,31 +2183,25 @@ class LineAnalysis extends Component {
2586
2183
  * @param p1
2587
2184
  * @param p2
2588
2185
  */
2589
- addData(p1, p2) {
2590
- const dxf = this.Dxf;
2591
- dxf.data.push([p1.clone(), p2.clone(), [], false, dxf.data.length]);
2592
- this.appendLineSegmentList.push(new LineSegment(p1.clone(), p2.clone()));
2186
+ addData(t, e) {
2187
+ const n = this.Dxf;
2188
+ n.data.push([t.clone(), e.clone(), [], !1, n.data.length]), this.appendLineSegmentList.push(new L(t.clone(), e.clone()));
2593
2189
  }
2594
2190
  /** 结果分析创建矩形
2595
2191
  * @param result
2596
2192
  */
2597
- createRectangle(result) {
2598
- const dxf = this.Dxf;
2599
- const project0 = result.project, project1 = result.project2;
2600
- if (project0.includedAngle(project1) > 135) {
2601
- project1.points = [project1.points[1], project1.points[0]];
2602
- }
2603
- this.addData(project0.points[0], project1.points[0]);
2604
- this.addData(project0.points[1], project1.points[1]);
2605
- const leftHeight = project0.points[0].distance(project1.points[0]), rightHeight = project0.points[1].distance(project1.points[1]), count = Math.ceil(Math.max(leftHeight, rightHeight) / dxf.width), leftFragment = leftHeight / count, rightFragment = rightHeight / count, leftDirection = project1.points[0].direction(project0.points[0]), rightDirection = project1.points[1].direction(project0.points[1]), leftP = project0.points[0].clone(), rightP = project0.points[1].clone(), direction = rightP.direction(leftP);
2606
- direction.multiplyScalar(dxf.width * 0.5);
2607
- const _leftP = leftP.clone().add(direction), _rightP = rightP.clone().add(direction.multiplyScalar(-1)), d1 = leftP.direction(rightP), d2 = _leftP.direction(_rightP);
2608
- if (d1.x > 0 && d2.x < 0 || d1.x < 0 && d2.x > 0 || d1.y > 0 && d2.y < 0 || d1.y < 0 && d2.y > 0) return;
2609
- leftP.set(_leftP.x, _leftP.y);
2610
- rightP.set(_rightP.x, _rightP.y);
2611
- for (let i = 1; i < count; i++) {
2612
- const left = leftDirection.clone().multiplyScalar(leftFragment * i), right = rightDirection.clone().multiplyScalar(rightFragment * i), p1 = leftP.clone().add(left), p2 = rightP.clone().add(right);
2613
- this.addData(p1, p2);
2193
+ createRectangle(t) {
2194
+ const e = this.Dxf, n = t.project, i = t.project2;
2195
+ n.includedAngle(i) > 135 && (i.points = [i.points[1], i.points[0]]), this.addData(n.points[0], i.points[0]), this.addData(n.points[1], i.points[1]);
2196
+ const s = n.points[0].distance(i.points[0]), o = n.points[1].distance(i.points[1]), r = Math.ceil(Math.max(s, o) / e.width), a = s / r, c = o / r, h = i.points[0].direction(n.points[0]), l = i.points[1].direction(n.points[1]), d = n.points[0].clone(), f = n.points[1].clone(), m = f.direction(d);
2197
+ m.multiplyScalar(e.width * 0.5);
2198
+ const y = d.clone().add(m), u = f.clone().add(m.multiplyScalar(-1)), x = d.direction(f), w = y.direction(u);
2199
+ if (!(x.x > 0 && w.x < 0 || x.x < 0 && w.x > 0 || x.y > 0 && w.y < 0 || x.y < 0 && w.y > 0)) {
2200
+ d.set(y.x, y.y), f.set(u.x, u.y);
2201
+ for (let S = 1; S < r; S++) {
2202
+ const b = h.clone().multiplyScalar(a * S), P = l.clone().multiplyScalar(c * S), A = d.clone().add(b), D = f.clone().add(P);
2203
+ this.addData(A, D);
2204
+ }
2614
2205
  }
2615
2206
  }
2616
2207
  quadtree;
@@ -2618,18 +2209,13 @@ class LineAnalysis extends Component {
2618
2209
  * 构建线段四叉树,快速查找,
2619
2210
  */
2620
2211
  buildQuadtree() {
2621
- const dxf = this.Dxf;
2622
- const lineSegmentList = [];
2623
- this.quadtree = new Quadtree(dxf.originalBox, 2);
2624
- dxf.lineSegments.forEach((lineSegment) => {
2625
- if (lineSegment.userData?.isDoor) return;
2626
- this.quadtree?.insert({
2627
- line: lineSegment,
2628
- userData: lineSegmentList.length
2629
- });
2630
- lineSegmentList.push(lineSegment);
2631
- });
2632
- this.lineSegmentList = lineSegmentList;
2212
+ const t = this.Dxf, e = [];
2213
+ this.quadtree = new j(t.originalBox, 2), t.lineSegments.forEach((n) => {
2214
+ n.userData?.isDoor || (this.quadtree?.insert({
2215
+ line: n,
2216
+ userData: e.length
2217
+ }), e.push(n));
2218
+ }), this.lineSegmentList = e;
2633
2219
  }
2634
2220
  resultList = [];
2635
2221
  mergeWallLines = [];
@@ -2639,24 +2225,18 @@ class LineAnalysis extends Component {
2639
2225
  */
2640
2226
  lineAnalysis() {
2641
2227
  this.buildQuadtree();
2642
- const quadtree = this.quadtree;
2643
- const lineSegmentList = this.lineSegmentList;
2644
- const visited = /* @__PURE__ */ new Set(), resultList = [];
2645
- lineSegmentList.forEach((_0, i) => {
2646
- const sourceLineSegment = lineSegmentList[i], rectangle = Rectangle.fromByLineSegment(sourceLineSegment, this.width * 2, false, -0.01), ids = quadtree.queryRect(rectangle).map((i2) => i2.userData).filter((index2) => index2 !== i);
2647
- ids.forEach((id) => {
2228
+ const t = this.quadtree, e = this.lineSegmentList, n = /* @__PURE__ */ new Set(), i = [];
2229
+ e.forEach((s, o) => {
2230
+ const r = e[o], a = O.fromByLineSegment(r, this.width * 2, !1, -0.01);
2231
+ t.queryRect(a).map((h) => h.userData).filter((h) => h !== o).forEach((h) => {
2648
2232
  try {
2649
- if (visited.has(`${i}-${id}`) || visited.has(`${id}-${i}`)) return;
2650
- const res = this.projectionAnalysis(id, i, sourceLineSegment, lineSegmentList);
2651
- if (res) resultList.push(res);
2652
- visited.add(`${i}-${id}`);
2653
- } catch (error) {
2233
+ if (n.has(`${o}-${h}`) || n.has(`${h}-${o}`)) return;
2234
+ const l = this.projectionAnalysis(h, o, r, e);
2235
+ l && i.push(l), n.add(`${o}-${h}`);
2236
+ } catch {
2654
2237
  }
2655
2238
  });
2656
- });
2657
- this.appendLineSegmentList.length = 0;
2658
- resultList.forEach(this.createRectangle.bind(this));
2659
- this.resultList = resultList;
2239
+ }), this.appendLineSegmentList.length = 0, i.forEach(this.createRectangle.bind(this)), this.resultList = i;
2660
2240
  }
2661
2241
  /** 线段投影分析
2662
2242
  * @param index
@@ -2664,43 +2244,40 @@ class LineAnalysis extends Component {
2664
2244
  * @param lineSegmentList
2665
2245
  * @returns
2666
2246
  */
2667
- projectionAnalysis(index2, sourceIndex, sourceLineSegment, lineSegmentList) {
2668
- const temLineSegment = lineSegmentList[index2], direct = sourceLineSegment.direction(), temDirect = temLineSegment.direction(), angle = direct.angleBetween(temDirect) / (Math.PI / 180);
2669
- if (angle < this.errorAngle || angle > 180 - this.errorAngle) {
2670
- let data;
2671
- const p1 = temLineSegment.projectLineSegment(sourceLineSegment), p2 = sourceLineSegment.projectLineSegment(temLineSegment);
2672
- if (p1.getLength() > p2.getLength()) {
2673
- data = {
2674
- target: temLineSegment,
2675
- targetIndex: index2,
2676
- source: sourceLineSegment,
2677
- sourceIndex,
2678
- project: p1,
2679
- project2: p2
2680
- };
2681
- } else {
2682
- data = {
2683
- target: sourceLineSegment,
2684
- targetIndex: sourceIndex,
2685
- source: temLineSegment,
2686
- sourceIndex: index2,
2687
- project: p2,
2688
- project2: p1
2689
- };
2690
- }
2691
- if (!data || data.project.getLength() < 0.2 || data.project2.getLength() < 0.2) return;
2692
- return data;
2247
+ projectionAnalysis(t, e, n, i) {
2248
+ const s = i[t], o = n.direction(), r = s.direction(), a = o.angleBetween(r) / (Math.PI / 180);
2249
+ if (a < this.errorAngle || a > 180 - this.errorAngle) {
2250
+ let c;
2251
+ const h = s.projectLineSegment(n), l = n.projectLineSegment(s);
2252
+ return h.getLength() > l.getLength() ? c = {
2253
+ target: s,
2254
+ targetIndex: t,
2255
+ source: n,
2256
+ sourceIndex: e,
2257
+ project: h,
2258
+ project2: l
2259
+ } : c = {
2260
+ target: n,
2261
+ targetIndex: e,
2262
+ source: s,
2263
+ sourceIndex: t,
2264
+ project: l,
2265
+ project2: h
2266
+ }, !c || c.project.getLength() < 0.2 || c.project2.getLength() < 0.2 ? void 0 : c;
2693
2267
  }
2694
2268
  }
2695
2269
  doorSearchNearAngle = 110;
2696
2270
  doorSearchDistance = 2;
2697
2271
  doors = [];
2698
2272
  doorsAnalysis() {
2699
- new DoorsAnalysis(this);
2273
+ new rt(this), this.dispatchEvent({
2274
+ type: "analysisCompleted"
2275
+ });
2700
2276
  }
2701
2277
  }
2702
- class DxfSystem extends ComponentManager {
2278
+ class ct extends it {
2703
2279
  Dxf;
2280
+ AngleCorrectionDxf;
2704
2281
  Variable;
2705
2282
  wallWidth;
2706
2283
  environment;
@@ -2708,116 +2285,87 @@ class DxfSystem extends ComponentManager {
2708
2285
  * @param wallWidth 输出墙壁厚度,该墙壁厚度不受缩放影响
2709
2286
  * @param scale 原始数据缩放比例
2710
2287
  */
2711
- constructor(wallWidth = 0.1, scale = 1) {
2712
- super();
2713
- this.environment = typeof window !== "undefined" ? "browser" : typeof global !== "undefined" ? "node" : "unknown";
2714
- this.wallWidth = wallWidth;
2715
- this.Dxf = new Dxf(this.wallWidth, scale);
2716
- this.Variable = new Variable();
2717
- this.addComponent(this.Variable);
2718
- this.addComponent(this.Dxf);
2719
- this.addComponent(new LineAnalysis());
2288
+ constructor(t = 0.1, e = 1) {
2289
+ super(), this.environment = typeof window < "u" ? "browser" : typeof global < "u" ? "node" : "unknown", this.wallWidth = t, this.Dxf = new X(this.wallWidth, e), this.AngleCorrectionDxf = new ot(), this.Variable = new _(), this.addComponent(this.Variable), this.addComponent(this.Dxf), this.addComponent(new at()), this.addComponent(this.AngleCorrectionDxf);
2720
2290
  }
2721
- usePlugin(plugin) {
2722
- if (typeof plugin === "function") plugin.call(this, this);
2723
- return this;
2291
+ usePlugin(t) {
2292
+ return typeof t == "function" && t.call(this, this), this;
2724
2293
  }
2725
2294
  destroy() {
2726
- [...this.components].forEach((com) => {
2727
- com.destroy();
2728
- });
2729
- [...this.components].forEach((com) => {
2730
- this.removeComponent(com);
2295
+ [...this.components].forEach((t) => {
2296
+ t.destroy();
2297
+ }), [...this.components].forEach((t) => {
2298
+ this.removeComponent(t);
2731
2299
  });
2732
2300
  }
2733
2301
  }
2734
- const exporter = new OBJExporter();
2735
- const glbExporter = new GLTFExporter();
2736
- function lineSqueezing(p1, p2, width = 0.1) {
2737
- const normal = p2.normal(p1);
2738
- const pDirect = p2.direction(p1).mutiplyScalar(width * 0.5);
2739
- const nDirect = p1.direction(p2).mutiplyScalar(width * 0.5);
2740
- const offsetX = normal.x * width * 0.5;
2741
- const offsetY = normal.y * width * 0.5;
2302
+ const ht = new et(), lt = new nt();
2303
+ function dt(g, t, e = 0.1) {
2304
+ const n = t.normal(g), i = t.direction(g).mutiplyScalar(e * 0.5), s = g.direction(t).mutiplyScalar(e * 0.5), o = n.x * e * 0.5, r = n.y * e * 0.5;
2742
2305
  return {
2743
2306
  points: [
2744
2307
  // 第一条线
2745
- new Point(p1.x + offsetX, p1.y + offsetY).add(nDirect),
2746
- new Point(p2.x + offsetX, p2.y + offsetY).add(pDirect),
2308
+ new p(g.x + o, g.y + r).add(s),
2309
+ new p(t.x + o, t.y + r).add(i),
2747
2310
  // 第二条线
2748
- new Point(p1.x - offsetX, p1.y - offsetY).add(nDirect),
2749
- new Point(p2.x - offsetX, p2.y - offsetY).add(pDirect)
2311
+ new p(g.x - o, g.y - r).add(s),
2312
+ new p(t.x - o, t.y - r).add(i)
2750
2313
  ],
2751
2314
  indices: [0, 1, 1, 3, 3, 2, 2, 0],
2752
2315
  rectIndices: [0, 1, 3, 2, 0]
2753
2316
  };
2754
2317
  }
2755
- class WhiteModel extends Component {
2318
+ class H extends q {
2756
2319
  static name = "WhiteModel";
2757
2320
  Dxf = null;
2758
2321
  Variable = null;
2759
2322
  // dxf数据白模
2760
- whiteModelGroup = new THREE.Group();
2323
+ whiteModelGroup = new M.Group();
2761
2324
  // dxf数据白模边缘线
2762
- whiteModelLineGroup = new THREE.Group();
2325
+ whiteModelLineGroup = new M.Group();
2763
2326
  // 原始数据白模
2764
- originalWhiteMode = new THREE.Group();
2765
- material = new THREE.MeshBasicMaterial({ color: 16777215, transparent: true, opacity: 0.8, side: THREE.DoubleSide });
2766
- onAddFromParent(parent) {
2767
- this.Dxf = parent.findComponentByName("Dxf");
2768
- this.Variable = parent.findComponentByName("Variable");
2769
- this.originalWhiteMode.visible = false;
2770
- this.Dxf?.addEventListener("lineOffset", () => {
2327
+ originalWhiteMode = new M.Group();
2328
+ material = new M.MeshBasicMaterial({ color: 16777215, transparent: !0, opacity: 0.8, side: M.DoubleSide });
2329
+ onAddFromParent(t) {
2330
+ this.Dxf = t.findComponentByName("Dxf"), this.Variable = t.findComponentByName("Variable"), this.originalWhiteMode.visible = !1, this.Dxf?.addEventListener("lineOffset", () => {
2771
2331
  this.updateModel();
2772
2332
  });
2773
2333
  }
2774
2334
  updateModel() {
2775
- this.Variable?.set("whiteModelVisible", false);
2776
- const dxf = this.Dxf;
2777
- this.originalWhiteMode.clear();
2778
- this.whiteModelGroup.clear();
2779
- this.whiteModelLineGroup.clear();
2780
- this.whiteModelGroup.add(this.whiteModelLineGroup);
2781
- this.whiteModelGroup.position.z = dxf.originalZAverage;
2782
- this.originalWhiteMode.position.z = dxf.originalZAverage;
2783
- dxf.wallsGroup.forEach((points) => {
2784
- const shape = new THREE.Shape();
2785
- points.forEach((p, i) => i === 0 ? shape.moveTo(p.x / dxf.scale, p.y / dxf.scale) : shape.lineTo(p.x / dxf.scale, p.y / dxf.scale));
2786
- const geometry = new THREE.ExtrudeGeometry(shape, {
2335
+ this.Variable?.set("whiteModelVisible", !1);
2336
+ const t = this.Dxf;
2337
+ this.originalWhiteMode.clear(), this.whiteModelGroup.clear(), this.whiteModelLineGroup.clear(), this.whiteModelGroup.add(this.whiteModelLineGroup), this.whiteModelGroup.position.z = t.originalZAverage, this.originalWhiteMode.position.z = t.originalZAverage, t.wallsGroup.forEach((n) => {
2338
+ const i = new M.Shape();
2339
+ n.forEach((r, a) => a === 0 ? i.moveTo(r.x / t.scale, r.y / t.scale) : i.lineTo(r.x / t.scale, r.y / t.scale));
2340
+ const s = new M.ExtrudeGeometry(i, {
2787
2341
  depth: 2.8,
2788
2342
  bevelSize: 0
2789
- });
2790
- const mesh = new THREE.Mesh(geometry, this.material);
2791
- this.whiteModelGroup.add(mesh);
2792
- this.whiteModelLineGroup.add(
2793
- new THREE.LineSegments(new THREE.EdgesGeometry(geometry), new THREE.LineBasicMaterial({ color: 0 }))
2343
+ }), o = new M.Mesh(s, this.material);
2344
+ this.whiteModelGroup.add(o), this.whiteModelLineGroup.add(
2345
+ new M.LineSegments(new M.EdgesGeometry(s), new M.LineBasicMaterial({ color: 0 }))
2794
2346
  );
2795
- });
2796
- const walls = dxf.originalData.map(({ start, end, insetionArr }) => {
2797
- const startVec3 = new Point(start.x, start.y).mutiplyScalar(dxf.scale), endVec3 = new Point(end.x, end.y).mutiplyScalar(dxf.scale), { points, indices, rectIndices } = lineSqueezing(startVec3, endVec3, dxf.width);
2347
+ }), t.originalData.map(({ start: n, end: i, insetionArr: s }) => {
2348
+ const o = new p(n.x, n.y).mutiplyScalar(t.scale), r = new p(i.x, i.y).mutiplyScalar(t.scale), { points: a, indices: c, rectIndices: h } = dt(o, r, t.width);
2798
2349
  return {
2799
- points,
2800
- indices,
2801
- rectIndices,
2802
- insetions: (insetionArr ?? []).map((insetion) => insetion.index)
2350
+ points: a,
2351
+ indices: c,
2352
+ rectIndices: h,
2353
+ insetions: (s ?? []).map((l) => l.index)
2803
2354
  };
2804
- });
2805
- walls.forEach((wall) => {
2806
- const shape = new THREE.Shape();
2807
- wall.rectIndices.forEach((index2, i) => {
2808
- const p = wall.points[index2];
2809
- if (i === 0) shape.moveTo(p.x, p.y);
2810
- else shape.lineTo(p.x, p.y);
2355
+ }).forEach((n) => {
2356
+ const i = new M.Shape();
2357
+ n.rectIndices.forEach((r, a) => {
2358
+ const c = n.points[r];
2359
+ a === 0 ? i.moveTo(c.x, c.y) : i.lineTo(c.x, c.y);
2811
2360
  });
2812
- const geometry = new THREE.ExtrudeGeometry(shape, {
2361
+ const s = new M.ExtrudeGeometry(i, {
2813
2362
  depth: 2.8,
2814
2363
  bevelSize: 0
2815
2364
  });
2816
- if (geometry.attributes.position.array.filter((num) => Number.isNaN(num)).length) return;
2817
- const mesh = new THREE.Mesh(geometry);
2818
- this.originalWhiteMode?.add(mesh);
2819
- });
2820
- this.dispatchEvent({
2365
+ if (s.attributes.position.array.filter((r) => Number.isNaN(r)).length) return;
2366
+ const o = new M.Mesh(s);
2367
+ this.originalWhiteMode?.add(o);
2368
+ }), this.dispatchEvent({
2821
2369
  type: "updateModel",
2822
2370
  originalWhiteMode: this.originalWhiteMode,
2823
2371
  whiteModelGroup: this.whiteModelGroup
@@ -2828,13 +2376,9 @@ class WhiteModel extends Component {
2828
2376
  * @returns
2829
2377
  */
2830
2378
  toOBJ() {
2831
- return new Promise((resolve) => {
2832
- this.material.opacity = 1;
2833
- this.material.needsUpdate = true;
2834
- setTimeout(() => {
2835
- resolve(exporter.parse(this.whiteModelGroup));
2836
- this.material.opacity = 0.8;
2837
- this.material.transparent = true;
2379
+ return new Promise((t) => {
2380
+ this.material.opacity = 1, this.material.needsUpdate = !0, setTimeout(() => {
2381
+ t(ht.parse(this.whiteModelGroup)), this.material.opacity = 0.8, this.material.transparent = !0;
2838
2382
  }, 20);
2839
2383
  });
2840
2384
  }
@@ -2843,38 +2387,28 @@ class WhiteModel extends Component {
2843
2387
  * @param binary
2844
2388
  * @returns
2845
2389
  */
2846
- toGltf(binary = true) {
2847
- return new Promise((resolve) => {
2848
- this.material.opacity = 1;
2849
- this.material.needsUpdate = true;
2850
- setTimeout(async () => {
2851
- if (typeof window === "object") {
2852
- glbExporter.parse(this.whiteModelGroup.children, (gltf) => {
2853
- resolve(gltf);
2854
- this.material.opacity = 0.8;
2855
- this.material.transparent = true;
2390
+ toGltf(t = !0) {
2391
+ return new Promise((e) => {
2392
+ this.material.opacity = 1, this.material.needsUpdate = !0, setTimeout(async () => {
2393
+ if (typeof window == "object")
2394
+ lt.parse(this.whiteModelGroup.children, (n) => {
2395
+ e(n), this.material.opacity = 0.8, this.material.transparent = !0;
2856
2396
  }, () => {
2857
- resolve(void 0);
2397
+ e(void 0);
2858
2398
  }, {
2859
- binary
2399
+ binary: t
2860
2400
  });
2861
- } else if (typeof global !== "function") {
2401
+ else if (typeof global != "function")
2862
2402
  try {
2863
- const obj2gltf = await include("obj2gltf", true);
2864
- const fs = await include("fs", false);
2865
- const obj = await this.toOBJ();
2866
- fs.writeFileSync(this.uuid, obj);
2867
- const result = await obj2gltf(this.uuid, {
2868
- binary
2403
+ const n = await G("obj2gltf", !0), i = await G("fs", !1), s = await this.toOBJ(), o = Date.now().toString(16) + "-" + Math.floor(Math.random() * 16777215).toString(16);
2404
+ i.writeFileSync(o, s ?? "存贮失败");
2405
+ const r = await n(o, {
2406
+ binary: t
2869
2407
  });
2870
- fs.unlinkSync(this.uuid);
2871
- if (binary) resolve(result);
2872
- else resolve(JSON.stringify(result));
2873
- } catch (error) {
2874
- resolve(void 0);
2875
- console.log(error);
2408
+ i.unlinkSync(o), e(t ? r : JSON.stringify(r));
2409
+ } catch (n) {
2410
+ e(void 0), console.log(n);
2876
2411
  }
2877
- }
2878
2412
  }, 20);
2879
2413
  });
2880
2414
  }
@@ -2883,40 +2417,33 @@ class WhiteModel extends Component {
2883
2417
  * @returns
2884
2418
  */
2885
2419
  async toOBJBlob() {
2886
- const buffer = await this.toOBJ();
2887
- if (buffer) {
2888
- return new Blob([buffer], { type: "application/octet-stream" });
2889
- }
2420
+ const t = await this.toOBJ();
2421
+ if (t)
2422
+ return new Blob([t], { type: "application/octet-stream" });
2890
2423
  }
2891
2424
  /**
2892
2425
  * 转为 GltfBlob
2893
2426
  * @returns
2894
2427
  */
2895
- async toGltfBlob(binary = true) {
2896
- const buffer = await this.toGltf(binary);
2897
- if (buffer) {
2898
- return new Blob([buffer], { type: "application/octet-stream" });
2899
- }
2428
+ async toGltfBlob(t = !0) {
2429
+ const e = await this.toGltf(t);
2430
+ if (e)
2431
+ return new Blob([e], { type: "application/octet-stream" });
2900
2432
  }
2901
2433
  /**
2902
2434
  * 下载 OBJ
2903
2435
  * @param filename
2904
2436
  * @returns
2905
2437
  */
2906
- async downloadOBJ(filename) {
2907
- if (typeof window !== "undefined") {
2908
- const blob = await this.toOBJBlob();
2909
- if (!blob) return;
2910
- const a = document.createElement("a");
2911
- a.href = URL.createObjectURL(blob);
2912
- a.download = filename;
2913
- a.click();
2914
- } else if (typeof global !== "undefined") {
2915
- const buffer = await this.toOBJ();
2916
- if (buffer) {
2917
- const fs = await include("fs", false);
2918
- fs.writeFileSync(filename, buffer);
2919
- }
2438
+ async downloadOBJ(t) {
2439
+ if (typeof window < "u") {
2440
+ const e = await this.toOBJBlob();
2441
+ if (!e) return;
2442
+ const n = document.createElement("a");
2443
+ n.href = URL.createObjectURL(e), n.download = t, n.click();
2444
+ } else if (typeof global < "u") {
2445
+ const e = await this.toOBJ();
2446
+ e && (await G("fs", !1)).writeFileSync(t, e);
2920
2447
  }
2921
2448
  }
2922
2449
  /**
@@ -2924,24 +2451,19 @@ class WhiteModel extends Component {
2924
2451
  * @param filename
2925
2452
  * @returns
2926
2453
  */
2927
- async downloadGltf(filename, binary = true) {
2928
- if (typeof window !== "undefined") {
2929
- const blob = await this.toGltfBlob(binary);
2930
- if (!blob) return;
2931
- const a = document.createElement("a");
2932
- a.href = URL.createObjectURL(blob);
2933
- a.download = filename;
2934
- a.click();
2935
- } else if (typeof global !== "undefined") {
2936
- const buffer = await this.toGltf(binary);
2937
- if (buffer) {
2938
- const fs = await include("fs", false);
2939
- fs.writeFileSync(filename, binary ? buffer : Buffer.from(buffer));
2940
- }
2454
+ async downloadGltf(t, e = !0) {
2455
+ if (typeof window < "u") {
2456
+ const n = await this.toGltfBlob(e);
2457
+ if (!n) return;
2458
+ const i = document.createElement("a");
2459
+ i.href = URL.createObjectURL(n), i.download = t, i.click();
2460
+ } else if (typeof global < "u") {
2461
+ const n = await this.toGltf(e);
2462
+ n && (await G("fs", !1)).writeFileSync(t, e ? n : Buffer.from(n));
2941
2463
  }
2942
2464
  }
2943
2465
  }
2944
- class DetailsPoint extends Component {
2466
+ class Z extends q {
2945
2467
  static name = "DetailsPoint";
2946
2468
  Dxf = null;
2947
2469
  WhiteModel = null;
@@ -2949,10 +2471,8 @@ class DetailsPoint extends Component {
2949
2471
  desPoints = [];
2950
2472
  raylines = [];
2951
2473
  data = [];
2952
- onAddFromParent(parent) {
2953
- this.Dxf = parent.findComponentByName("Dxf");
2954
- this.Variable = parent.findComponentByName("Variable");
2955
- this.Dxf?.addEventListener("setDta", () => {
2474
+ onAddFromParent(t) {
2475
+ this.Dxf = t.findComponentByName("Dxf"), this.Variable = t.findComponentByName("Variable"), this.Dxf?.addEventListener("setDta", () => {
2956
2476
  this.updateModel();
2957
2477
  });
2958
2478
  }
@@ -2960,37 +2480,29 @@ class DetailsPoint extends Component {
2960
2480
  * 设置值
2961
2481
  * @param data
2962
2482
  */
2963
- async set(data) {
2964
- if (typeof data === "string") {
2965
- if (typeof global !== "undefined") {
2966
- const packageName = "fs";
2967
- const { default: fs } = await import(
2483
+ async set(t) {
2484
+ if (typeof t == "string")
2485
+ if (typeof global < "u") {
2486
+ const { default: n } = await import(
2968
2487
  /* @vite-ignore */
2969
- packageName
2970
- );
2971
- const buffer = fs.readFileSync(data);
2972
- const json = JSON.parse(buffer.toString("utf-8"));
2973
- this.set(json);
2488
+ "fs"
2489
+ ), i = n.readFileSync(t), s = JSON.parse(i.toString("utf-8"));
2490
+ this.set(s);
2974
2491
  return;
2975
- } else {
2492
+ } else
2976
2493
  throw new Error("非node环境不允许使用路径");
2977
- }
2978
- }
2979
- this.data = data;
2980
- this.updateModel();
2494
+ this.data = t, this.updateModel();
2981
2495
  }
2982
2496
  /**
2983
2497
  * 设置射线辅助
2984
2498
  */
2985
- racasterHelper(position, direction, far) {
2986
- this.raylines.push([
2987
- position.clone(),
2988
- position.clone().add(direction.clone().multiplyScalar(far))
2989
- ]);
2990
- direction.z = 0;
2499
+ racasterHelper(t, e, n) {
2991
2500
  this.raylines.push([
2992
- position.clone(),
2993
- position.clone().add(direction.clone().multiplyScalar(far))
2501
+ t.clone(),
2502
+ t.clone().add(e.clone().multiplyScalar(n))
2503
+ ]), e.z = 0, this.raylines.push([
2504
+ t.clone(),
2505
+ t.clone().add(e.clone().multiplyScalar(n))
2994
2506
  ]);
2995
2507
  }
2996
2508
  _timer = null;
@@ -2998,159 +2510,136 @@ class DetailsPoint extends Component {
2998
2510
  * 更新模型
2999
2511
  */
3000
2512
  updateModel() {
3001
- if (this._timer) clearTimeout(this._timer);
3002
- this._timer = setTimeout(() => {
2513
+ this._timer && clearTimeout(this._timer), this._timer = setTimeout(() => {
3003
2514
  this._timer = null;
3004
- const whiteModel = this.parent?.findComponentByName("WhiteModel");
3005
- this.raylines.length = 0;
3006
- this.desPoints.length = 0;
3007
- this.data.forEach((item) => {
3008
- const position = new THREE.Vector3(
3009
- item.position.x,
3010
- item.position.y,
3011
- item.position.z
3012
- );
3013
- const direction = new THREE.Vector3(
3014
- item.direction.x,
3015
- item.direction.y,
3016
- item.direction.z
3017
- );
3018
- const far = 100;
3019
- this.racasterHelper(position, direction, far);
3020
- direction.z = 0;
3021
- const raycaster = new THREE.Raycaster(position, direction, 0, far);
3022
- const list = raycaster.intersectObject(whiteModel.originalWhiteMode);
3023
- if (list.length) {
3024
- const { point } = list[0];
2515
+ const t = this.parent?.findComponentByName("WhiteModel");
2516
+ this.raylines.length = 0, this.desPoints.length = 0, this.data.forEach((e) => {
2517
+ const n = new M.Vector3(
2518
+ e.position.x,
2519
+ e.position.y,
2520
+ e.position.z
2521
+ ), i = new M.Vector3(
2522
+ e.direction.x,
2523
+ e.direction.y,
2524
+ e.direction.z
2525
+ ), s = 100;
2526
+ this.racasterHelper(n, i, s), i.z = 0;
2527
+ const r = new M.Raycaster(n, i, 0, s).intersectObject(t.originalWhiteMode);
2528
+ if (r.length) {
2529
+ const { point: a } = r[0];
3025
2530
  this.desPoints.push({
3026
- message: item.desc,
3027
- position,
3028
- intersection: point
2531
+ message: e.desc,
2532
+ position: n,
2533
+ intersection: a
3029
2534
  });
3030
2535
  }
3031
- });
3032
- this.dispatchEvent({
2536
+ }), this.dispatchEvent({
3033
2537
  type: "handleSuccess",
3034
2538
  desPoints: this.desPoints
3035
2539
  });
3036
2540
  }, 50);
3037
2541
  }
3038
2542
  }
3039
- class DxfLineModel extends Component {
2543
+ class K extends q {
3040
2544
  static name = "DxfLineModel";
3041
- dxfLineModel = new THREE.LineSegments();
3042
- dxfDoorsLineModel = new THREE.LineSegments();
3043
- dxfModelGroup = new THREE.Group();
3044
- onAddFromParent(parent) {
3045
- const dxf = parent.findComponentByName("Dxf");
3046
- this.dxfModelGroup.add(this.dxfLineModel);
3047
- this.dxfModelGroup.add(this.dxfDoorsLineModel);
3048
- this.dxfDoorsLineModel.material = new THREE.LineBasicMaterial({ color: 16776960, vertexColors: true });
3049
- dxf?.addEventListener("lineOffset", () => this.updateMode());
2545
+ dxfLineModel = new M.LineSegments();
2546
+ dxfDoorsLineModel = new M.LineSegments();
2547
+ dxfModelGroup = new M.Group();
2548
+ onAddFromParent(t) {
2549
+ const e = t.findComponentByName("Dxf");
2550
+ this.dxfModelGroup.add(this.dxfLineModel), this.dxfModelGroup.add(this.dxfDoorsLineModel), this.dxfDoorsLineModel.material = new M.LineBasicMaterial({ color: 16776960, vertexColors: !0 }), e?.addEventListener("lineOffset", () => this.updateMode());
3050
2551
  }
3051
2552
  updateMode() {
3052
- const dxf = this.parent?.findComponentByName("Dxf");
2553
+ const t = this.parent?.findComponentByName("Dxf");
3053
2554
  this.dxfLineModel.clear();
3054
- const dxfArray = dxf.to3DArray(1 / dxf.scale, 0);
3055
- this.dxfLineModel.geometry = new THREE.BufferGeometry().setAttribute("position", new THREE.BufferAttribute(dxfArray, 3, true));
3056
- const doorsArray = new Float32Array(
3057
- dxf.doorLineSegment.flatMap(({ start, end }) => [start.x, start.y, 0, end.x, end.y, 0])
3058
- ).map((n) => n / dxf.scale);
3059
- const doorsColorArray = new Float32Array(dxf.doorLineSegment.flatMap(() => [1, 0, 0, 0, 1, 0]));
3060
- this.dxfDoorsLineModel.geometry = new THREE.BufferGeometry().setAttribute("position", new THREE.BufferAttribute(doorsArray, 3, true)).setAttribute("color", new THREE.BufferAttribute(doorsColorArray, 3));
3061
- this.dxfModelGroup.position.z = dxf.originalZAverage;
3062
- this.dispatchEvent({
2555
+ const e = t.to3DArray(1 / t.scale, 0);
2556
+ this.dxfLineModel.geometry = new M.BufferGeometry().setAttribute("position", new M.BufferAttribute(e, 3, !0));
2557
+ const n = new Float32Array(
2558
+ t.doorLineSegment.flatMap(({ start: s, end: o }) => [s.x, s.y, 0, o.x, o.y, 0])
2559
+ ).map((s) => s / t.scale), i = new Float32Array(t.doorLineSegment.flatMap(() => [1, 0, 0, 0, 1, 0]));
2560
+ this.dxfDoorsLineModel.geometry = new M.BufferGeometry().setAttribute("position", new M.BufferAttribute(n, 3, !0)).setAttribute("color", new M.BufferAttribute(i, 3)), this.dxfModelGroup.position.z = t.originalZAverage, this.dispatchEvent({
3063
2561
  type: "modelUpdate",
3064
2562
  model: this.dxfModelGroup
3065
2563
  });
3066
2564
  }
3067
2565
  }
3068
- const index$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2566
+ const ut = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
3069
2567
  __proto__: null,
3070
- DetailsPoint,
3071
- DxfLineModel,
3072
- WhiteModel
2568
+ DetailsPoint: Z,
2569
+ DxfLineModel: K,
2570
+ WhiteModel: H
3073
2571
  }, Symbol.toStringTag, { value: "Module" }));
3074
- function ModelDataPlugin_(dxfSystem, option = {}) {
2572
+ function W(g, t = {}) {
3075
2573
  const {
3076
- detailsPoint = true,
3077
- whiteModel = true,
3078
- dxfLineModel = true
3079
- } = option;
3080
- dxfLineModel && dxfSystem.addComponent(new DxfLineModel());
3081
- whiteModel && dxfSystem.addComponent(new WhiteModel());
3082
- detailsPoint && dxfSystem.addComponent(new DetailsPoint());
2574
+ detailsPoint: e = !0,
2575
+ whiteModel: n = !0,
2576
+ dxfLineModel: i = !0
2577
+ } = t;
2578
+ i && g.addComponent(new K()), n && g.addComponent(new H()), e && g.addComponent(new Z());
3083
2579
  }
3084
- const ModelDataPlugin = Object.assign(ModelDataPlugin_, {
3085
- create(option = {}) {
3086
- return (dxfSystem) => ModelDataPlugin_(dxfSystem, option);
2580
+ const ft = Object.assign(W, {
2581
+ create(g = {}) {
2582
+ return (t) => W(t, g);
3087
2583
  }
3088
- });
3089
- const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2584
+ }), pt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
3090
2585
  __proto__: null,
3091
- ModelDataPlugin,
3092
- components: index$1
2586
+ ModelDataPlugin: ft,
2587
+ components: ut
3093
2588
  }, Symbol.toStringTag, { value: "Module" }));
3094
- function loadRenderPlugin() {
2589
+ function mt() {
3095
2590
  return import("./index2.js");
3096
2591
  }
3097
- function loadEditorPlugin() {
2592
+ function xt() {
3098
2593
  return import("./index3.js");
3099
2594
  }
3100
- let gloabalDxfSystem = null;
3101
- async function createEditor(dom, camera, orbitControls = false, viewPermission) {
3102
- const mp = await Promise.resolve().then(() => index);
3103
- const rp = await loadRenderPlugin();
3104
- const editor = await loadEditorPlugin();
3105
- const dxfSystem = new DxfSystem().usePlugin(mp.ModelDataPlugin.create({
3106
- detailsPoint: false,
3107
- whiteModel: true
3108
- })).usePlugin(rp.RenderPlugin.create({
3109
- originalLine: false,
3110
- modelData: false,
3111
- detailsPoint: false,
3112
- orbitControls,
3113
- camera
3114
- })).usePlugin(editor.Editor.create({ viewPermission }));
3115
- const domContainer = dxfSystem.findComponentByType(rp.components.DomContainer);
3116
- domContainer && dom.appendChild(domContainer.domElement);
3117
- gloabalDxfSystem = dxfSystem;
3118
- return {
3119
- dxfSystem,
3120
- getFileAll: () => getFileAll(dxfSystem)
2595
+ let z = null;
2596
+ async function Et(g, t, e = !1, n) {
2597
+ const i = await Promise.resolve().then(() => pt), s = await mt(), o = await xt(), r = new ct().usePlugin(i.ModelDataPlugin.create({
2598
+ detailsPoint: !1,
2599
+ whiteModel: !0
2600
+ })).usePlugin(s.RenderPlugin.create({
2601
+ originalLine: !1,
2602
+ modelData: !1,
2603
+ detailsPoint: !1,
2604
+ orbitControls: e,
2605
+ camera: t
2606
+ })).usePlugin(o.Editor.create({ viewPermission: n })), a = r.findComponentByType(s.components.DomContainer);
2607
+ return a && g.appendChild(a.domElement), z = r, {
2608
+ dxfSystem: r,
2609
+ getFileAll: () => yt(r)
3121
2610
  };
3122
2611
  }
3123
- async function getFileAll(dxfSystem = gloabalDxfSystem) {
3124
- const whiteModel = dxfSystem.findComponentByName("WhiteModel");
3125
- const dxf = new File([dxfSystem.Dxf.toDxfBlob()], "dxf.dxf", { type: "application/dxf" });
3126
- const obj = new File([await whiteModel.toOBJBlob()], "model.obj", { type: "application/octet-stream" });
3127
- const glb = new File([await whiteModel.toGltfBlob(true)], "model.glb", { type: "application/octet-stream" });
3128
- const gltf = new File([await whiteModel.toGltfBlob(false)], "model.gltf", { type: "application/json" });
2612
+ async function yt(g = z) {
2613
+ const t = g.findComponentByName("WhiteModel"), e = new File([await g.AngleCorrectionDxf.toDxfImageBlob()], "img.jpg", { type: "image/jpeg" }), n = new File([g.Dxf.toDxfBlob()], "dxf.dxf", { type: "application/dxf" }), i = new File([g.AngleCorrectionDxf.toDxfBlob()], "dxf.dxf", { type: "application/dxf" }), s = new File([await t.toOBJBlob()], "model.obj", { type: "application/octet-stream" }), o = new File([await t.toGltfBlob(!0)], "model.glb", { type: "application/octet-stream" }), r = new File([await t.toGltfBlob(!1)], "model.gltf", { type: "application/json" }), a = new File([JSON.stringify(g.Dxf.originalData)], "json.json", { type: "application/json" });
3129
2614
  return {
3130
- dxf,
3131
- obj,
3132
- glb,
3133
- gltf
2615
+ dxf: n,
2616
+ obj: s,
2617
+ glb: o,
2618
+ gltf: r,
2619
+ json: a,
2620
+ jpg: e,
2621
+ correctionDxf: i
3134
2622
  };
3135
2623
  }
3136
- function getGlobalDxfSystem() {
3137
- return gloabalDxfSystem;
2624
+ function At() {
2625
+ return z;
3138
2626
  }
3139
2627
  export {
3140
- Box2 as B,
3141
- Component as C,
3142
- DxfSystem as D,
3143
- EventDispatcher as E,
3144
- LineSegment as L,
3145
- ModelDataPlugin as M,
3146
- Point as P,
3147
- Quadtree as Q,
3148
- Variable as V,
3149
- WhiteModel as W,
3150
- DetailsPoint as a,
3151
- PointVirtualGrid as b,
3152
- createEditor as c,
3153
- getGlobalDxfSystem as d,
3154
- getFileAll as g,
3155
- index$1 as i
2628
+ v as B,
2629
+ q as C,
2630
+ ct as D,
2631
+ $ as E,
2632
+ L,
2633
+ ft as M,
2634
+ p as P,
2635
+ j as Q,
2636
+ _ as V,
2637
+ H as W,
2638
+ Z as a,
2639
+ U as b,
2640
+ Et as c,
2641
+ At as d,
2642
+ yt as g,
2643
+ ut as i,
2644
+ N as u
3156
2645
  };