58 lines
2.5 KiB
TypeScript
58 lines
2.5 KiB
TypeScript
import { test } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import {
|
|
CALIBRATION_FRAME,
|
|
applyApprovedMask,
|
|
cropTickPositions,
|
|
pinchPhotoTransform,
|
|
photoToStage,
|
|
stageToPhoto,
|
|
tapeLineFromStageTicks,
|
|
} from './tapeCalibration.ts';
|
|
|
|
test('the reference line is fixed at the center of the calibration frame', () => {
|
|
assert.equal(CALIBRATION_FRAME.width, 480);
|
|
assert.equal(CALIBRATION_FRAME.height, 640);
|
|
assert.equal(CALIBRATION_FRAME.width / 2, 240);
|
|
const [top, bottom] = cropTickPositions(90);
|
|
assert.ok(Math.abs(top - 32) < 1e-9);
|
|
assert.ok(Math.abs(bottom - 608) < 1e-9);
|
|
const transform = { tiltDeg: 21, zoom: 1.4, panX: -18, panY: 11 };
|
|
const tape = tapeLineFromStageTicks(100, 530, 2400, 1800, transform);
|
|
const start = photoToStage(tape.start, 2400, 1800, transform);
|
|
const end = photoToStage(tape.end, 2400, 1800, transform);
|
|
assert.ok(Math.abs(start[0] - 240) < 1e-8 && Math.abs(start[1] - 100) < 1e-8);
|
|
assert.ok(Math.abs(end[0] - 240) < 1e-8 && Math.abs(end[1] - 530) < 1e-8);
|
|
});
|
|
|
|
test('pan, zoom, and tilt change the photo under the fixed reference line without losing source coordinates', () => {
|
|
const transform = { tiltDeg: 31, zoom: 1.7, panX: 15, panY: -24 };
|
|
const sourcePoint: [number, number] = [317, 218];
|
|
const stagePoint = photoToStage(sourcePoint, 1200, 900, transform);
|
|
const restored = stageToPhoto(stagePoint, 1200, 900, transform);
|
|
assert.ok(Math.abs(restored[0] - sourcePoint[0]) < 1e-8);
|
|
assert.ok(Math.abs(restored[1] - sourcePoint[1]) < 1e-8);
|
|
});
|
|
|
|
test('approved-mask rendering removes background pixels but preserves slab pixels', () => {
|
|
const rgba = new Uint8ClampedArray([
|
|
180, 90, 30, 255,
|
|
20, 200, 40, 255,
|
|
]);
|
|
const masked = applyApprovedMask(rgba, Uint8Array.of(1, 0));
|
|
assert.deepEqual([...masked.slice(0, 4)], [180, 90, 30, 255]);
|
|
assert.deepEqual([...masked.slice(4, 8)], [20, 200, 40, 0]);
|
|
});
|
|
|
|
test('pinch zoom keeps the photo point under the moving pinch midpoint', () => {
|
|
const transform = { tiltDeg: 17, zoom: 1.2, panX: 11, panY: -8 };
|
|
const anchor: [number, number] = [420, 530];
|
|
const before = photoToStage(anchor, 1200, 900, transform);
|
|
const midpoint: [number, number] = [before[0] + 18, before[1] - 12];
|
|
const next = pinchPhotoTransform(transform, anchor, midpoint, 1.5, 1200, 900);
|
|
const after = photoToStage(anchor, 1200, 900, next);
|
|
assert.ok(Math.abs(after[0] - midpoint[0]) < 1e-8);
|
|
assert.ok(Math.abs(after[1] - midpoint[1]) < 1e-8);
|
|
assert.ok(Math.abs(next.zoom - 1.8) < 1e-12);
|
|
});
|