StructV2/src/View/boundingRect.ts
Phenom 72fcf5394a 基本重构完成
底层渲染库舍弃 zrender,换为 antvG6
2021-04-06 21:45:11 +08:00

141 lines
3.6 KiB
TypeScript

import { Vector } from "../Common/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;
}
};