fix(capture): align masked tape calibration with #99
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
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);
|
||||
});
|
||||
Reference in New Issue
Block a user