GCodeOverlay/src/geometry/transform.test.ts

37 lines
1.5 KiB
TypeScript
Raw Normal View History

import { describe, it, expect } from 'vitest';
import { applyAlignment, projectSegments, imageToMachine, alignmentFromOrigin } from './transform';
import type { Vec2, Mat3, Segment, Alignment } from '../types';
const close = (a: Vec2, b: Vec2, eps = 1e-9) =>
Math.abs(a[0] - b[0]) < eps && Math.abs(a[1] - b[1]) < eps;
const IDENT: Mat3 = [1, 0, 0, 0, 1, 0, 0, 0, 1];
describe('transform', () => {
it('applyAlignment rotates then translates', () => {
const a: Alignment = { tx: 5, ty: 1, rot: Math.PI / 2 };
// (1,0) rotated 90° → (0,1), then +(5,1) → (5,2)
expect(close(applyAlignment(a, [1, 0]), [5, 2])).toBe(true);
});
it('projectSegments applies alignment then homography to every point', () => {
const segs: Segment[] = [{ kind: 'cut', points: [[0, 0], [10, 0]] }];
const a: Alignment = { tx: 2, ty: 3, rot: 0 };
const out = projectSegments(segs, a, IDENT);
expect(out[0]!.kind).toBe('cut');
expect(close(out[0]!.points[0]!, [2, 3])).toBe(true);
expect(close(out[0]!.points[1]!, [12, 3])).toBe(true);
});
it('imageToMachine is the inverse of the homography', () => {
const H: Mat3 = [2, 0, 10, 0, 2, 20, 0, 0, 1];
// machine (5,5) → image (20,30); invert should return (5,5)
expect(close(imageToMachine(H, [20, 30]), [5, 5])).toBe(true);
});
it('alignmentFromOrigin places work-origin at the given machine point', () => {
const a = alignmentFromOrigin([7, 9], 0);
expect(close(applyAlignment(a, [0, 0]), [7, 9])).toBe(true);
});
});