Files
SlabUploader/frontend/src/capture/tapeCalibration.test.ts
T

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);
});