-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathintersection.ts
More file actions
50 lines (42 loc) · 1.33 KB
/
intersection.ts
File metadata and controls
50 lines (42 loc) · 1.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import type { CommittedBox } from '../types/box.ts';
import { getRectanglePoints } from './box.ts';
import type { Point } from './point.ts';
import { dotProduct, subtract } from './point.ts';
// Check if 2 rectangles intersect based on the separating Axis Theorem (SAT)
export function rectanglesIntersect(
rect1: CommittedBox,
rect2: CommittedBox,
): boolean {
const corners1 = getRectanglePoints(rect1);
const corners2 = getRectanglePoints(rect2);
const axes = [...getAxes(corners1), ...getAxes(corners2)];
for (const axis of axes) {
const proj1 = projectOntoAxis(corners1, axis);
const proj2 = projectOntoAxis(corners2, axis);
if (proj1.max < proj2.min || proj2.max < proj1.min) {
return false; // Gap found, no intersection
}
}
return true;
}
function getAxes(corners: Point[]): Point[] {
const axes: Point[] = [];
for (let i = 0; i < corners.length; i++) {
const p1 = corners[i];
const p2 = corners[(i + 1) % corners.length];
const edge = subtract(p2, p1);
// Perpendicular axis
axes.push({ x: -edge.y, y: edge.x });
}
return axes;
}
function projectOntoAxis(
corners: Point[],
axis: Point,
): { min: number; max: number } {
const projections = corners.map((c) => dotProduct(c, axis));
return {
min: Math.min(...projections),
max: Math.max(...projections),
};
}