65 lines
1.0 KiB
TypeScript
65 lines
1.0 KiB
TypeScript
const LINE_PARALLEL_EPSILON = 1e-10;
|
|
|
|
export function lineEdgeIntersection({
|
|
lineX,
|
|
lineY,
|
|
normalX,
|
|
normalY,
|
|
x1,
|
|
y1,
|
|
x2,
|
|
y2,
|
|
}: {
|
|
lineX: number;
|
|
lineY: number;
|
|
normalX: number;
|
|
normalY: number;
|
|
x1: number;
|
|
y1: number;
|
|
x2: number;
|
|
y2: number;
|
|
}): { x: number; y: number } | null {
|
|
const distance1 = halfPlaneSign({
|
|
lineX,
|
|
lineY,
|
|
normalX,
|
|
normalY,
|
|
x: x1,
|
|
y: y1,
|
|
});
|
|
const distance2 = halfPlaneSign({
|
|
lineX,
|
|
lineY,
|
|
normalX,
|
|
normalY,
|
|
x: x2,
|
|
y: y2,
|
|
});
|
|
const denom = distance1 - distance2;
|
|
if (Math.abs(denom) < LINE_PARALLEL_EPSILON) return null;
|
|
const t = distance1 / denom;
|
|
if (t < 0 || t > 1) return null;
|
|
return {
|
|
x: x1 + (x2 - x1) * t,
|
|
y: y1 + (y2 - y1) * t,
|
|
};
|
|
}
|
|
|
|
export function halfPlaneSign({
|
|
lineX,
|
|
lineY,
|
|
normalX,
|
|
normalY,
|
|
x,
|
|
y,
|
|
}: {
|
|
lineX: number;
|
|
lineY: number;
|
|
normalX: number;
|
|
normalY: number;
|
|
x: number;
|
|
y: number;
|
|
}): number {
|
|
return (x - lineX) * normalX + (y - lineY) * normalY;
|
|
}
|