fix(shape): 후열 계단 경계를 후열 받침 사이 중앙에 둔다

전·후열 받침 수가 같으면 후열 계단 경계를 전열 경계로 썼기 때문에, 후열 받침이 전열과 마주 보지 않는 교각
(산외교 P11 ⑥|⑦: 경계 12.75, 받침 11.64 · 18.49)에서 경계가 중앙에서 벗어났다. 후열도 자기 받침 사이 중앙을 쓰되,
전열 경계와 블럭 반폭(0.6 m) 이내로 가까우면 전열 경계에 맞춘다 (P1처럼 약간 엇갈린 열에 얇은 단이 생기지 않게).

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
ypshimandClaude Haiku 5.5 committed 2026-11-10 15:38:30 +09:00
1 parent 0fb39076b8
commit bd84ac6176
2 files changed
+30 -2

No files matched your search

+9 -2
View File
@@ -344,9 +344,16 @@ export function buildPier(input: PierInput, ctx: PierContext = {}): PierModel {
const segments: Segment[] = frontPlaced.map((b, k) => ({ s0: bounds[k], s1: bounds[k + 1], top: seatOf.get(b.no) ?? b.z - h1 }));
// Lateral step (spec §4.3, Q1·Q2 추천안): front and back tops differ by 5 mm or more in some segment.
// The back steps break midway between consecutive back bearings (2026-11-10), as the front ones do: back bearings need
// not sit opposite the front ones (산외교 P11 ⑥ ↔ ⑦). With equal counts, a back bound less than half a block from the
// front bound snaps to it, so slightly staggered rows (P1, ≈ 0.09 m) keep one boundary and no sliver step.
const backBound = (k: number) => {
const own = (backPlaced[k-1].g + backPlaced[k].g) / 2;
return !unequalRows && Math.abs(own - bounds[k]) < DIM.blockSize / 2 ? bounds[k] : own;
};
const backSegments: Segment[] = backPlaced.map((b,k) => ({
s0: unequalRows ? (k === 0 ? 0 : (backPlaced[k-1].g+b.g)/2) : segments[k].s0,
s1: unequalRows ? (k === backPlaced.length-1 ? L : (b.g+backPlaced[k+1].g)/2) : segments[k].s1,
s0: k === 0 ? 0 : backBound(k),
s1: k === backPlaced.length-1 ? L : backBound(k + 1),
top: seatOf.get(b.no) ?? b.z-h2,
}));
const stepBounds = [...new Set([0,L,...segments.slice(1).map(s=>s.s0),...backSegments.slice(1).map(s=>s.s0)])].sort((a,b)=>a-b);