36 lines
1.8 KiB
TypeScript
36 lines
1.8 KiB
TypeScript
import { test } from 'node:test';
|
||
import assert from 'node:assert/strict';
|
||
import { minAreaRect, orientedRect, rectAlongLine } from './rect.ts';
|
||
|
||
// 100×20 horizontal slab
|
||
const W = 100, H = 20;
|
||
const bitset = new Uint8Array(W * H);
|
||
for (let x = 0; x < W; x++) for (let y = 0; y < H; y++) bitset[y * W + x] = 1;
|
||
|
||
test('orientedRect changes angleDeg and preserves longSidePx', () => {
|
||
const prev = minAreaRect(bitset, W, H);
|
||
assert.ok(prev, 'minAreaRect returned a box');
|
||
const rotated = orientedRect(prev, 45);
|
||
assert.ok(Math.abs(rotated.angleDeg - 45) < 1e-9);
|
||
assert.equal(rotated.longSidePx, prev.longSidePx);
|
||
// The long side (angleDeg 0 → +x) must be preserved by the rotation.
|
||
const longOf = (c) => Math.hypot(c[3][0] - c[0][0], c[3][1] - c[0][1]);
|
||
assert.ok(Math.abs(longOf(rotated.corners) - longOf(prev.corners)) < 1e-9);
|
||
assert.ok(Math.abs(longOf(prev.corners) - prev.longSidePx) < 1e-9);
|
||
// angle normalization to [0, 180)
|
||
assert.ok(orientedRect(prev, 190).angleDeg >= 0 && orientedRect(prev, 190).angleDeg < 180);
|
||
});
|
||
|
||
test('rectAlongLine sets the approved axis from the owner-positioned tape endpoints', () => {
|
||
const previous = minAreaRect(bitset, W, H)!;
|
||
const start: [number, number] = [20, 30];
|
||
const end: [number, number] = [80, 70];
|
||
const calibrated = rectAlongLine(previous, start, end);
|
||
const center: [number, number] = [50, 50];
|
||
assert.ok(Math.abs(calibrated.angleDeg - (Math.atan2(40, 60) * 180) / Math.PI) < 1e-9);
|
||
assert.ok(Math.abs(calibrated.longSidePx - Math.hypot(60, 40)) < 1e-9);
|
||
assert.ok(Math.abs(calibrated.corners.reduce((sum, point) => sum + point[0], 0) / 4 - center[0]) < 1e-9);
|
||
assert.ok(Math.abs(calibrated.corners.reduce((sum, point) => sum + point[1], 0) / 4 - center[1]) < 1e-9);
|
||
assert.notEqual(calibrated.angleDeg, previous.angleDeg, 'direction comes from tape endpoints, not mask rectangle');
|
||
});
|