fix(abut): 수축줄눈을 받침 사이 중간에 · 기본 개수 ceil(L/10) − 1 · 3D 선 표시

spec_abut §3 · §4.9 (QA-7 가정)와 맞지 않던 세 가지를 고친다.
- 위치: 등분점(1개면 L/2)이 아니라 가장 가까운 '받침 사이 중간'(= 교좌면 계단 경계). 이전에는 운곡교 교대
  5기 모두 줄눈이 가운데 받침 ③ 블럭을 지났다 (A1: 줄눈 6.099 · 받침 6.037). 이제 A1은 IP3에서 4.905 m
- 개수: 입력이 없으면 ceil(L/10) − 1 (길이에 따라 자동, 이전에는 1 고정). 입력 칸은 비우면 자동
- 3D: 벽체 전면 · 흉벽 전면 · 벽체 배면 · 흉벽 배면에 선으로 표시(저판은 연속이라 없음), '벽체·흉벽' 토글을 따름
- 공통 계산 core/abut/joints.ts를 ② 정면·배면 삽도, 교대 상세 요약, 입력 칸 안내, 3D가 함께 씀
- 테스트: 개수 규칙, A1 위치 = ②·③ 중간 = 계단 경계, 여러 개 · 받침 부족 시 등분, 3D 선 4면

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ypshimandClaude Opus 5.5 committed 2026-11-06 16:23:04 +09:00
1 parent 1fda705b75
commit bff1502ecf
8 files changed
+158 -13

No files matched your search

+3 -2
View File
@@ -1,3 +1,4 @@
import { jointPositions } from '../src/core/abut/joints';
import { readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import * as XLSX from 'xlsx';
@@ -26,7 +27,7 @@ const d: AbutWallDrawing = {
footingFrontM: m.shape.footingFrontM,
footingBackM: m.shape.footingBackM,
bracketHeightM: m.shape.bracketHeightM,
shrinkJointCount: 1,
shrinkJointsS: jointPositions(model.length, model.bearings.map((b) => b.s)),
bracketWidthMm: 300,
parapetThicknessMm: 500,
seatWidthMm: 1600,
@@ -50,7 +51,7 @@ describe('교대 벽체·흉벽 삽도 (시안 ② 벽체·흉벽 카드)', () =
});
it('the 수축줄눈 count follows the input', () => {
const svg = abutWallElevationSvg({ ...d, shrinkJointCount: 2 });
const svg = abutWallElevationSvg({ ...d, shrinkJointsS: jointPositions(model.length, model.bearings.map((b) => b.s), 2) });
expect(svg).toContain('수축줄눈 2');
expect(svg.match(/stroke-dasharray="5 3"/g)).toHaveLength(2);
});