fix(abut-rebar): 날개벽 WR7-1 · 7-2 · 7-3 평면 형상 (긴 대각 + 양끝 갈고리 394)
- 사용자 도면(2026-11-05): 헌치 빗변과 나란한 대각이 안쪽 모서리를 c 떨어져 지나, 교대 쪽은 전면 − c (WR7-1 · 7-2 흉벽 전면, WR7-3 벽체 전면), 날개벽 쪽은 날개벽 바깥면 − c에서 끝남. 양끝 평면 90° 갈고리 394 (교대 안쪽 / 날개벽 끝 쪽) - WR7-3의 긴 대각이 더 낮은 이웃 계단의 교좌면 위로 나오는 단은 WR7-2로 (교좌면 계단을 날개벽 형상에 전달) - 테스트: 갈고리 394 · 끝점 · 대각 길이, WR7-1 · 7-2 끝, 우측 재분류, 콘크리트 안 검사 통과 Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
89ebf852a9
commit
7b9de649e5
5 files changed
+86
-31
No files matched your search
+45
-27
@@ -74,6 +74,9 @@ export interface AbutWingGeom {
|
||||
bracketTop: number;
|
||||
/** 저판 하면망 B6 · B8 높이 (z). */
|
||||
zB68: number;
|
||||
/** 교좌면 계단 (u = s − k·t 범위 mm, 교좌면 z): WR7-3이 긴 대각으로 이웃 계단까지 갈 때 그 교좌면 아래인지 본다. 없으면 seat 하나. */
|
||||
seats?: { from: number; to: number; z: number }[];
|
||||
skewK?: number;
|
||||
}
|
||||
|
||||
export type WingRole = '연직' | '수평' | '헌치' | '모서리' | '간격재' | '경사 하단';
|
||||
@@ -154,6 +157,8 @@ export function abutWingGeom(
|
||||
bands: { name: string; zBottomEl: number }[];
|
||||
},
|
||||
zB68: number,
|
||||
seats?: { from: number; to: number; z: number }[],
|
||||
skewK?: number,
|
||||
): AbutWingGeom {
|
||||
const front = { e: model.nLeft.e * model.frontSide, n: model.nLeft.n * model.frontSide };
|
||||
const st = (p: { e: number; n: number }): V2 => {
|
||||
@@ -193,6 +198,8 @@ export function abutWingGeom(
|
||||
seat: seatBand ? z(wing.bands.find((b) => b.name === '변화단면1')!.zBottomEl) : z(members.footingTopEl),
|
||||
bracketTop: z(wing.topStartEl - members.shape.bracketHeightM),
|
||||
zB68,
|
||||
seats,
|
||||
skewK,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -368,34 +375,44 @@ export function abutWingRebar(g: AbutWingGeom, changes?: Partial<AbutWingRebarSe
|
||||
};
|
||||
if (g.haunch > 0) {
|
||||
const sp = 2 * sBackV;
|
||||
const legIn = T - c - (d('H16') + d('H25')) / 2 - (d('H25') + d('H25')) / 2; // WR3–5 안쪽 25.4
|
||||
for (let k = 0; ; k++) {
|
||||
const z = g.footTop + c + k * sp;
|
||||
if (z > g.topStart - c + 1e-6) break;
|
||||
const mark: WingMark = z > g.bracketTop + 1e-6 ? 'WR7-1' : z > g.seat + 1e-6 ? 'WR7-2' : 'WR7-3';
|
||||
let mark: WingMark = z > g.bracketTop + 1e-6 ? 'WR7-1' : z > g.seat + 1e-6 ? 'WR7-2' : 'WR7-3';
|
||||
// 평면 (사용자 도면 2026-11-05): 헌치 빗변과 나란한 긴 대각이 안쪽 모서리(날개벽 배면 × 교대 배면)를 콘크리트 쪽으로 c 떨어져
|
||||
// 지나, 교대 쪽은 전면 − c 선(WR7-1 · 7-2 흉벽 전면, WR7-3 벽체 전면), 날개벽 쪽은 날개벽 바깥면 − c 선에서 끝난다.
|
||||
// 양끝은 평면 안 90° 갈고리 394: 교대 쪽은 전면 선을 따라 교대 안쪽으로, 날개벽 쪽은 바깥면 선을 따라 날개벽 끝 쪽으로.
|
||||
const plan = (m: WingMark) => {
|
||||
const backT = m === 'WR7-1' ? g.parapetBackT : g.wallBackT;
|
||||
const tEnd = m === 'WR7-3' ? g.wallFrontT - c : -c;
|
||||
const corner = lineX(at(0, T), wDir, [0, backT], [1, 0]);
|
||||
const hw = add2(corner, wDir, g.haunch);
|
||||
const ha = add2(corner, uOut, g.haunch);
|
||||
const dl = Math.hypot(ha[0] - hw[0], ha[1] - hw[1]);
|
||||
const du: V2 = [(ha[0] - hw[0]) / dl, (ha[1] - hw[1]) / dl];
|
||||
const away: V2 = [corner[0] - (hw[0] + ha[0]) / 2, corner[1] - (hw[1] + ha[1]) / 2];
|
||||
const al = Math.hypot(away[0], away[1]);
|
||||
const L0 = add2(corner, [away[0] / al, away[1] / al], c);
|
||||
const F = lineX(L0, du, [0, tEnd], [1, 0]);
|
||||
const G = lineX(L0, du, at(0, c), wDir);
|
||||
const legG = Math.min(h25, legEnd(G, z));
|
||||
const len = h25 + Math.hypot(G[0] - F[0], G[1] - F[1]) + legG;
|
||||
return { pts: [add2(F, uOut, h25), F, G, add2(G, wDir, legG)] as V2[], len };
|
||||
};
|
||||
let bar = plan(mark);
|
||||
// WR7-3의 긴 대각이 이웃 계단(교좌면이 더 낮음)까지 가면 그 교좌면 위로 나온다 → 그 단은 WR7-2 (흉벽 전면 − c, 브라켓 안).
|
||||
if (mark === 'WR7-3' && g.seats) {
|
||||
const seatAt = (q: V2) => {
|
||||
const u = q[0] - (g.skewK ?? 0) * q[1];
|
||||
return (g.seats!.find((x) => u < x.to) ?? g.seats![g.seats!.length - 1]).z;
|
||||
};
|
||||
if (bar.pts.some((q) => z > seatAt(q) + 1e-6)) {
|
||||
mark = 'WR7-2';
|
||||
bar = plan(mark);
|
||||
}
|
||||
}
|
||||
haunchLevels[mark]++;
|
||||
const backT = mark === 'WR7-1' ? g.parapetBackT : g.wallBackT;
|
||||
const tEnd = mark === 'WR7-3' ? g.wallFrontT - c : -c;
|
||||
// 모서리 = 배면 선 ∩ 교대 배면 선; 헌치 대각은 날개벽 쪽 점 ~ 교대 쪽 점, 철근은 그 안쪽 c.
|
||||
const backFace = at(0, T);
|
||||
const corner = lineX(backFace, wDir, [0, backT], [1, 0]);
|
||||
const hw = add2(corner, wDir, g.haunch);
|
||||
const ha = add2(corner, uOut, g.haunch);
|
||||
const dv: V2 = [ha[0] - hw[0], ha[1] - hw[1]];
|
||||
const dl = Math.hypot(dv[0], dv[1]);
|
||||
const du: V2 = [dv[0] / dl, dv[1] / dl];
|
||||
const toCorner: V2 = [corner[0] - hw[0], corner[1] - hw[1]];
|
||||
const nrm: V2 = [-du[1], du[0]];
|
||||
const sgn = nrm[0] * toCorner[0] + nrm[1] * toCorner[1] > 0 ? 1 : -1;
|
||||
const diagP = add2(hw, nrm, sgn * c);
|
||||
const legLine = at(0, legIn);
|
||||
const A = lineX(legLine, wDir, diagP, du);
|
||||
const B = lineX(diagP, du, [0, backT + c], [1, 0]);
|
||||
const leg = legEnd(A, z);
|
||||
const P0 = add2(A, wDir, leg);
|
||||
const C: V2 = [B[0], tEnd];
|
||||
const len = leg + Math.hypot(B[0] - A[0], B[1] - A[1]) + Math.abs(tEnd - B[1]) + h25;
|
||||
put(mark, [P3(P0, z), P3(A, z), P3(B, z), P3(C, z), P3(C, z - h25)], len);
|
||||
put(mark, bar.pts.map((q) => P3(q, z)), bar.len);
|
||||
}
|
||||
}
|
||||
// WR9 (사용자 도면 2026-11-04, 연직헌치 보강철근): 저판 상면 헌치(날개벽 배면 ~ 저판 상면, 다리 g.haunch) 보강.
|
||||
@@ -485,9 +502,10 @@ export function abutWingRebar(g: AbutWingGeom, changes?: Partial<AbutWingRebarSe
|
||||
push({ mark: 'WR4', size: SZ.WR4, role: '수평', spacing: hz1, actual: hz1, shape: `흉벽 + 브라켓 지나 90° 갈고리 ${h25}`, position: '배면 수평 · 변화단면1', note: '', basis: '규칙', modified: hMod });
|
||||
push({ mark: 'WR5', size: SZ.WR5, role: '수평', spacing: hz1, actual: hz1, shape: `벽체 지나 90° 갈고리 ${h25}`, position: '배면 수평 · 변화단면2', note: '', basis: '규칙', modified: hMod });
|
||||
push({ mark: 'WR6', size: SZ.WR6, role: '경사 하단', spacing: '—', actual: '—', shape: `경사 하단과 나란히 · 아래 저판 안 l_d ${ld.H16}`, position: '경사 하단 · 전면 · 배면 각 1', note: '"cycle-2" 삭제 (결정)', basis: '규칙', modified: false });
|
||||
push({ mark: 'WR7-1', size: SZ['WR7-1'], role: '헌치', spacing: hz2, actual: hz2, shape: `꺾임 · 날개벽 l_d ${ld.H25} · 헌치 대각 · 흉벽 지나 갈고리`, position: '위 헌치 · 브라켓 상면 ~ 상단', note: '날개벽 다리 WR3–5 안쪽 25.4 (Q-WR7)', basis: '규칙', modified: hMod });
|
||||
push({ mark: 'WR7-2', size: SZ['WR7-2'], role: '헌치', spacing: hz2, actual: hz2, shape: '꺾임 · 흉벽 + 브라켓 지나 갈고리', position: '아래 헌치 윗부분 · 교좌면 ~ 브라켓 상면', note: '띠 경계 브라켓 상면 / 교좌면 (Q-WR6)', basis: '규칙', modified: hMod });
|
||||
push({ mark: 'WR7-3', size: SZ['WR7-3'], role: '헌치', spacing: hz2, actual: hz2, shape: '꺾임 · 벽체 지나 갈고리', position: '아래 헌치 아랫부분 · 저판 상면 ~ 교좌면', note: 'WR8 결번', basis: '규칙', modified: hMod });
|
||||
const wr7Shape = (front: string) => `평면 꺾임 · 갈고리 ${h25} · 안쪽 모서리 c 지나는 대각 (헌치 빗변과 나란히) · ${front} − c ~ 날개벽 바깥면 − c · 갈고리 ${h25}`;
|
||||
push({ mark: 'WR7-1', size: SZ['WR7-1'], role: '헌치', spacing: hz2, actual: hz2, shape: wr7Shape('흉벽 전면'), position: '위 헌치 · 브라켓 상면 ~ 상단', note: '사용자 도면 2026-11-05: 긴 대각 + 양끝 평면 갈고리', basis: '규칙', modified: hMod });
|
||||
push({ mark: 'WR7-2', size: SZ['WR7-2'], role: '헌치', spacing: hz2, actual: hz2, shape: wr7Shape('흉벽 전면'), position: '아래 헌치 윗부분 · 교좌면 ~ 브라켓 상면', note: '띠 경계 브라켓 상면 / 교좌면 (Q-WR6)', basis: '규칙', modified: hMod });
|
||||
push({ mark: 'WR7-3', size: SZ['WR7-3'], role: '헌치', spacing: hz2, actual: hz2, shape: wr7Shape('벽체 전면'), position: '아래 헌치 아랫부분 · 저판 상면 ~ 교좌면', note: 'WR8 결번', basis: '규칙', modified: hMod });
|
||||
push({ mark: 'WR9', size: SZ.WR9, role: '헌치', spacing: lenText(2 * sBack), actual: lenText(2 * sBack), shape: `꺾임 · 연직 다리 ${lenText(la9)} · 헌치 빗변과 나란한 대각 · 저판 하면망에서 90° 갈고리 ${h16}`, position: '저판 상면 헌치 (날개벽 배면) · 벽체 배면 ~ 뒷굽 끝', note: `연직헌치 보강 (사용자 도면 2026-11-04) · @${lenText(2 * sBack)} 자동 개수 · 연직 다리 = 벽체 W9 · W10 정착장`, basis: '규칙', modified: vMod });
|
||||
push({ mark: 'WR10', size: SZ.WR10, role: '모서리', spacing: hz1, actual: hz1, shape: `꺾임 · 모서리 대각 300 · 양끝 l_d ${ld.H25}`, position: '벽체 · 흉벽 배면 ↔ 날개벽 배면 모서리 · 저판 상면 ~ 흉벽 상단', note: '헌치 철근과의 간섭은 보지 않음 (Q-WR4)', basis: '규칙', modified: hMod });
|
||||
push({ mark: 'WR20', size: SZ.WR20, role: '간격재', spacing: `${lenText(s.k20 * sBack)} × ${lenText(s.k20 * sBackV)}`, actual: '—', shape: `양끝 90° 갈고리 ${hook(SZ.WR20)}`, position: `내측 간격재 · 두께 ${lenText(T - 2 * (c + (d('H16') + d('H25')) / 2))} 걸침`, note: '철근표 H20은 오기 → H13', basis: '규칙', modified: s.k20 !== 8 });
|
||||
|
||||
+3
-1
@@ -3163,8 +3163,10 @@ function abutWingsBuilt(rec: AbutRecord, footing: AbutFootingRebar): { geom: Abu
|
||||
const model = buildAbut(toAbutInput(rec));
|
||||
const members = buildMembers(model, { bottomEl: rec.foundationBottomEl, pileLengthMm: rec.pileLengthMm }, rec.shape);
|
||||
const material = materialFor(state.material, state.fckByMember, 'abutBody');
|
||||
const zOf = (el: number) => (el - (members.footingBottomEl ?? 0)) * 1000;
|
||||
const seats = members.wallSegments.map((sg) => ({ from: sg.sFrom * 1000, to: sg.sTo * 1000, z: zOf(sg.seatEl) }));
|
||||
return buildWings(model, members, rec.wings, rec.wingDims).map((w) => {
|
||||
const geom = abutWingGeom(model, members, w, footing.z.B68);
|
||||
const geom = abutWingGeom(model, members, w, footing.z.B68, seats, abutSkewK(model));
|
||||
// WR9 연직 다리 = 벽체 W9 · W10 정착장 (사용자 결정 2026-11-04).
|
||||
return { geom, result: abutWingRebar(geom, rec.rebar?.wing, material, rec.name, resolveWallRebar(rec.rebar?.wall).la) };
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user