|
@@ -4,6 +4,8 @@ import { SPoint, SRect } from "@persagy-web/draw/lib";
|
|
import { FloorScene } from "./FloorScene";
|
|
import { FloorScene } from "./FloorScene";
|
|
import { HighlightItem } from "./HighlightItem";
|
|
import { HighlightItem } from "./HighlightItem";
|
|
import { ShadeItem } from "./ShadeItem";
|
|
import { ShadeItem } from "./ShadeItem";
|
|
|
|
+// @ts-ignore
|
|
|
|
+import { intersect, polygon, segments, combine, selectIntersect, selectUnion, selectDifference, selectDifferenceRev, difference } from "polybooljs";
|
|
|
|
|
|
export class DivideFloorScene extends FloorScene {
|
|
export class DivideFloorScene extends FloorScene {
|
|
/** 划分item */
|
|
/** 划分item */
|
|
@@ -12,7 +14,7 @@ export class DivideFloorScene extends FloorScene {
|
|
isCutting: boolean = false;
|
|
isCutting: boolean = false;
|
|
|
|
|
|
/** 是否开启吸附 */
|
|
/** 是否开启吸附 */
|
|
- private _isAbsorbing: boolean = true;
|
|
|
|
|
|
+ private _isAbsorbing: boolean = false;
|
|
get isAbsorbing(): boolean {
|
|
get isAbsorbing(): boolean {
|
|
return this._isAbsorbing;
|
|
return this._isAbsorbing;
|
|
} // Get isAbsorbing
|
|
} // Get isAbsorbing
|
|
@@ -190,12 +192,12 @@ export class DivideFloorScene extends FloorScene {
|
|
} // Function isPointInAbsorbArea()
|
|
} // Function isPointInAbsorbArea()
|
|
|
|
|
|
/**
|
|
/**
|
|
- * 吸附空间线
|
|
|
|
- *
|
|
|
|
- * @param event 鼠标事件对象
|
|
|
|
- * @param absorbLen 吸附距离
|
|
|
|
- * @return PointToLine 吸附的线
|
|
|
|
- */
|
|
|
|
|
|
+ * 吸附空间线
|
|
|
|
+ *
|
|
|
|
+ * @param event 鼠标事件对象
|
|
|
|
+ * @param absorbLen 吸附距离
|
|
|
|
+ * @return PointToLine 吸附的线
|
|
|
|
+ */
|
|
absorbSpaceLine(event: SMouseEvent, absorbLen: number): any {
|
|
absorbSpaceLine(event: SMouseEvent, absorbLen: number): any {
|
|
let minPointDis = Number.MAX_SAFE_INTEGER;
|
|
let minPointDis = Number.MAX_SAFE_INTEGER;
|
|
let Point, Line;
|
|
let Point, Line;
|
|
@@ -232,4 +234,204 @@ export class DivideFloorScene extends FloorScene {
|
|
Line: Line
|
|
Line: Line
|
|
};
|
|
};
|
|
} // Function absorbSpaceLine()
|
|
} // Function absorbSpaceLine()
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 计算选中的空间与业务空间的差集
|
|
|
|
+ */
|
|
|
|
+ getSpaceZoneIntersect(): SPoint[][] | undefined {
|
|
|
|
+ // 未选中空间- 不计算
|
|
|
|
+ if (!this.selectContainer.itemList.length) {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ // 没有业务空间不计算
|
|
|
|
+ if (!this.zoneList.length) {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ // 生成选中的空间计算时用的格式
|
|
|
|
+ const space = {
|
|
|
|
+ regions: [],
|
|
|
|
+ inverted: false
|
|
|
|
+ }
|
|
|
|
+ const sourceIdToDiff = {};
|
|
|
|
+ try {
|
|
|
|
+ let poly1, poly2;
|
|
|
|
+ const start = +new Date();
|
|
|
|
+ let rect1: SRect, list = [];
|
|
|
|
+ // 计算外接矩阵与选中空间相交的业务空间的所有轮廓
|
|
|
|
+ this.selectContainer.itemList.forEach(item => {
|
|
|
|
+ rect1 = item.boundingRect();
|
|
|
|
+ this.zoneList.forEach(t => {
|
|
|
|
+ if (t.visible) {
|
|
|
|
+ let rect2 = t.boundingRect();
|
|
|
|
+ // 外接矩阵是否相交,缩小计算范围
|
|
|
|
+ if (SMathUtil.rectIntersection(rect1, rect2)) {
|
|
|
|
+ t.pointList.forEach((zoneLine): void => {
|
|
|
|
+ let polygons = {
|
|
|
|
+ regions: [],
|
|
|
|
+ inverted: false
|
|
|
|
+ };
|
|
|
|
+ zoneLine.forEach((po): void => {
|
|
|
|
+ let point = SMathUtil.transferToArray(po);
|
|
|
|
+ polygons.regions.push(point);
|
|
|
|
+ });
|
|
|
|
+ list.push(polygons);
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ })
|
|
|
|
+ //
|
|
|
|
+ if (list.length) {
|
|
|
|
+ let seg1 = segments(list[0]),
|
|
|
|
+ seg2,
|
|
|
|
+ comb;
|
|
|
|
+ for (let i = 1; i < list.length; i++) {
|
|
|
|
+ seg2 = segments(list[i]);
|
|
|
|
+ comb = combine(seg1, seg2);
|
|
|
|
+ seg1 = selectUnion(comb);
|
|
|
|
+ }
|
|
|
|
+ poly1 = seg1;
|
|
|
|
+ this.selectContainer.itemList.forEach(t => {
|
|
|
|
+ let key = t.data.SourceId;
|
|
|
|
+ poly2 = {
|
|
|
|
+ regions: [],
|
|
|
|
+ inverted: false
|
|
|
|
+ }
|
|
|
|
+ poly2.regions = t.pointList[0].map((item): number[][] => {
|
|
|
|
+ return SMathUtil.transferToArray(item);
|
|
|
|
+ });
|
|
|
|
+ const comb = combine(segments(poly2), poly1)
|
|
|
|
+ const diffObj = selectDifference(comb);
|
|
|
|
+ const diffPoly = polygon(diffObj)
|
|
|
|
+ // 理论上只要选择了空间 length就不会为0
|
|
|
|
+ if (diffPoly.regions.length) {
|
|
|
|
+ let outlineList = SMathUtil.getIntersectInArray(
|
|
|
|
+ diffPoly.regions
|
|
|
|
+ );
|
|
|
|
+ console.log(outlineList);
|
|
|
|
+ // @ts-ignore
|
|
|
|
+ sourceIdToDiff[key] = outlineList.map(t => {
|
|
|
|
+ let arr = [t.Outer];
|
|
|
|
+ t.Inner.forEach((inner): void => {
|
|
|
|
+ arr.push(inner);
|
|
|
|
+ });
|
|
|
|
+ return arr;
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ const end = +new Date()
|
|
|
|
+ console.log(sourceIdToDiff);
|
|
|
|
+ console.log(end - start, 'comb-diff');
|
|
|
|
+ return sourceIdToDiff
|
|
|
|
+ }
|
|
|
|
+ } catch (err) {
|
|
|
|
+ console.log(err);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 计算选中的空间与绘制的区域交集
|
|
|
|
+ */
|
|
|
|
+ getSpaceCutIntersect(seg?: any): SPoint[][] | undefined {
|
|
|
|
+ // 未选中空间- 不计算
|
|
|
|
+ if (!this.selectContainer.itemList.length) {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ // 没有绘制不计算
|
|
|
|
+ if (!this.cutItem) {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ const sourceIdToIntersect = {};
|
|
|
|
+ try {
|
|
|
|
+ const start = +new Date();
|
|
|
|
+ let cutPoly;
|
|
|
|
+ if (seg) {
|
|
|
|
+ cutPoly = seg
|
|
|
|
+ } else {
|
|
|
|
+ const poly = {
|
|
|
|
+ regions: [SMathUtil.transferToArray(this.cutItem.pointList)],
|
|
|
|
+ inverted: false
|
|
|
|
+ }
|
|
|
|
+ cutPoly = segments(poly)
|
|
|
|
+ }
|
|
|
|
+ this.selectContainer.itemList.forEach(item => {
|
|
|
|
+ const arr = item.pointList[0].map(t => {
|
|
|
|
+ return SMathUtil.transferToArray(t);
|
|
|
|
+ })
|
|
|
|
+ const poly2 = {
|
|
|
|
+ regions: arr,
|
|
|
|
+ inverted: false
|
|
|
|
+ }
|
|
|
|
+ const seg = segments(poly2)
|
|
|
|
+ const comb = combine(cutPoly, seg)
|
|
|
|
+ if (item.data.SourceId) {
|
|
|
|
+ const spoly = polygon(selectIntersect(comb));
|
|
|
|
+ // 绘制切割区域可能与空间没有交集
|
|
|
|
+ if (spoly.regions.length) {
|
|
|
|
+ let outlineList = SMathUtil.getIntersectInArray(
|
|
|
|
+ spoly.regions
|
|
|
|
+ );
|
|
|
|
+ console.log(outlineList);
|
|
|
|
+ // @ts-ignore
|
|
|
|
+ sourceIdToIntersect[item.data.SourceId] = outlineList.map(t => {
|
|
|
|
+ let arr = [t.Outer];
|
|
|
|
+ t.Inner.forEach((inner): void => {
|
|
|
|
+ arr.push(inner);
|
|
|
|
+ });
|
|
|
|
+ return arr;
|
|
|
|
+ });
|
|
|
|
+ // 得到的结果
|
|
|
|
+ // sourceIdToIntersect[item.data.SourceId] = polygon(selectIntersect(comb))
|
|
|
|
+ } else {
|
|
|
|
+ // 没有交集
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ const end = +new Date()
|
|
|
|
+ console.log(end - start, 'comb-intersect', sourceIdToIntersect);
|
|
|
|
+ return sourceIdToIntersect
|
|
|
|
+ } catch (err) {
|
|
|
|
+ console.log(err);
|
|
|
|
+ }
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 如果场景中既有绘制的区域也有创建好的业务空间,则在区域中将已创建的业务空间减去
|
|
|
|
+ */
|
|
|
|
+ getCurInZone() {
|
|
|
|
+ if (!this.cutItem) {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ // 绘制区域外接矩阵
|
|
|
|
+ const rect2 = this.cutItem.boundingRect()
|
|
|
|
+ // 绘制区域的多边形 - 也是每次减去业务空间后剩下的多边形
|
|
|
|
+ let poly = segments({
|
|
|
|
+ regions: [SMathUtil.transferToArray(this.cutItem.pointList)],
|
|
|
|
+ inverted: false
|
|
|
|
+ })
|
|
|
|
+ this.zoneList.forEach(item => {
|
|
|
|
+ if (item.visible) {
|
|
|
|
+ const rect1 = item.boundingRect();
|
|
|
|
+ if (SMathUtil.rectIntersection(rect1, rect2)) {
|
|
|
|
+ item.pointList.forEach((zoneLine): void => {
|
|
|
|
+ let polygons = {
|
|
|
|
+ regions: [],
|
|
|
|
+ inverted: false
|
|
|
|
+ }
|
|
|
|
+ zoneLine.forEach((po): void => {
|
|
|
|
+ let point = SMathUtil.transferToArray(po);
|
|
|
|
+ polygons.regions.push(point);
|
|
|
|
+ });
|
|
|
|
+ const segZone = segments(polygons);
|
|
|
|
+ const comb = combine(poly, segZone);
|
|
|
|
+ poly = selectDifference(comb)
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ console.log(poly);
|
|
|
|
+ // poly为segments类型
|
|
|
|
+ return poly;
|
|
|
|
+ }
|
|
}
|
|
}
|