45 lines
1.7 KiB
TypeScript
45 lines
1.7 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
||
import { buildPier, blockFramePoint } from '../src/core/geometry';
|
||
import { loadP1 } from './helpers';
|
||
|
||
const model = buildPier(loadP1());
|
||
const front = model.blocks.filter((b) => b.row === '전열');
|
||
const back = model.blocks.filter((b) => b.row === '후열');
|
||
|
||
describe('받침블럭 방위 (삽도 · 승인 2026-10-23)', () => {
|
||
it('uses the bearing angles after the same X/Y reflection as positions: front ≈ +4.42°, back ≈ +3.11°', () => {
|
||
for (const b of front) expect(Math.abs(b.rowSkewDeg - 4.42)).toBeLessThan(0.02);
|
||
for (const b of back) expect(Math.abs(b.rowSkewDeg - 3.11)).toBeLessThan(0.02);
|
||
});
|
||
|
||
it('a block side follows the bearing row: the n side of a block runs along (−sinδ, cosδ)', () => {
|
||
const b = front[0];
|
||
const [s1, n1] = blockFramePoint(b, 0, -0.6);
|
||
const [s2, n2] = blockFramePoint(b, 0, 0.6);
|
||
const ds = s2 - s1;
|
||
const dn = n2 - n1;
|
||
const len = Math.hypot(ds, dn);
|
||
const d = (b.rowSkewDeg * Math.PI) / 180;
|
||
expect(ds / len).toBeCloseTo(-Math.sin(d), 9);
|
||
expect(dn / len).toBeCloseTo(Math.cos(d), 9);
|
||
});
|
||
|
||
it('turning keeps the block centre and the bearing spacing (the row is unchanged)', () => {
|
||
const b = front[0];
|
||
const [s0, n0] = blockFramePoint(b, 0, 0);
|
||
expect(s0).toBeCloseTo(b.s, 12);
|
||
expect(n0).toBeCloseTo(b.n, 12);
|
||
});
|
||
|
||
it('the turned block corners stay inside the coping ends', () => {
|
||
const L = model.copingL;
|
||
for (const b of model.blocks) {
|
||
for (const [a, c] of [[-0.6, -0.6], [-0.6, 0.6], [0.6, -0.6], [0.6, 0.6]] as const) {
|
||
const [s] = blockFramePoint(b, a, c);
|
||
expect(s, `block ${b.no}`).toBeGreaterThan(0);
|
||
expect(s, `block ${b.no}`).toBeLessThan(L);
|
||
}
|
||
}
|
||
});
|
||
});
|