feat(view,rebar): column diameter D as a free input on ② (1200–3000 mm, 50 mm steps), with three checks
D is an input on the column card (default 2000 mm). The 3D column, the piles of a cast-in pier and the column rebar follow it; n_div stays 46. Three checks run on each regenerate and appear in 알림: D below the Level width (2100), D + 2c within the coping width, and the 주철근 arc spacing ≥ max(1.5·d_b, 40). Spec §5.2 records the rule (approved 2026-10-23). Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a6b92ae341
commit
65c53f2b5d
7 files changed
+80
-4
No files matched your search
@@ -7,6 +7,7 @@ import type { PierInput } from './types';
|
||||
export const EDITABLE_FIELDS = [
|
||||
{ key: 'copingWidthMm', label: '코핑 폭 B', unit: 'mm' },
|
||||
{ key: 'copingLengthMm', label: '코핑 길이 L', unit: 'mm' },
|
||||
{ key: 'columnDiameterMm', label: '기둥 직경 D', unit: 'mm' },
|
||||
{ key: 'copingH1Mm', label: '끝단 높이 h1', unit: 'mm' },
|
||||
{ key: 'copingH2Mm', label: '테이퍼 높이 h2', unit: 'mm' },
|
||||
{ key: 'levelWidthMm', label: 'Level 폭', unit: 'mm' },
|
||||
@@ -21,6 +22,7 @@ export type EditableKey = (typeof TRACKED_KEYS)[number];
|
||||
export const FIELD_LABELS: Record<EditableKey, string> = {
|
||||
copingWidthMm: '코핑 폭 B',
|
||||
copingLengthMm: '코핑 길이 L',
|
||||
columnDiameterMm: '기둥 직경 D',
|
||||
copingH1Mm: '끝단 높이 h1',
|
||||
copingH2Mm: '테이퍼 높이 h2',
|
||||
levelWidthMm: 'Level 폭',
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* 기둥 직경 D (승인 2026-10-23): free input 1200–3000 mm in 50 mm steps. Checks, all in mm:
|
||||
* - D < Level 폭 (the column meets the Level zone);
|
||||
* - D + 2·c ≤ 코핑 폭 B (c = 125, 기둥철근.md: 기둥 면 ~ P1 중심 피복);
|
||||
* - the arc spacing of the 주철근 (2π·r1 / n_div, n_div = 46 kept) ≥ max(1.5·d_b, 40), with d_b = 32 (S32).
|
||||
* Pure: gives the messages for the 알림 list.
|
||||
*/
|
||||
import type { PierModel } from './geometry';
|
||||
|
||||
export const COLUMN_D_RANGE = { min: 1200, max: 3000, step: 50 } as const;
|
||||
export const COLUMN_COVER_MM = 125;
|
||||
const N_DIV = 46;
|
||||
const DB_MAIN = 31.8;
|
||||
|
||||
export function columnDiameterIssues(dMm: number, model: PierModel): string[] {
|
||||
const out: string[] = [];
|
||||
if (!Number.isFinite(dMm) || dMm < COLUMN_D_RANGE.min || dMm > COLUMN_D_RANGE.max || Math.round(dMm) % COLUMN_D_RANGE.step !== 0) {
|
||||
out.push(`기둥 직경은 ${COLUMN_D_RANGE.min}~${COLUMN_D_RANGE.max} mm, ${COLUMN_D_RANGE.step} mm 단위여야 합니다.`);
|
||||
return out;
|
||||
}
|
||||
const levelW = model.copingGeom.levelWidth;
|
||||
if (dMm >= levelW) out.push(`기둥 직경 ${dMm} mm가 Level 폭 ${levelW} mm 이상입니다.`);
|
||||
const copingW = model.copingB * 1000;
|
||||
if (dMm + 2 * COLUMN_COVER_MM > copingW) out.push(`기둥 직경 ${dMm} mm와 피복이 코핑 폭 ${copingW} mm를 넘습니다.`);
|
||||
const r1 = dMm / 2 - COLUMN_COVER_MM;
|
||||
const arc = (2 * Math.PI * r1) / N_DIV;
|
||||
const minArc = Math.max(1.5 * DB_MAIN, 40);
|
||||
if (arc < minArc) out.push(`주철근 순간격 ${arc.toFixed(1)} mm가 최소 ${minArc.toFixed(1)} mm보다 작습니다.`);
|
||||
return out;
|
||||
}
|
||||
@@ -166,6 +166,8 @@ export interface PierModel {
|
||||
endBottom: number;
|
||||
/** Coping heights and Level width in mm, as used by the coping rebar (1단계). */
|
||||
copingGeom: CopingGeom;
|
||||
/** Column diameter D (mm) used by the model and the column rebar. */
|
||||
columnDiameterMm: number;
|
||||
bearings: BearingLocal[];
|
||||
blocks: BlockModel[];
|
||||
columns: ColumnModel[];
|
||||
@@ -225,6 +227,8 @@ export function buildPier(input: PierInput): PierModel {
|
||||
const copingH1 = (input.copingH1Mm ?? P1_COPING_GEOM.h1) / 1000;
|
||||
const copingH2 = (input.copingH2Mm ?? P1_COPING_GEOM.h2) / 1000;
|
||||
const levelW = (input.levelWidthMm ?? P1_COPING_GEOM.levelWidth) / 1000;
|
||||
// Column diameter (m): the input, with 2.0 m when absent (승인 2026-10-23).
|
||||
const colD = (input.columnDiameterMm ?? DIM.columnDiameter * 1000) / 1000;
|
||||
const planHalfB = B / 2;
|
||||
const ip1v: Vec2 = { e: ip1.x, n: ip1.y };
|
||||
const ip2v: Vec2 = { e: ip2.x, n: ip2.y };
|
||||
@@ -367,7 +371,7 @@ export function buildPier(input: PierInput): PierModel {
|
||||
k: colK[i],
|
||||
top: levelBottom,
|
||||
bottom: footingTop,
|
||||
diameter: DIM.columnDiameter,
|
||||
diameter: colD,
|
||||
}));
|
||||
|
||||
const footings: FootingModel[] = [];
|
||||
@@ -378,7 +382,7 @@ export function buildPier(input: PierInput): PierModel {
|
||||
|
||||
if (input.foundationType === '현장타설말뚝') {
|
||||
columns.forEach((c) => {
|
||||
piles.push({ s: c.s, k: c.k, n: 0, top: input.footingBottomEl, bottom: pileTip, diameter: DIM.columnDiameter });
|
||||
piles.push({ s: c.s, k: c.k, n: 0, top: input.footingBottomEl, bottom: pileTip, diameter: colD });
|
||||
});
|
||||
} else {
|
||||
for (const f of footingSets) {
|
||||
@@ -448,6 +452,7 @@ export function buildPier(input: PierInput): PierModel {
|
||||
levelBottom,
|
||||
endBottom,
|
||||
copingGeom: { h1: copingH1 * 1000, h2: copingH2 * 1000, levelWidth: levelW * 1000 },
|
||||
columnDiameterMm: colD * 1000,
|
||||
bearings: [...frontPlaced, ...backPlaced].map((b) => ({ no: b.no, row: b.row, k: b.k, s: b.s, g: b.g, n: b.n, z: b.z })),
|
||||
blocks,
|
||||
columns,
|
||||
|
||||
@@ -54,7 +54,7 @@ export function columnInputFor(model: PierModel, base: ColumnInput = COLUMN_P1):
|
||||
const eP1 = Math.round((seg.top - (c3 - 0.1)) * 1000);
|
||||
// e_top: the coping middle level (Level 하면 + 계단 상면)/2 is the top of P3 and P6 (승인 2026-10-23).
|
||||
const eTop = Math.round((seg.top - (model.levelBottom + seg.top) / 2) * 1000);
|
||||
return { ...base, Hc, hcop, eP1, eTop };
|
||||
return { ...base, Hc, hcop, eP1, eTop, D: model.columnDiameterMm };
|
||||
}
|
||||
|
||||
export const COLUMN_P1: ColumnInput = {
|
||||
|
||||
@@ -30,6 +30,8 @@ export interface PierInput {
|
||||
foundationType: FoundationType;
|
||||
pileLengthMm: number;
|
||||
copingWidthMm: number;
|
||||
/** 기둥 직경 D (mm, 1200–3000 in 50 mm steps, 승인 2026-10-23). Absent = 2000. */
|
||||
columnDiameterMm?: number;
|
||||
copingLengthMm: number;
|
||||
/** 끝단 높이 h1, 테이퍼 높이 h2, Level 폭 (mm). Absent = the P1 values (1000 · 1500 · 2100). */
|
||||
copingH1Mm?: number;
|
||||
|
||||
Reference in new issue
Block a user