diff --git a/src/core/abut/rebar/wing.ts b/src/core/abut/rebar/wing.ts index 9c7b86d..ca81136 100644 --- a/src/core/abut/rebar/wing.ts +++ b/src/core/abut/rebar/wing.ts @@ -6,7 +6,7 @@ * - 수평: WR3–5 배면 (@s_v), WR13–15 전면 (@2·s_v), 띠 = 등단면 / 변화단면1 / 변화단면2. 맨 위 2단은 상단 경사와 나란히 * (사용자 결정 2026-11-04, Q-WR1), 일반 단은 그 아래 s 이상. 교대 쪽 끝은 교대 단면을 지나 반대쪽 면 − c, 90° 갈고리. * - WR6 경사 하단 2개, WR7-1 · 7-2 · 7-3 헌치 꺾임 (전면 수평과 같은 단), WR9 저판 상면 헌치 보강 꺾임 (@2·s_h 자동 개수, 사용자 도면), - * WR10 모서리 꺾임 (@s_v), WR20 간격재. 교대 철근과의 간섭은 보지 않는다 (Q-WR2 · Q-WR4 결정). + * WR10 모서리 ㄱ자 (@s_v, 교대 끝면 쪽), WR20 간격재. 교대 철근과의 간섭은 보지 않는다 (Q-WR2 · Q-WR4 결정). * - 단축형 (QA-14 · §9): WR1 · WR11 · WR6 없음, 연직은 모두 등단면. * - 좌표: 교대 (s, t, z) — s 교대축 (IP1에서), t 교대축 직각 (전면 +), z 저판 하면에서. 날개벽 거리 d는 교대축 선에서 날개벽 방향. */ @@ -41,6 +41,9 @@ export const ABUT_WING_SIZES = { } as const satisfies Record; export type WingMark = keyof typeof ABUT_WING_SIZES; +/** WR10 ㄱ자 (사용자 도면 2026-11-05): 날개벽 바깥면 피복, 교대 쪽 다리, 날개벽 쪽 다리 (mm). */ +export const WR10 = { cover: 123, abutLeg: 3000, wingLeg: 1000 } as const; + type V2 = [number, number]; /** 한 측 날개벽 형상 (mm, 교대 s · t, z는 저판 하면에서). */ @@ -443,18 +446,13 @@ export function abutWingRebar(g: AbutWingGeom, changes?: Partial g.bracketTop + 1e-6 ? g.parapetBackT : g.wallBackT; - const wingLine = at(0, T - depth10); - const X = lineX(wingLine, wDir, [0, backT + depth10], [1, 0]); - const X1 = add2(X, uOut, r); - const X2 = add2(X, wDir, r); - const leg = legEnd(X2, z); - put('WR10', [P3(add2(X1, uOut, ld.H25), z), P3(X1, z), P3(X2, z), P3(add2(X2, wDir, leg), z)], ld.H25 + leg + Math.hypot(X2[0] - X1[0], X2[1] - X1[1])); + const leg = Math.min(WR10.wingLeg, legEnd(B, z)); + put('WR10', [P3(add2(B, uOut, WR10.abutLeg), z), P3(B, z), P3(add2(B, wDir, leg), z)], WR10.abutLeg + leg); } } // WR20 (§8): 간격재, 수평 @k·s_h × 연직 @k·s_v, 단마다 반 칸 엇갈림, 전면 · 배면 수평철근 사이 + 양끝 갈고리. @@ -507,7 +505,7 @@ export function abutWingRebar(g: AbutWingGeom, changes?: Partial { expect(R.haunchLevels['WR7-3']).toBeLessThan(total - R.haunchLevels['WR7-1'] - 6); }); }); + +describe('WR10 ㄱ자 (사용자 도면 2026-11-05)', () => { + it('꺾이는 점은 날개벽 바깥면 − 123 · 흉벽 배면 + 123, 교대 쪽 다리 3,000 (s 방향), 날개벽 쪽 다리 1,000; 단 수 38 그대로', () => { + const p = L1.paths.find((q) => q.mark === 'WR10')!; + expect(p.pts.length).toBe(3); + const [a, B, e] = p.pts; + expect(B[1]).toBeCloseTo(left.parapetBackT + 123, 6); + expect(a[1]).toBeCloseTo(B[1], 6); // 교대 쪽 다리는 s 방향 + expect(Math.abs(a[0] - B[0])).toBeCloseTo(3000, 6); + expect(Math.hypot(e[0] - B[0], e[1] - B[1])).toBeCloseTo(1000, 6); + const [ws, wt] = left.w; + const iw = left.inward[0] * ws + left.inward[1] * wt; + const nv = [left.inward[0] - iw * ws, left.inward[1] - iw * wt]; + const T = Math.hypot(nv[0], nv[1]); + expect(((B[0] - left.p0[0]) * nv[0] + (B[1] - left.p0[1]) * nv[1]) / T).toBeCloseTo(123, 6); + // 교대 쪽 다리는 교대 안쪽 (날개벽에서 반대쪽 날개벽 방향)으로. + expect(Math.sign(a[0] - B[0])).toBe(Math.sign(left.inward[0])); + expect(bar(L1, 'WR10')?.count).toBe(38); + }); +});