41 lines
1.3 KiB
TypeScript
41 lines
1.3 KiB
TypeScript
|
|
export type Point = {
|
|||
|
|
x: number;
|
|||
|
|
y: number;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
export class DiamondCheck {
|
|||
|
|
// 计算两个向量的叉积的绝对值
|
|||
|
|
static crossProduct(a: Point, b: Point, p: Point): number {
|
|||
|
|
return (b.x - a.x) * (p.y - a.y) - (b.y - a.y) * (p.x - a.x);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 判断点p是否在由顶点a, b, c, d定义的多边形内部
|
|||
|
|
static isPointInDiamond(
|
|||
|
|
point: Point,
|
|||
|
|
diamondCoords: [Point,Point,Point,Point]
|
|||
|
|
): boolean {
|
|||
|
|
|
|||
|
|
const [a,b,c,d] = diamondCoords;
|
|||
|
|
|
|||
|
|
// 计算多边形的边
|
|||
|
|
const ab = { x: b.x - a.x, y: b.y - a.y };
|
|||
|
|
const bc = { x: c.x - b.x, y: c.y - b.y };
|
|||
|
|
const cd = { x: d.x - c.x, y: d.y - c.y };
|
|||
|
|
const da = { x: a.x - d.x, y: a.y - d.y };
|
|||
|
|
|
|||
|
|
// 计算点p与多边形每条边的叉积
|
|||
|
|
const abP = DiamondCheck.crossProduct(a, b, point);
|
|||
|
|
const bcP = DiamondCheck.crossProduct(b, c, point);
|
|||
|
|
const cdP = DiamondCheck.crossProduct(c, d, point);
|
|||
|
|
const daP = DiamondCheck.crossProduct(d, a, point);
|
|||
|
|
|
|||
|
|
// 如果所有叉积的符号一致(即绝对值相同),点p在多边形内部
|
|||
|
|
const allSameSign = (a: number, b: number, c: number, d: number): boolean =>
|
|||
|
|
Math.sign(a) === Math.sign(b) &&
|
|||
|
|
Math.sign(b) === Math.sign(c) &&
|
|||
|
|
Math.sign(c) === Math.sign(d);
|
|||
|
|
|
|||
|
|
return allSameSign(abP, bcP, cdP, daP);
|
|||
|
|
}
|
|||
|
|
}
|