feature:添加泄漏区功能部分

This commit is contained in:
黎智洲
2021-05-17 14:02:19 +08:00
parent 7e6789c8de
commit 4c1510da1f
30 changed files with 1381 additions and 584 deletions
+140
View File
@@ -0,0 +1,140 @@
import { Vector } from "./vector";
// 包围盒类型
export type BoundingRect = {
x: number;
y: number;
width: number;
height: number;
};
// 包围盒操作
export const Bound = {
/**
* 从点集生成包围盒
* @param points
*/
fromPoints(points: Array<[number, number]>): BoundingRect {
let maxX = -Infinity,
minX = Infinity,
maxY = -Infinity,
minY = Infinity;
points.map(item => {
if(item[0] > maxX) maxX = item[0];
if(item[0] < minX) minX = item[0];
if(item[1] > maxY) maxY = item[1];
if(item[1] < minY) minY = item[1];
});
return {
x: minX,
y: minY,
width: maxX - minX,
height: maxY - minY
};
},
/**
* 由包围盒转化为四个顶点(顺时针)
* @param bound
*/
toPoints(bound: BoundingRect): Array<[number, number]> {
return [
[bound.x, bound.y],
[bound.x + bound.width, bound.y],
[bound.x + bound.width, bound.y + bound.height],
[bound.x, bound.y + bound.height]
];
},
/**
* 求包围盒并集
* @param arg
*/
union(...arg: BoundingRect[]): BoundingRect {
return arg.length > 1?
arg.reduce((total, cur) => {
let minX = total.x < cur.x? total.x: cur.x,
maxX = total.x + total.width < cur.x + cur.width? cur.x + cur.width: total.x + total.width,
minY = total.y < cur.y? total.y: cur.y,
maxY = total.y + total.height < cur.y + cur.height? cur.y + cur.height: total.y + total.height;
return {
x: minX,
y: minY,
width: maxX - minX,
height: maxY - minY
};
}): arg[0];
},
/**
* 包围盒求交集
* @param b1
* @param b2
*/
intersect(b1: BoundingRect, b2: BoundingRect): BoundingRect {
let x, y,
maxX, maxY,
overlapsX,
overlapsY;
if(b1.x < b2.x + b2.width && b1.x + b1.width > b2.x) {
x = b1.x < b2.x? b2.x: b1.x;
maxX = b1.x + b1.width < b2.x + b2.width? b1.x + b1.width: b2.x + b2.width;
overlapsX = maxX - x;
}
if(b1.y < b2.y + b2.height && b1.y + b1.height > b2.y) {
y = b1.y < b2.y? b2.y: b1.y;
maxY = b1.y + b1.height < b2.y + b2.height? b1.y + b1.height: b2.y + b2.height;
overlapsY = maxY - y;
}
if(!overlapsX || !overlapsY) return null;
return {
x,
y,
width: overlapsX,
height: overlapsY
};
},
/**
* 求包围盒旋转后新形成的包围盒
* @param bound
* @param rot
*/
rotation(bound: BoundingRect, rot: number): BoundingRect {
let cx = bound.x + bound.width / 2,
cy = bound.y + bound.height / 2;
return Bound.fromPoints(Bound.toPoints(bound).map(item => Vector.rotation(rot, item, [cx, cy])));
},
/**
* 判断两个包围盒是否相交
* @param b1
* @param b2
*/
isOverlap(b1: BoundingRect, b2: BoundingRect): boolean {
let maxX1 = b1.x + b1.width,
maxY1 = b1.y + b1.height,
maxX2 = b2.x + b2.width,
maxY2 = b2.y + b2.height;
if (b1.x < maxX2 && b2.x < maxX1 && b1.y < maxY2 && b2.y < maxY1) {
return true;
}
return false;
}
};
+101
View File
@@ -0,0 +1,101 @@
import { Util } from "./util";
import { BoundingRect, Bound } from "./boundingRect";
import { Vector } from "./vector";
import { Element } from "../Model/modelData";
/**
* element组
*/
export class Group {
id: string;
private elements: Array<Element | Group> = [];
constructor(...arg: Array<Element | Group>) {
this.id = Util.generateId();
if(arg) {
this.add(...arg);
}
}
/**
* 添加element
* @param arg
*/
add(...arg: Array<Element | Group>) {
arg.map(ele => {
this.elements.push(ele);
});
}
/**
* 移除element
* @param element
*/
remove(element: Element | Group) {
Util.removeFromList(this.elements, item => item.id === element.id);
}
/**
* 获取group的包围盒
*/
getBound(): BoundingRect {
return Bound.union(...this.elements.map(item => item.getBound()));
}
/**
* 位移group
* @param dx
* @param dy
*/
translate(dx: number, dy: number) {
this.elements.map(item => {
if(item instanceof Group) {
item.translate(dx, dy);
}
else {
item.set('x', item.get('x') + dx);
item.set('y', item.get('y') + dy);
}
});
}
/**
* 旋转group
* @param rotation
* @param center
*/
rotate(rotation: number, center?: [number, number]) {
// if(rotation === 0) return;
// let {x, y, width, height} = this.getBound(),
// cx = x + width / 2,
// cy = y + height / 2;
// if(center) {
// cx = center[0];
// cy = center[1];
// }
// this.elements.map(item => {
// if(item instanceof Group) {
// item.rotate(rotation, [cx, cy]);
// }
// else {
// let d = Vector.rotation(rotation, [item.x, item.y], [cx, cy]);
// item.x = d[0];
// item.y = d[1];
// item.set('rotation', rotation);
// }
// });
}
/**
* 清空group
*/
clear() {
this.elements.length = 0;
}
}
+22 -11
View File
@@ -1,4 +1,5 @@
import { ConstructedData } from "../Model/modelConstructor";
import { ConstructList } from "../Model/modelConstructor";
import { G6EdgeModel, G6NodeModel, Link, Model } from "../Model/modelData";
import { SV } from "../StructV";
import { G6Data } from "../View/renderer";
@@ -8,7 +9,6 @@ import { G6Data } from "../View/renderer";
*/
export const Util = {
/**
* 生成唯一id
*/
@@ -78,28 +78,39 @@ export const Util = {
/**
*
* @param constructedDataType
* @param constructListType
* @returns
*/
converterList(constructedDataType: ConstructedData[keyof ConstructedData]) {
return [].concat(...Object.keys(constructedDataType).map(item => constructedDataType[item]));
converterList(modelContainer: { [key: string]: ConstructList[keyof ConstructList]}) {
return [].concat(...Object.keys(modelContainer).map(item => modelContainer[item]));
},
/**
* G6 data 转换器
* @param constructedData
* @param constructList
* @returns
*/
convertG6Data(constructedData: ConstructedData): G6Data {
let nodes = [...Util.converterList(constructedData.element), ...Util.converterList(constructedData.pointer)],
edges = Util.converterList(constructedData.link);
convertG6Data(constructList: ConstructList): G6Data {
let nodes = [...constructList.element, ...constructList.pointer],
edges = constructList.link;
return {
nodes: nodes.map(item => item.cloneProps()),
edges: edges.map(item => item.cloneProps())
nodes: nodes.map(item => item.cloneProps()) as G6NodeModel[],
edges: edges.map(item => item.cloneProps()) as G6EdgeModel[]
};
},
/**
* 将 modelList 转换到 G6Data
* @param modelList
*/
convertModelList2G6Data(modelList: Model[]): G6Data {
return {
nodes: <G6NodeModel[]>(modelList.filter(item => !(item instanceof Link)).map(item => item.cloneProps())),
edges: <G6EdgeModel[]>(modelList.filter(item => item instanceof Link).map(item => item.cloneProps()))
}
},
/**
* 计算旋转矩阵
* @param matrix