build-dxf 0.0.5 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -3
- package/package.json +1 -1
- package/src/index.d.ts +23 -1
- package/src/index.js +248 -33
package/README.md
CHANGED
|
@@ -7,10 +7,16 @@ npm i build-dxf
|
|
|
7
7
|
|
|
8
8
|
# 使用
|
|
9
9
|
```typescript
|
|
10
|
+
|
|
10
11
|
import { DxfSystem } from "build-dxf"
|
|
11
12
|
|
|
13
|
+
/**
|
|
14
|
+
* json 文件格式为{ start: {x: number, y: number}, end: {x: number, y: number } , insetionArr: {index: number}[] }[]
|
|
15
|
+
*/
|
|
16
|
+
const path = process.argv[2] ?? "./json/d7.json"
|
|
12
17
|
const dxfSystem = new DxfSystem()
|
|
13
|
-
dxfSystem.Dxf.set(
|
|
14
|
-
dxfSystem.Dxf.lineOffset()
|
|
15
|
-
dxfSystem.Dxf.download("01.dxf")
|
|
18
|
+
dxfSystem.Dxf.set(path).then(()=> {
|
|
19
|
+
dxfSystem.Dxf.lineOffset()
|
|
20
|
+
dxfSystem.Dxf.download("01.dxf")
|
|
21
|
+
})
|
|
16
22
|
```
|
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
|
@@ -10,6 +10,12 @@ declare class Box2 {
|
|
|
10
10
|
get height(): number;
|
|
11
11
|
get center(): Point;
|
|
12
12
|
constructor(minX?: number, maxX?: number, minY?: number, maxY?: number);
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
* @param z
|
|
16
|
+
* @returns
|
|
17
|
+
*/
|
|
18
|
+
getPaths3D(z?: number): number[];
|
|
13
19
|
/**
|
|
14
20
|
* 判断线段是与包围盒相交
|
|
15
21
|
* @description Liang-Barsky算法的变种
|
|
@@ -41,6 +47,10 @@ declare class Box2 {
|
|
|
41
47
|
* @param box
|
|
42
48
|
*/
|
|
43
49
|
containsBox(box: Box2): boolean;
|
|
50
|
+
/** 判断点是在包围盒内
|
|
51
|
+
* @param point
|
|
52
|
+
*/
|
|
53
|
+
containsPoint(point: Point): boolean;
|
|
44
54
|
/**
|
|
45
55
|
*
|
|
46
56
|
* @param minX
|
|
@@ -340,6 +350,7 @@ declare class Point {
|
|
|
340
350
|
* @param y
|
|
341
351
|
*/
|
|
342
352
|
constructor(x?: number, y?: number);
|
|
353
|
+
set(x: number, y: number): this;
|
|
343
354
|
setX(x: number): this;
|
|
344
355
|
setY(y: number): this;
|
|
345
356
|
/**
|
|
@@ -362,6 +373,7 @@ declare class Point {
|
|
|
362
373
|
* @param scalar
|
|
363
374
|
*/
|
|
364
375
|
mutiplyScalar(scalar: number): this;
|
|
376
|
+
multiplyScalar(scalar: number): this;
|
|
365
377
|
/**
|
|
366
378
|
*
|
|
367
379
|
* @param scalar
|
|
@@ -401,7 +413,7 @@ declare class Point {
|
|
|
401
413
|
*/
|
|
402
414
|
normal(point: Point): Point;
|
|
403
415
|
/**
|
|
404
|
-
*
|
|
416
|
+
* 获取由传入的点到该点的单位方向向量
|
|
405
417
|
* @description 计算当前点到指定点的方向向量,并返回单位方向
|
|
406
418
|
* @param point
|
|
407
419
|
* @returns
|
|
@@ -460,6 +472,16 @@ declare class Rectangle {
|
|
|
460
472
|
* @returns 是否完全在矩形内部
|
|
461
473
|
*/
|
|
462
474
|
containsLineSegment(line: LineSegment): boolean;
|
|
475
|
+
/**
|
|
476
|
+
* 判断点是否完全位于矩形内部
|
|
477
|
+
* @param point
|
|
478
|
+
*/
|
|
479
|
+
containsPoint(point: Point): boolean;
|
|
480
|
+
/**
|
|
481
|
+
*
|
|
482
|
+
* @returns
|
|
483
|
+
*/
|
|
484
|
+
toBox(): Box2;
|
|
463
485
|
/**
|
|
464
486
|
*
|
|
465
487
|
* @param line
|
package/src/index.js
CHANGED
|
@@ -12545,6 +12545,11 @@ class Point {
|
|
|
12545
12545
|
this.x = x;
|
|
12546
12546
|
this.y = y;
|
|
12547
12547
|
}
|
|
12548
|
+
set(x, y) {
|
|
12549
|
+
this.x = x;
|
|
12550
|
+
this.y = y;
|
|
12551
|
+
return this;
|
|
12552
|
+
}
|
|
12548
12553
|
setX(x) {
|
|
12549
12554
|
this.x = x;
|
|
12550
12555
|
return this;
|
|
@@ -12585,6 +12590,11 @@ class Point {
|
|
|
12585
12590
|
this.y *= scalar;
|
|
12586
12591
|
return this;
|
|
12587
12592
|
}
|
|
12593
|
+
multiplyScalar(scalar) {
|
|
12594
|
+
this.x *= scalar;
|
|
12595
|
+
this.y *= scalar;
|
|
12596
|
+
return this;
|
|
12597
|
+
}
|
|
12588
12598
|
/**
|
|
12589
12599
|
*
|
|
12590
12600
|
* @param scalar
|
|
@@ -12653,7 +12663,7 @@ class Point {
|
|
|
12653
12663
|
return new Point(nx, ny);
|
|
12654
12664
|
}
|
|
12655
12665
|
/**
|
|
12656
|
-
*
|
|
12666
|
+
* 获取由传入的点到该点的单位方向向量
|
|
12657
12667
|
* @description 计算当前点到指定点的方向向量,并返回单位方向
|
|
12658
12668
|
* @param point
|
|
12659
12669
|
* @returns
|
|
@@ -12764,6 +12774,20 @@ class Box2 {
|
|
|
12764
12774
|
this.minY = minY;
|
|
12765
12775
|
this.maxY = maxY;
|
|
12766
12776
|
}
|
|
12777
|
+
/**
|
|
12778
|
+
*
|
|
12779
|
+
* @param z
|
|
12780
|
+
* @returns
|
|
12781
|
+
*/
|
|
12782
|
+
getPaths3D(z = 0) {
|
|
12783
|
+
const points = this.points, list = [];
|
|
12784
|
+
points.forEach((p, i) => {
|
|
12785
|
+
const nextP = points[(i + 1) % points.length];
|
|
12786
|
+
list.push(p.x, p.y, z);
|
|
12787
|
+
list.push(nextP.x, nextP.y, z);
|
|
12788
|
+
});
|
|
12789
|
+
return list;
|
|
12790
|
+
}
|
|
12767
12791
|
/**
|
|
12768
12792
|
* 判断线段是与包围盒相交
|
|
12769
12793
|
* @description Liang-Barsky算法的变种
|
|
@@ -12891,6 +12915,12 @@ class Box2 {
|
|
|
12891
12915
|
containsBox(box) {
|
|
12892
12916
|
return this.minX <= box.minX && box.maxX <= this.maxX && this.minY <= box.minY && box.maxY <= this.maxY;
|
|
12893
12917
|
}
|
|
12918
|
+
/** 判断点是在包围盒内
|
|
12919
|
+
* @param point
|
|
12920
|
+
*/
|
|
12921
|
+
containsPoint(point) {
|
|
12922
|
+
return point.x >= this.minX && point.x <= this.maxX && point.y >= this.minY && point.y <= this.maxY;
|
|
12923
|
+
}
|
|
12894
12924
|
/**
|
|
12895
12925
|
*
|
|
12896
12926
|
* @param minX
|
|
@@ -13519,6 +13549,37 @@ class Rectangle {
|
|
|
13519
13549
|
};
|
|
13520
13550
|
return isPointInRectangle(line.points[0]) && isPointInRectangle(line.points[1]);
|
|
13521
13551
|
}
|
|
13552
|
+
/**
|
|
13553
|
+
* 判断点是否完全位于矩形内部
|
|
13554
|
+
* @param point
|
|
13555
|
+
*/
|
|
13556
|
+
containsPoint(point) {
|
|
13557
|
+
let positiveCount = 0;
|
|
13558
|
+
let negativeCount = 0;
|
|
13559
|
+
for (let i = 0; i < 4; i++) {
|
|
13560
|
+
const p1 = this.points[i];
|
|
13561
|
+
const p2 = this.points[(i + 1) % 4];
|
|
13562
|
+
const cross = (p2.x - p1.x) * (point.y - p1.y) - (p2.y - p1.y) * (point.x - p1.x);
|
|
13563
|
+
if (cross > 0) positiveCount++;
|
|
13564
|
+
else if (cross < 0) negativeCount++;
|
|
13565
|
+
else return false;
|
|
13566
|
+
}
|
|
13567
|
+
return positiveCount === 4 || negativeCount === 4;
|
|
13568
|
+
}
|
|
13569
|
+
/**
|
|
13570
|
+
*
|
|
13571
|
+
* @returns
|
|
13572
|
+
*/
|
|
13573
|
+
toBox() {
|
|
13574
|
+
let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
|
|
13575
|
+
this.points.forEach((p) => {
|
|
13576
|
+
maxX = Math.max(p.x, maxX);
|
|
13577
|
+
minX = Math.min(p.x, minX);
|
|
13578
|
+
maxY = Math.max(p.x, maxY);
|
|
13579
|
+
minY = Math.min(p.x, minY);
|
|
13580
|
+
});
|
|
13581
|
+
return new Box2(minX, maxX, minY, maxY);
|
|
13582
|
+
}
|
|
13522
13583
|
/**
|
|
13523
13584
|
*
|
|
13524
13585
|
* @param line
|
|
@@ -13719,8 +13780,7 @@ class Quadtree {
|
|
|
13719
13780
|
*/
|
|
13720
13781
|
queryRect(rectangle) {
|
|
13721
13782
|
const result = [];
|
|
13722
|
-
|
|
13723
|
-
if (!this.bounds.intersectBox(rectBox)) {
|
|
13783
|
+
if (!this.bounds.intersectRectangle(rectangle)) {
|
|
13724
13784
|
return result;
|
|
13725
13785
|
}
|
|
13726
13786
|
for (const node of this.nodes) {
|
|
@@ -13754,17 +13814,135 @@ class Quadtree {
|
|
|
13754
13814
|
return array;
|
|
13755
13815
|
}
|
|
13756
13816
|
}
|
|
13817
|
+
class PointVirtualGrid {
|
|
13818
|
+
map = /* @__PURE__ */ new Map();
|
|
13819
|
+
gridSize;
|
|
13820
|
+
constructor(gridSize = 2) {
|
|
13821
|
+
this.gridSize = gridSize;
|
|
13822
|
+
}
|
|
13823
|
+
/**
|
|
13824
|
+
* 插入
|
|
13825
|
+
* @param point
|
|
13826
|
+
* @param userData
|
|
13827
|
+
*/
|
|
13828
|
+
insert(point, userData) {
|
|
13829
|
+
if (!point || isNaN(point.x) || isNaN(point.y)) {
|
|
13830
|
+
throw new Error("无效的点坐标");
|
|
13831
|
+
}
|
|
13832
|
+
const id = this.getGridId(point);
|
|
13833
|
+
if (!this.map.has(id)) this.map.set(id, /* @__PURE__ */ new Set());
|
|
13834
|
+
const set = this.map.get(id);
|
|
13835
|
+
set?.add({ point, userData });
|
|
13836
|
+
}
|
|
13837
|
+
/**
|
|
13838
|
+
* 批量加入
|
|
13839
|
+
* @param points
|
|
13840
|
+
*/
|
|
13841
|
+
insertBatch(points) {
|
|
13842
|
+
for (const { point, userData } of points) {
|
|
13843
|
+
this.insert(point, userData);
|
|
13844
|
+
}
|
|
13845
|
+
}
|
|
13846
|
+
/**
|
|
13847
|
+
* 获取通过坐标,获取唯一网格索引
|
|
13848
|
+
* @param point
|
|
13849
|
+
* @returns
|
|
13850
|
+
*/
|
|
13851
|
+
getGridId(point) {
|
|
13852
|
+
const i = Math.ceil(point.x / this.gridSize), j = Math.ceil(point.y / this.gridSize);
|
|
13853
|
+
return `${i}.${j}`;
|
|
13854
|
+
}
|
|
13855
|
+
/**
|
|
13856
|
+
*
|
|
13857
|
+
* @param gridId
|
|
13858
|
+
* @returns
|
|
13859
|
+
*/
|
|
13860
|
+
decodeGridId(gridId) {
|
|
13861
|
+
const [i, j] = gridId.split(".").map(Number);
|
|
13862
|
+
return new Point(i, j);
|
|
13863
|
+
}
|
|
13864
|
+
/**
|
|
13865
|
+
* 查询与矩形相交的点
|
|
13866
|
+
* @param rectangle 矩形
|
|
13867
|
+
* @returns 相交的节点数组
|
|
13868
|
+
*/
|
|
13869
|
+
queryRect(rectangle) {
|
|
13870
|
+
const box2 = rectangle.toBox();
|
|
13871
|
+
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);
|
|
13872
|
+
for (let i = minI; i <= maxI; i++) {
|
|
13873
|
+
for (let j = minJ; j <= maxJ; j++) {
|
|
13874
|
+
const id = `${i}.${j}`;
|
|
13875
|
+
if (!this.map.has(id)) continue;
|
|
13876
|
+
const set = this.map.get(id);
|
|
13877
|
+
set?.forEach((item) => {
|
|
13878
|
+
if (rectangle.containsPoint(item.point)) ;
|
|
13879
|
+
});
|
|
13880
|
+
}
|
|
13881
|
+
}
|
|
13882
|
+
}
|
|
13883
|
+
/**
|
|
13884
|
+
* 查询与圆形区域相交的点
|
|
13885
|
+
* @param pos 圆心
|
|
13886
|
+
* @param radius 半径
|
|
13887
|
+
* @returns 相交的节点数组
|
|
13888
|
+
*/
|
|
13889
|
+
queryCircle(pos, radius) {
|
|
13890
|
+
const box2 = new Box2(pos.x - radius, pos.x + radius, pos.y - radius, pos.y + radius);
|
|
13891
|
+
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 = [];
|
|
13892
|
+
for (let i = minI; i <= maxI; i++) {
|
|
13893
|
+
for (let j = minJ; j <= maxJ; j++) {
|
|
13894
|
+
const id = `${i}.${j}`;
|
|
13895
|
+
if (!this.map.has(id)) continue;
|
|
13896
|
+
const set = this.map.get(id);
|
|
13897
|
+
set?.forEach((item) => {
|
|
13898
|
+
if (pos.distance(item.point) <= radius) list.push(item);
|
|
13899
|
+
});
|
|
13900
|
+
}
|
|
13901
|
+
}
|
|
13902
|
+
return list;
|
|
13903
|
+
}
|
|
13904
|
+
/**
|
|
13905
|
+
* 查询与包围盒相交的点
|
|
13906
|
+
* @param box2 包围盒
|
|
13907
|
+
* @returns 相交的节点数组
|
|
13908
|
+
*/
|
|
13909
|
+
queryBox(box2) {
|
|
13910
|
+
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 = [];
|
|
13911
|
+
for (let i = minI; i <= maxI; i++) {
|
|
13912
|
+
for (let j = minJ; j <= maxJ; j++) {
|
|
13913
|
+
const id = `${i}.${j}`;
|
|
13914
|
+
if (!this.map.has(id)) continue;
|
|
13915
|
+
const set = this.map.get(id);
|
|
13916
|
+
set?.forEach((item) => {
|
|
13917
|
+
if (box2.containsPoint(item.point)) list.push(item);
|
|
13918
|
+
});
|
|
13919
|
+
}
|
|
13920
|
+
}
|
|
13921
|
+
return list;
|
|
13922
|
+
}
|
|
13923
|
+
/**
|
|
13924
|
+
* 查找相同点
|
|
13925
|
+
* @param point
|
|
13926
|
+
*/
|
|
13927
|
+
queryPoint(point) {
|
|
13928
|
+
const id = this.getGridId(point), list = [];
|
|
13929
|
+
if (this.map.has(id)) {
|
|
13930
|
+
const set = this.map.get(id);
|
|
13931
|
+
set?.forEach((item) => {
|
|
13932
|
+
if (point.equal(item.point)) list.push(item);
|
|
13933
|
+
});
|
|
13934
|
+
}
|
|
13935
|
+
return list;
|
|
13936
|
+
}
|
|
13937
|
+
}
|
|
13757
13938
|
class LineAnalysis extends Component {
|
|
13758
13939
|
Dxf = null;
|
|
13759
13940
|
Variable = null;
|
|
13760
13941
|
lineSegmentList = [];
|
|
13761
13942
|
container = new Group();
|
|
13762
|
-
showQuadtreeGrid = false;
|
|
13763
|
-
showLineInfo = false;
|
|
13764
|
-
showProjectLineInfo = false;
|
|
13765
|
-
showSearchRectangle = false;
|
|
13766
13943
|
// 误差角度
|
|
13767
13944
|
errorAngle = 4;
|
|
13945
|
+
width = 0.4;
|
|
13768
13946
|
/**
|
|
13769
13947
|
*
|
|
13770
13948
|
* @param parent
|
|
@@ -13781,16 +13959,25 @@ class LineAnalysis extends Component {
|
|
|
13781
13959
|
*/
|
|
13782
13960
|
duplicatePointFiltering() {
|
|
13783
13961
|
const dxf = this.Dxf;
|
|
13784
|
-
dxf.wallsGroup = dxf.wallsGroup.filter((i) => i.length >= 4);
|
|
13785
13962
|
dxf.wallsGroup = dxf.wallsGroup.map((points) => {
|
|
13786
13963
|
const filterPoints = [];
|
|
13787
13964
|
points.forEach((point, index) => {
|
|
13788
13965
|
if (index < 1 || points.length - 1 === index) return filterPoints.push(point);
|
|
13789
13966
|
const preP = points[index - 1], nextP = points[index + 1], direct1 = point.direction(preP), direct2 = nextP.direction(point), angle = direct1.angleBetween(direct2) / (Math.PI / 180);
|
|
13790
|
-
if (angle > 0.
|
|
13967
|
+
if (angle > 0.02 && angle < 180 - 0.02) filterPoints.push(point);
|
|
13791
13968
|
});
|
|
13792
|
-
|
|
13969
|
+
points = [filterPoints[0]];
|
|
13970
|
+
for (let i = 1; i < filterPoints.length; i++) {
|
|
13971
|
+
const point = filterPoints[i];
|
|
13972
|
+
const nextP = filterPoints[i - 1];
|
|
13973
|
+
if (nextP.distance(point) < dxf.width * 0.5) {
|
|
13974
|
+
console.log(111);
|
|
13975
|
+
}
|
|
13976
|
+
points.push(point);
|
|
13977
|
+
}
|
|
13978
|
+
return points;
|
|
13793
13979
|
});
|
|
13980
|
+
dxf.wallsGroup = dxf.wallsGroup.filter((i) => i.length >= 4);
|
|
13794
13981
|
}
|
|
13795
13982
|
/**
|
|
13796
13983
|
*
|
|
@@ -13818,29 +14005,50 @@ class LineAnalysis extends Component {
|
|
|
13818
14005
|
rectIndices: [0, 1, 3, 2, 0]
|
|
13819
14006
|
};
|
|
13820
14007
|
}
|
|
14008
|
+
appendLineSegmentList = [];
|
|
14009
|
+
/**
|
|
14010
|
+
* 追加数据
|
|
14011
|
+
* @param p1
|
|
14012
|
+
* @param p2
|
|
14013
|
+
*/
|
|
14014
|
+
addData(p1, p2) {
|
|
14015
|
+
const dxf = this.Dxf;
|
|
14016
|
+
dxf.data.push([p1.clone(), p2.clone(), [], false, dxf.data.length]);
|
|
14017
|
+
this.appendLineSegmentList.push(new LineSegment(p1.clone(), p2.clone()));
|
|
14018
|
+
}
|
|
13821
14019
|
/** 结果分析创建矩形
|
|
13822
14020
|
* @param result
|
|
13823
14021
|
*/
|
|
13824
14022
|
createRectangle(result) {
|
|
13825
14023
|
const dxf = this.Dxf;
|
|
13826
|
-
const
|
|
13827
|
-
|
|
13828
|
-
|
|
13829
|
-
const
|
|
13830
|
-
|
|
13831
|
-
|
|
13832
|
-
|
|
13833
|
-
);
|
|
13834
|
-
|
|
13835
|
-
|
|
13836
|
-
|
|
13837
|
-
|
|
13838
|
-
const temDirect = p2.direction(p1).mutiplyScalar(dxf.width);
|
|
13839
|
-
p2.division(temDirect);
|
|
13840
|
-
p1.division(temDirect.mutiplyScalar(-1));
|
|
13841
|
-
dxf.data.push([p1, p2, [], false, dxf.data.length]);
|
|
14024
|
+
const project0 = result.project, project1 = result.project2;
|
|
14025
|
+
this.addData(project0.points[0], project1.points[0]);
|
|
14026
|
+
this.addData(project0.points[1], project1.points[1]);
|
|
14027
|
+
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);
|
|
14028
|
+
direction.multiplyScalar(dxf.width * 0.5);
|
|
14029
|
+
const _leftP = leftP.clone().add(direction), _rightP = rightP.clone().add(direction.multiplyScalar(-1)), d1 = leftP.direction(rightP), d2 = _leftP.direction(_rightP);
|
|
14030
|
+
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;
|
|
14031
|
+
leftP.set(_leftP.x, _leftP.y);
|
|
14032
|
+
rightP.set(_rightP.x, _rightP.y);
|
|
14033
|
+
for (let i = 1; i < count; i++) {
|
|
14034
|
+
const left = leftDirection.clone().multiplyScalar(leftFragment * i), right = rightDirection.clone().multiplyScalar(rightFragment * i), p1 = leftP.clone().add(left), p2 = rightP.clone().add(right);
|
|
14035
|
+
this.addData(p1, p2);
|
|
13842
14036
|
}
|
|
13843
14037
|
}
|
|
14038
|
+
pointVirtualGrid = new PointVirtualGrid();
|
|
14039
|
+
/**
|
|
14040
|
+
* 构建点的虚拟网格索引
|
|
14041
|
+
*/
|
|
14042
|
+
buildVirtualGrid() {
|
|
14043
|
+
const dxf = this.Dxf;
|
|
14044
|
+
const pointVirtualGrid = new PointVirtualGrid();
|
|
14045
|
+
dxf.originalData.forEach((d, index) => {
|
|
14046
|
+
const [p1, p2] = [Point.from(d.start), Point.from(d.end)];
|
|
14047
|
+
pointVirtualGrid.insert(p1, { index, type: "start" });
|
|
14048
|
+
pointVirtualGrid.insert(p2, { index, type: "end" });
|
|
14049
|
+
});
|
|
14050
|
+
this.pointVirtualGrid = pointVirtualGrid;
|
|
14051
|
+
}
|
|
13844
14052
|
quadtree;
|
|
13845
14053
|
/**
|
|
13846
14054
|
* 构建线段四叉树,快速查找,
|
|
@@ -13848,7 +14056,7 @@ class LineAnalysis extends Component {
|
|
|
13848
14056
|
buildQuadtree() {
|
|
13849
14057
|
const dxf = this.Dxf;
|
|
13850
14058
|
const lineSegmentList = [];
|
|
13851
|
-
this.quadtree = new Quadtree(
|
|
14059
|
+
this.quadtree = new Quadtree(dxf.originalBox, 2);
|
|
13852
14060
|
dxf.originalData.forEach((d) => {
|
|
13853
14061
|
if (d.isDoor) return;
|
|
13854
14062
|
const lineSegment = new LineSegment(Point.from(d.start), Point.from(d.end));
|
|
@@ -13867,11 +14075,12 @@ class LineAnalysis extends Component {
|
|
|
13867
14075
|
*/
|
|
13868
14076
|
lineAnalysis() {
|
|
13869
14077
|
this.buildQuadtree();
|
|
14078
|
+
this.buildVirtualGrid();
|
|
13870
14079
|
const quadtree = this.quadtree;
|
|
13871
14080
|
const lineSegmentList = this.lineSegmentList;
|
|
13872
14081
|
const visited = /* @__PURE__ */ new Set(), resultList = [];
|
|
13873
14082
|
lineSegmentList.forEach((_0, i) => {
|
|
13874
|
-
const sourceLineSegment = lineSegmentList[i], rectangle = Rectangle.fromByLineSegment(sourceLineSegment,
|
|
14083
|
+
const sourceLineSegment = lineSegmentList[i], rectangle = Rectangle.fromByLineSegment(sourceLineSegment, this.width * 2, false, -0.01), ids = quadtree.queryRect(rectangle).map((i2) => i2.userData).filter((index) => index !== i);
|
|
13875
14084
|
ids.forEach((id) => {
|
|
13876
14085
|
try {
|
|
13877
14086
|
if (visited.has(`${i}-${id}`) || visited.has(`${id}-${i}`)) return;
|
|
@@ -13879,10 +14088,10 @@ class LineAnalysis extends Component {
|
|
|
13879
14088
|
if (res) resultList.push(res);
|
|
13880
14089
|
visited.add(`${i}-${id}`);
|
|
13881
14090
|
} catch (error) {
|
|
13882
|
-
console.log(error);
|
|
13883
14091
|
}
|
|
13884
14092
|
});
|
|
13885
14093
|
});
|
|
14094
|
+
this.appendLineSegmentList.length = 0;
|
|
13886
14095
|
resultList.forEach(this.createRectangle.bind(this));
|
|
13887
14096
|
this.resultList = [];
|
|
13888
14097
|
}
|
|
@@ -13896,13 +14105,18 @@ class LineAnalysis extends Component {
|
|
|
13896
14105
|
const temLineSegment = lineSegmentList[index], direct = sourceLineSegment.direction(), temDirect = temLineSegment.direction(), angle = direct.angleBetween(temDirect) / (Math.PI / 180);
|
|
13897
14106
|
if (angle < this.errorAngle || angle > 180 - this.errorAngle) {
|
|
13898
14107
|
let data;
|
|
13899
|
-
|
|
14108
|
+
const p1 = temLineSegment.projectLineSegment(sourceLineSegment), p2 = sourceLineSegment.projectLineSegment(temLineSegment), d1 = p1.direction(), d2 = p2.direction();
|
|
14109
|
+
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) {
|
|
14110
|
+
p1.points = [p1.points[1], p1.points[0]];
|
|
14111
|
+
}
|
|
14112
|
+
if (p1.getLength() > p2.getLength()) {
|
|
13900
14113
|
data = {
|
|
13901
14114
|
target: temLineSegment,
|
|
13902
14115
|
targetIndex: index,
|
|
13903
14116
|
source: sourceLineSegment,
|
|
13904
14117
|
sourceIndex,
|
|
13905
|
-
project:
|
|
14118
|
+
project: p1,
|
|
14119
|
+
project2: p2
|
|
13906
14120
|
};
|
|
13907
14121
|
} else {
|
|
13908
14122
|
data = {
|
|
@@ -13910,10 +14124,11 @@ class LineAnalysis extends Component {
|
|
|
13910
14124
|
targetIndex: sourceIndex,
|
|
13911
14125
|
source: temLineSegment,
|
|
13912
14126
|
sourceIndex: index,
|
|
13913
|
-
project:
|
|
14127
|
+
project: p2,
|
|
14128
|
+
project2: p1
|
|
13914
14129
|
};
|
|
13915
14130
|
}
|
|
13916
|
-
if (!data || data.project.getLength() <
|
|
14131
|
+
if (!data || data.project.getLength() < 0.01) return;
|
|
13917
14132
|
return data;
|
|
13918
14133
|
}
|
|
13919
14134
|
}
|