The split between C12 and C13 follows the end underside, not a fixed level: C12 rows lie between the Level underside and the end underside (taper height h2), C13 rows between the end underside and the top (end height h1). The break is the end underside + 127 mm, the taper line's start at the end face. P1 is unchanged (C12 41.288–42.288, C13 42.538–42.788). Tests check the band rule for h1 and h2 changes. Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
88 lines
4.1 KiB
TypeScript
88 lines
4.1 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { buildPier } from '../src/core/geometry';
|
|
import { P1_COPING_GEOM, SIDE_COVER_M, sideRowLevels } from '../src/core/coping-geom';
|
|
import { sideRows } from '../src/core/rebar/coping';
|
|
import { shearUHeight, shearULength } from '../src/core/rebar/coping';
|
|
import { rebarSummary } from '../src/core/rebar/summary';
|
|
import { buildRebar3D } from '../src/view/rebar3d';
|
|
import { loadP1 } from './helpers';
|
|
|
|
const L = 12000;
|
|
|
|
describe('① 코핑 끝단 높이 h1 · 테이퍼 높이 h2 · Level 폭 (1단계, 승인 2026-10-23)', () => {
|
|
it('the P1 geometry reproduces the document U heights (890.9, 2178.8, Level 2300)', () => {
|
|
expect(shearUHeight(300, L)).toBeCloseTo(890.9, 1);
|
|
expect(shearUHeight(4550, L)).toBeCloseTo(2178.8, 1);
|
|
expect(shearUHeight(6000, L)).toBeCloseTo(2300, 6);
|
|
});
|
|
|
|
it('the model defaults to the P1 coping geometry and the P1 shear lengths', () => {
|
|
const model = buildPier(loadP1());
|
|
expect(model.copingGeom).toEqual(P1_COPING_GEOM);
|
|
expect(model.endBottom).toBeCloseTo(43.411 - 1.0, 6);
|
|
expect(model.levelBottom).toBeCloseTo(43.411 - 1.0 - 1.5, 6);
|
|
});
|
|
|
|
it('a higher end height h1 lowers the coping ends and adds the same height to every U', () => {
|
|
const base = buildPier(loadP1());
|
|
const high = buildPier({ ...loadP1(), copingH1Mm: 1200 });
|
|
expect(high.endBottom).toBeCloseTo(base.endBottom - 0.2, 6);
|
|
expect(high.levelBottom).toBeCloseTo(base.levelBottom - 0.2, 6);
|
|
const geomH1 = { ...P1_COPING_GEOM, h1: 1200 };
|
|
expect(shearUHeight(300, L, geomH1)).toBeCloseTo(shearUHeight(300, L) + 200, 6);
|
|
expect(shearULength(300, L, geomH1)).toBeCloseTo(shearULength(300, L) + 400, 6);
|
|
});
|
|
|
|
it('a taper h2 changes the Level underside and the height at the Level', () => {
|
|
const high = buildPier({ ...loadP1(), copingH2Mm: 1800 });
|
|
expect(high.levelBottom).toBeCloseTo(43.411 - 1.0 - 1.8, 6);
|
|
expect(shearUHeight(6000, L, { ...P1_COPING_GEOM, h2: 1800 })).toBeCloseTo(2600, 6);
|
|
});
|
|
|
|
it('a wider Level changes the Level zone in the model and the shear-bar Level half-width', () => {
|
|
const wide = buildPier({ ...loadP1(), levelWidthMm: 2500 });
|
|
expect(wide.copingGeom.levelWidth).toBe(2500);
|
|
expect(wide.levelBottom).toBeCloseTo(buildPier(loadP1()).levelBottom, 6);
|
|
});
|
|
|
|
it('side-row levels keep their P1 values from the Level underside (assumption, 명세 확인 필요)', () => {
|
|
const levels = sideRowLevels(40.911, 42.411);
|
|
expect(levels.zBottom).toBeCloseTo(41.288, 6);
|
|
expect(levels.zBreak).toBeCloseTo(42.538, 6);
|
|
});
|
|
|
|
it('the coping rebar follows a changed geometry: the rows and the 3D build without error, the positions are unchanged', () => {
|
|
const base = rebarSummary(buildPier(loadP1())).rows;
|
|
const changed = buildPier({ ...loadP1(), copingH1Mm: 1200, copingH2Mm: 1600, levelWidthMm: 2300 });
|
|
const rows = rebarSummary(changed).rows;
|
|
expect(rows.find((r) => r.name === 'C10')!.count).toBe(base.find((r) => r.name === 'C10')!.count);
|
|
expect(rows.find((r) => r.name === 'C9')!.count).toBe(base.find((r) => r.name === 'C9')!.count);
|
|
expect(buildRebar3D(changed).byName.get('C10')!.length).toBeGreaterThan(0);
|
|
});
|
|
});
|
|
|
|
describe('C12 in the taper band (h2), C13 in the end band (h1)', () => {
|
|
const bands = (input: Parameters<typeof buildPier>[0]) => {
|
|
const m = buildPier(input);
|
|
const lv = sideRowLevels(m.levelBottom, m.endBottom);
|
|
const rows = sideRows(lv.zBottom, lv.zBreak);
|
|
return { m, rows };
|
|
};
|
|
it.each([
|
|
['P1', {}],
|
|
['h1 800', { copingH1Mm: 800 }],
|
|
['h1 1200', { copingH1Mm: 1200 }],
|
|
['h2 1800', { copingH2Mm: 1800 }],
|
|
])('%s: every C12 row is in the taper band and every C13 row in the end band', (_name, change) => {
|
|
const { m, rows } = bands({ ...loadP1(), ...change });
|
|
for (const z of rows.c12) {
|
|
expect(z).toBeGreaterThanOrEqual(m.levelBottom - 1e-9);
|
|
expect(z).toBeLessThan(m.endBottom + SIDE_COVER_M);
|
|
}
|
|
for (const z of rows.c13) {
|
|
expect(z).toBeGreaterThanOrEqual(m.endBottom + SIDE_COVER_M - 1e-9);
|
|
expect(z).toBeLessThanOrEqual(m.copingRefTop);
|
|
}
|
|
});
|
|
});
|