41 lines
1.4 KiB
TypeScript
41 lines
1.4 KiB
TypeScript
import { describe, expect, test } from "bun:test";
|
|
import { rotatedRectBounds, rotatedRectCorners } from "./rotated-rect";
|
|
|
|
describe("rotated rectangle geometry", () => {
|
|
test("interprets rotation as radians and keeps the center anchored", () => {
|
|
const corners = rotatedRectCorners({ x: 10, y: 20, w: 40, h: 20 }, Math.PI / 2);
|
|
|
|
expectPoint(corners[0], { x: 40, y: 10 });
|
|
expectPoint(corners[1], { x: 40, y: 50 });
|
|
expectPoint(corners[2], { x: 20, y: 10 });
|
|
expectPoint(corners[3], { x: 20, y: 50 });
|
|
expect((corners[0].x + corners[3].x) / 2).toBeCloseTo(30);
|
|
expect((corners[0].y + corners[3].y) / 2).toBeCloseTo(30);
|
|
});
|
|
|
|
test("expands axis-aligned clipping bounds around a rotated quad", () => {
|
|
const bounds = rotatedRectBounds({ x: 10, y: 20, w: 40, h: 20 }, Math.PI / 2);
|
|
|
|
expect(bounds.x).toBeCloseTo(20);
|
|
expect(bounds.y).toBeCloseTo(10);
|
|
expect(bounds.w).toBeCloseTo(20);
|
|
expect(bounds.h).toBeCloseTo(40);
|
|
});
|
|
|
|
test("preserves an unrotated rectangle exactly", () => {
|
|
const rect = { x: 10, y: 20, w: 40, h: 20 };
|
|
expect(rotatedRectBounds(rect, 0)).toBe(rect);
|
|
expect(rotatedRectCorners(rect, 0)).toEqual([
|
|
{ x: 10, y: 20 },
|
|
{ x: 50, y: 20 },
|
|
{ x: 10, y: 40 },
|
|
{ x: 50, y: 40 },
|
|
]);
|
|
});
|
|
});
|
|
|
|
function expectPoint(actual: { x: number; y: number }, expected: { x: number; y: number }) {
|
|
expect(actual.x).toBeCloseTo(expected.x);
|
|
expect(actual.y).toBeCloseTo(expected.y);
|
|
}
|