From bb2af4bdf546fd6faf1a0112e0093235e8ff25c1 Mon Sep 17 00:00:00 2001 From: ypshim Date: Thu, 5 Nov 2026 09:15:46 +0900 Subject: [PATCH] =?UTF-8?q?fix(abut-rebar):=20=EB=82=A0=EA=B0=9C=EB=B2=BD?= =?UTF-8?q?=20WR10=20=3D=20=EA=B5=90=EB=8C=80=20=EB=81=9D=EB=A9=B4=20?= =?UTF-8?q?=EC=AA=BD=20=E3=84=B1=EC=9E=90=20(=EA=B5=90=EB=8C=80=203,000=20?= =?UTF-8?q?=C2=B7=20=EB=82=A0=EA=B0=9C=EB=B2=BD=201,000)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 사용자 도면(2026-11-05): 꺾이는 점 = 날개벽 바깥면(교대 끝면) − 피복 123 선 × 흉벽 배면 + 123 선. 교대 쪽 다리 3,000 (s 방향, 교대 안쪽), 날개벽 쪽 다리 1,000 (바깥면 − 123, 경사 하단에서는 짧아짐). 단 @s_v · 단 수 그대로 (A1 38) - 이전 안쪽 모서리 L자 (대각 300 + 양끝 l_d) 폐기 - 테스트: 꺾이는 점 · 다리 길이 · 방향 · 단 수, 콘크리트 안 검사 통과 Co-Authored-By: Claude Haiku 5.5 --- src/core/abut/rebar/wing.ts | 22 ++++++++++------------ tests/abut-rebar-wing.test.ts | 20 ++++++++++++++++++++ 2 files changed, 30 insertions(+), 12 deletions(-) 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); + }); +});