fix(rebar): 조립 철근 B11·B12를 짝수 격자에 배치 (B9 홀수 격자와 겹치지 않음)
- assemblyEvenStart: 짝수 시작칸 중 양끝 여유 차이가 가장 작은 값 선택 - B12(W 방향, n 61)는 시작칸이 1(홀수)이던 것을 2(짝수)로 바꿔 B9 행선과 겹치지 않게 함 - 개수(B11 30, B12 24)와 가운데 정렬(차이 ≤ 1칸)은 그대로, 엇갈림 2칸 유지 - 테스트: 조립 철근 인덱스가 모두 짝수 Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5fb2b9938f
commit
bad220d791
2 files changed
+34
-10
No files matched your search
+25
-10
@@ -139,18 +139,33 @@ export function assemblyEndOffset(): number {
|
||||
|
||||
/** B11 (along W, between the B10-2 levels) and B12 (along L), 4s apart with a 2s stagger per level (§8). */
|
||||
/**
|
||||
* Grid indices of the assembly bars (B11 or B12) on one level, centred in the grid (승인 2026-10-26, 추천안).
|
||||
* Bars every k steps; the level's 2-step stagger alternates (even levels start at e0, odd levels at e0 + 2), and e0 centres
|
||||
* the even group so the left and right gaps differ by at most one step. n = positions − 1; idx = level index (0, 1, …).
|
||||
* First grid index of the even group of the assembly bars (B11 or B12), chosen on EVEN indices (확대기초철근 (1).md §9.1: the
|
||||
* B5·B1 and B9 positions take the odd grid, so B11·B12 sit on the even grid and never overlap them). Among the even choices,
|
||||
* the one that centres the union of both 2-step-staggered groups best (left and right gaps as equal as possible) is used.
|
||||
*/
|
||||
export function assemblyEvenStart(n: number, k: number): number {
|
||||
let best = 0;
|
||||
let bestGap = Infinity;
|
||||
for (let e0 = 0; e0 + 2 <= n; e0 += 2) {
|
||||
const idx: number[] = [];
|
||||
for (const s of [e0, e0 + 2]) for (let i = s; i <= n; i += k) idx.push(i);
|
||||
const gap = Math.abs(Math.min(...idx) - (n - Math.max(...idx)));
|
||||
if (gap < bestGap) {
|
||||
best = e0;
|
||||
bestGap = gap;
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grid indices of the assembly bars (B11 or B12) on one level (승인 2026-10-26): every k grid steps, on even indices, with the
|
||||
* 2-step stagger between levels (even levels at e0, odd levels at e0 + 2). n = positions − 1; idx = level index (0, 1, …).
|
||||
*/
|
||||
export function assemblyGridIndices(n: number, k: number, idx: number): number[] {
|
||||
const cEven = Math.floor(n / k) + 1;
|
||||
const cOdd = Math.floor((n - 2) / k) + 1;
|
||||
const e0 = Math.max(0, Math.floor((n - (cEven - 1) * k - 2) / 2));
|
||||
const even = idx % 2 === 0;
|
||||
const start = even ? e0 : e0 + 2;
|
||||
const count = even ? cEven : cOdd;
|
||||
return Array.from({ length: count }, (_, m) => start + m * k).filter((i) => i <= n);
|
||||
const start = idx % 2 === 0 ? assemblyEvenStart(n, k) : assemblyEvenStart(n, k) + 2;
|
||||
const count = start <= n ? Math.floor((n - start) / k) + 1 : 0;
|
||||
return Array.from({ length: count }, (_, m) => start + m * k);
|
||||
}
|
||||
|
||||
export function assemblyBars(L: number, W: number, H: number, f: FootingRebarSettings = DEFAULT_FOOTING_REBAR): FootingBar[] {
|
||||
|
||||
@@ -49,4 +49,13 @@ describe('확대기초 교각축 직각 단면 (폭 W) (승인 2026-10-26, 추
|
||||
}
|
||||
expect(assemblyGridIndices(61, 8, 1)[0] - assemblyGridIndices(61, 8, 0)[0]).toBe(2);
|
||||
});
|
||||
|
||||
it('조립 철근(B11·B12)은 짝수 격자에 놓여 B9(홀수 격자)와 겹치지 않음 (확대기초철근 (1).md §9.1)', () => {
|
||||
const levels = assemblyJs(H, fs).length;
|
||||
for (const [n, k] of [[79, 8], [61, 8]] as const) {
|
||||
for (let idx = 0; idx < levels; idx++) {
|
||||
for (const i of assemblyGridIndices(n, k, idx)) expect(i % 2).toBe(0);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user