feat(rebar): 기둥 배근 입력 8개 (피복·띠철근 K3/K5/K4·K6·커플러·Δz·n_div), CL01·CL02 검사
- core/rebar/column-settings.ts: 입력 정의, 기본값(기둥철근 (1).md), 범위(제안), 검사 (CL01 범위, CL02 n_div 홀수) - 주철근 하단 갈고리는 고정 (입력 없음) - 기둥 탭 패널: 적용 버튼으로 반영, 계산 결과(K2 내측 r, 주철근·커플러 수량) 표시 - P1·P2 등분 수, P3·P5·P4·P6 간격, 커플러 간격·상승을 철근표 간격·비고와 근거(기본값/입력)에 연동 - 3D 주철근 개수도 n_div 입력을 사용 (COLUMN_P1 하드코딩 제거) Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
496e0ea4e5
commit
f619b9ea20
9 files changed
+215
-20
No files matched your search
+2
-1
@@ -23,7 +23,7 @@ export const EDITABLE_FIELDS = [
|
||||
] as const;
|
||||
|
||||
/** Inputs tracked for overrides and pending changes: the numeric cards plus 열별 본수 (an array, compared by value). */
|
||||
export const TRACKED_KEYS = [...EDITABLE_FIELDS.map((f) => f.key), 'pileRows', 'groundPosition', 'groundWaterOn', 'groundWaterEl', 'floodLevelEl', 'scourDepthM', 'highWaterEl', 'lowWaterEl', 'strataRows', 'bearingType', 'bearingLayout', 'blockRebar', 'copingRebar', 'topSplice'] as const;
|
||||
export const TRACKED_KEYS = [...EDITABLE_FIELDS.map((f) => f.key), 'pileRows', 'groundPosition', 'groundWaterOn', 'groundWaterEl', 'floodLevelEl', 'scourDepthM', 'highWaterEl', 'lowWaterEl', 'strataRows', 'bearingType', 'bearingLayout', 'blockRebar', 'copingRebar', 'topSplice', 'columnRebar'] as const;
|
||||
|
||||
export type EditableKey = (typeof TRACKED_KEYS)[number];
|
||||
|
||||
@@ -56,6 +56,7 @@ export const FIELD_LABELS: Record<EditableKey, string> = {
|
||||
blockRebar: '받침블럭 철근 설정',
|
||||
copingRebar: '코핑 배근 입력',
|
||||
topSplice: '상면 주철근 이음',
|
||||
columnRebar: '기둥 배근 입력',
|
||||
strataRows: '지층 행',
|
||||
};
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import { buildAxis, copingSpan, fromAxis, kinkArc, nearKink, toAxis } from './ax
|
||||
import { buildIntegratedBlocks, type IntegratedBlock } from './integrated-block';
|
||||
import { type BlockRebarSettings, DEFAULT_BLOCK_REBAR } from './rebar/bearing-block';
|
||||
import { type CopingRebarSettings, DEFAULT_COPING_REBAR, DEFAULT_TOP_SPLICE, type TopSpliceSettings } from './rebar/coping-settings';
|
||||
import { type ColumnRebarSettings, DEFAULT_COLUMN_REBAR } from './rebar/column-settings';
|
||||
import { layoutText, resolveRowCounts, rowLayout, type PileGeometry } from './piles';
|
||||
import type { PierInput, Row } from './types';
|
||||
import { type CopingGeom, P1_COPING_GEOM } from './coping-geom';
|
||||
@@ -181,6 +182,8 @@ export interface PierModel {
|
||||
copingRebar: CopingRebarSettings;
|
||||
/** 상면 주철근 이음 used by the coping rebar (승인 2026-10-26). */
|
||||
topSplice: TopSpliceSettings;
|
||||
/** 기둥 배근 입력 used by the column rebar (승인 2026-10-26). */
|
||||
columnRebar: ColumnRebarSettings;
|
||||
columns: ColumnModel[];
|
||||
footings: FootingModel[];
|
||||
blindings: BlindingModel[];
|
||||
@@ -471,6 +474,7 @@ export function buildPier(input: PierInput): PierModel {
|
||||
blockRebar: { ...DEFAULT_BLOCK_REBAR, ...input.blockRebar },
|
||||
copingRebar: { ...DEFAULT_COPING_REBAR, ...input.copingRebar },
|
||||
topSplice: { ...DEFAULT_TOP_SPLICE, ...input.topSplice },
|
||||
columnRebar: { ...DEFAULT_COLUMN_REBAR, ...input.columnRebar },
|
||||
columns,
|
||||
footings,
|
||||
blindings,
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* 기둥 배근 입력 (승인 2026-10-26, 시안 ③ 기둥 삽도). The inputs of the 기둥 panel; the names match ColumnInput.
|
||||
* Defaults are the 기둥철근 (1).md P1 values; the ranges are proposed and pending the design-standard check.
|
||||
* The 주철근 하단 갈고리 is fixed (no input).
|
||||
*/
|
||||
export interface ColumnRebarSettings {
|
||||
/** K1 중심 피복 c (기둥 면 ~ P1 중심, mm). */
|
||||
c: number;
|
||||
/** 띠철근 간격 K3 (일반 구간, mm). */
|
||||
ctcP3: number;
|
||||
/** 띠철근 간격 K5 (단부, mm). */
|
||||
ctcP5: number;
|
||||
/** 띠철근 간격 K4 (기초 안, mm). */
|
||||
ctcP4: number;
|
||||
/** 크로스타이 K6 간격 (단 간격, mm). */
|
||||
ctcP6: number;
|
||||
/** 주철근 커플러 간격 (기초 상면부터, mm). */
|
||||
ctcCoupler: number;
|
||||
/** P2 커플러를 P1보다 올리는 높이 (mm). */
|
||||
dzCp2: number;
|
||||
/** 주철근 원주 등분 수 n_div (P1·P2 공통, 짝수). */
|
||||
nDiv: number;
|
||||
}
|
||||
|
||||
export const DEFAULT_COLUMN_REBAR: ColumnRebarSettings = {
|
||||
c: 125,
|
||||
ctcP3: 300,
|
||||
ctcP5: 120,
|
||||
ctcP4: 120,
|
||||
ctcP6: 1800,
|
||||
ctcCoupler: 3000,
|
||||
dzCp2: 150,
|
||||
nDiv: 46,
|
||||
};
|
||||
|
||||
/** Allowed range per input (inclusive, mm). */
|
||||
export const COLUMN_REBAR_RANGES: Record<keyof ColumnRebarSettings, [number, number]> = {
|
||||
c: [100, 150],
|
||||
ctcP3: [200, 400],
|
||||
ctcP5: [80, 200],
|
||||
ctcP4: [80, 200],
|
||||
ctcP6: [1200, 2400],
|
||||
ctcCoupler: [2000, 4000],
|
||||
dzCp2: [0, 300],
|
||||
nDiv: [40, 50],
|
||||
};
|
||||
|
||||
export interface ColumnSettingsIssue {
|
||||
code: 'CL01' | 'CL02';
|
||||
key: keyof ColumnRebarSettings;
|
||||
message: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* CL01: a value is not a finite number or is out of range (W). CL02: n_div is odd (the main bars come in pairs around the circle).
|
||||
*/
|
||||
export function columnSettingsIssues(s: ColumnRebarSettings): ColumnSettingsIssue[] {
|
||||
const out: ColumnSettingsIssue[] = [];
|
||||
for (const key of Object.keys(COLUMN_REBAR_RANGES) as (keyof ColumnRebarSettings)[]) {
|
||||
const v = s[key];
|
||||
const [lo, hi] = COLUMN_REBAR_RANGES[key];
|
||||
if (!Number.isFinite(v) || v < lo || v > hi) {
|
||||
out.push({ code: 'CL01', key, message: `CL01 ${key} ${v} 범위 밖 (${lo}–${hi})` });
|
||||
}
|
||||
}
|
||||
if (Number.isFinite(s.nDiv) && s.nDiv % 2 !== 0) {
|
||||
out.push({ code: 'CL02', key: 'nDiv', message: `CL02 주철근 등분 수 ${s.nDiv}는 홀수 (짝수만 허용)` });
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { PierModel } from '../geometry';
|
||||
import { DEFAULT_MATERIAL, developmentLength, fyOf, hookLength, Material, NOMINAL_DIAMETER, spliceLength } from './common';
|
||||
import { layers } from './footing';
|
||||
import { DEFAULT_COLUMN_REBAR } from './column-settings';
|
||||
|
||||
/**
|
||||
* 기둥 철근 C4 (plan C4). Source: RAG/기둥철근 (1).md, 2026-10-22 최종 정리. Type-1 원형 중실 기둥.
|
||||
@@ -54,26 +55,19 @@ 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, D: model.columnDiameterMm };
|
||||
return { ...base, ...model.columnRebar, Hc, hcop, eP1, eTop, D: model.columnDiameterMm };
|
||||
}
|
||||
|
||||
export const COLUMN_P1: ColumnInput = {
|
||||
D: 2000,
|
||||
Hc: 12703,
|
||||
hcop: 2644,
|
||||
c: 125,
|
||||
...DEFAULT_COLUMN_REBAR,
|
||||
eP1: 485,
|
||||
// Coping middle level: (Level 하면 + 계단 상면)/2 on P1 = 42.233 → e_top 1322 (승인 2026-10-23, Q-C3 대체).
|
||||
eTop: 1322,
|
||||
Hf: 2000,
|
||||
nDiv: 46,
|
||||
ctcCoupler: 3000,
|
||||
dzCp2: 150,
|
||||
ctcP3: 300,
|
||||
ctcP5: 120,
|
||||
ctcP4: 120,
|
||||
rP4: 0.5,
|
||||
ctcP6: 1800,
|
||||
};
|
||||
|
||||
/** A bar in the 확대기초 top layer, height from the 확대기초 상면 (mm, negative = below). */
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { PierModel } from '../geometry';
|
||||
import { barLength, bearingBlockRebar, DEFAULT_BLOCK_REBAR, totals } from './bearing-block';
|
||||
import { DEFAULT_COPING_REBAR } from './coping-settings';
|
||||
import { DEFAULT_COLUMN_REBAR } from './column-settings';
|
||||
import { bottomPiece, topBarLength, widthLayout, topSplicePieces } from './coping-main';
|
||||
import { shearBars, shearBarsMulti, copingSideBars, SIDE_HOOK_LEG, c14Bars, c14Length, stairBars, stepDevLength, undersideAt, shearULength, capLength, PIECES_PER_POSITION } from './coping';
|
||||
import { sideRowLevels } from '../coping-geom';
|
||||
@@ -147,6 +148,17 @@ export function linkedSpacing(name: string, model: PierModel): Pick<RebarRow, 's
|
||||
basis: basis(c.c14UpperSpacing !== d.c14UpperSpacing || c.c14LowerSpacing !== d.c14LowerSpacing),
|
||||
};
|
||||
}
|
||||
// 기둥 (승인 2026-10-26): P1·P2 등분 수, 주철근 커플러, 띠철근 P3·P5·P4, 크로스타이 P6.
|
||||
const k = model.columnRebar;
|
||||
const kd = DEFAULT_COLUMN_REBAR;
|
||||
if (name === 'P1' || name === 'P2') return { spacing: `원주 ${k.nDiv}등분`, actual: '—', basis: basis(k.nDiv !== kd.nDiv) };
|
||||
if (name === '주철근 커플러') {
|
||||
return { spacing: `@${k.ctcCoupler} (P2 +${k.dzCp2})`, actual: '—', basis: basis(k.ctcCoupler !== kd.ctcCoupler || k.dzCp2 !== kd.dzCp2) };
|
||||
}
|
||||
if (name === 'P3') return { spacing: String(k.ctcP3), actual: String(k.ctcP3), basis: basis(k.ctcP3 !== kd.ctcP3) };
|
||||
if (name === 'P5') return { spacing: String(k.ctcP5), actual: String(k.ctcP5), basis: basis(k.ctcP5 !== kd.ctcP5) };
|
||||
if (name === 'P4') return { spacing: String(k.ctcP4), actual: String(k.ctcP4), basis: basis(k.ctcP4 !== kd.ctcP4) };
|
||||
if (name === 'P6') return { spacing: String(k.ctcP6), actual: String(k.ctcP6), basis: basis(k.ctcP6 !== kd.ctcP6) };
|
||||
if (name === 'S1') return { spacing: String(b.spacingS1), actual: String(b.spacingS1), basis: basis(b.spacingS1 !== bd.spacingS1) };
|
||||
if (name === 'S2') return { spacing: String(b.spacingS2), actual: String(b.spacingS2), basis: basis(b.spacingS2 !== bd.spacingS2) };
|
||||
return undefined;
|
||||
@@ -257,11 +269,11 @@ export function rebarSummary(
|
||||
const col = columnRebar(columnInputFor(model), mColumn);
|
||||
rows.push({ member: 'column', name: 'P1', size: 'S32', count: col.mainP1, length: null, pieces: col.p1Pieces.map((length) => ({ length, count: col.mainP1 })), note: `외측 r ${col.r1}, 마디 ${col.p1Pieces.join(' / ')} (첫 마디에 갈고리 ${col.p1Hook}, 기둥철근.md §3.2)` });
|
||||
rows.push({ member: 'column', name: 'P2', size: 'S32', count: col.mainP2, length: null, pieces: col.p2Pieces.map((length) => ({ length, count: col.mainP2 })), note: `내측 r ${col.r2}, 마디 ${col.p2Pieces.join(' / ')}` });
|
||||
rows.push({ member: 'column', name: '주철근 커플러', size: 'D32용 (L150 Ø60)', count: col.couplers, length: 150, note: '@3000, P2는 +150 mm 상향 엇갈림' });
|
||||
rows.push({ member: 'column', name: '주철근 커플러', size: 'D32용 (L150 Ø60)', count: col.couplers, length: 150, note: `@${model.columnRebar.ctcCoupler}, P2는 +${model.columnRebar.dzCp2} mm 상향 엇갈림` });
|
||||
const tieCouplerCount = col.p5Count + col.p4Count * 2;
|
||||
rows.push({ member: 'column', name: '띠철근 커플러', size: 'D19용 (L100 Ø40)', count: tieCouplerCount, length: 100, note: `단부 P5 1개(${col.p5Count}) · 기초안 P4 2개(${col.p4Count * 2}) 폐합용` });
|
||||
rows.push({ member: 'column', name: 'P3', size: 'H19', count: col.p3Count, length: col.p3Length, note: `일반 구간 띠철근 @300, 겹침 ${col.lapP3} (추천안, Q-C6)` });
|
||||
rows.push({ member: 'column', name: 'P5', size: 'H19', count: col.p5Count, length: col.p5Length, note: '단부 띠철근 @120, 커플러 1개' });
|
||||
rows.push({ member: 'column', name: 'P3', size: 'H19', count: col.p3Count, length: col.p3Length, note: `일반 구간 띠철근 @${model.columnRebar.ctcP3}, 겹침 ${col.lapP3} (추천안, Q-C6)` });
|
||||
rows.push({ member: 'column', name: 'P5', size: 'H19', count: col.p5Count, length: col.p5Length, note: `단부 띠철근 @${model.columnRebar.ctcP5}, 커플러 1개` });
|
||||
rows.push({ member: 'column', name: 'P4', size: 'H19', count: col.p4Count, length: col.p4SemicircleLength * 2, note: '확대기초 안, 반원 2개 (길이는 반원 2개 합) · B11 간섭 무시' });
|
||||
rows.push({ member: 'column', name: 'P6', size: 'H16', count: col.p6Count, length: col.p6Length, note: '크로스타이, 8단 × 4' });
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { CopingRebarSettings, TopSpliceSettings } from './rebar/coping-settings';
|
||||
import type { ColumnRebarSettings } from './rebar/column-settings';
|
||||
|
||||
export type PierType = 'T형' | '2주형' | '3주형';
|
||||
export type FoundationType = '말뚝기초' | '직접기초' | '현장타설말뚝';
|
||||
@@ -80,6 +81,8 @@ export interface PierInput {
|
||||
copingRebar?: Partial<CopingRebarSettings>;
|
||||
/** 상면 주철근(C1–C6) 이음 (승인 2026-10-26). Absent = 이음 무시, 기둥 중심. */
|
||||
topSplice?: Partial<TopSpliceSettings>;
|
||||
/** 기둥 배근 입력 (승인 2026-10-26, 시안 ③ 기둥). Absent = the 기둥철근 (1).md defaults. */
|
||||
columnRebar?: Partial<ColumnRebarSettings>;
|
||||
strataRows?: StrataRow[];
|
||||
}
|
||||
|
||||
|
||||
+67
@@ -28,6 +28,8 @@ import { copingEndStation, copingFrontSvg, copingSectionSvg } from './view/copin
|
||||
import { BLOCK_REBAR_RANGES } from './core/rebar/block-check';
|
||||
import { DEFAULT_BLOCK_REBAR, type BlockRebarSettings } from './core/rebar/bearing-block';
|
||||
import { COPING_REBAR_RANGES, copingSettingsIssues, type CopingRebarSettings, DEFAULT_COPING_REBAR, DEFAULT_TOP_SPLICE, type TopSpliceSettings } from './core/rebar/coping-settings';
|
||||
import { COLUMN_REBAR_RANGES, type ColumnRebarSettings, columnSettingsIssues, DEFAULT_COLUMN_REBAR } from './core/rebar/column-settings';
|
||||
import { columnInputFor, columnRebar } from './core/rebar/column';
|
||||
import { groundSectionSvg } from './view/ground-svg';
|
||||
import { parseBearingElevationTable, parseSolplateTable, readDxfTexts } from './core/dxf-table';
|
||||
import { columnDiameterIssues } from './core/column-check';
|
||||
@@ -1183,6 +1185,70 @@ function renderCopingSettings(box: HTMLDivElement, pier: Pier): void {
|
||||
box.appendChild(wrap);
|
||||
}
|
||||
|
||||
/** 기둥 배근 입력 (승인 2026-10-26, 시안 ③ 기둥 삽도). The 주철근 하단 갈고리 is fixed. The 띠철근 간격 is three inputs (K3 · K5 · K4). */
|
||||
const COLUMN_REBAR_FIELDS: { key: keyof ColumnRebarSettings; label: string }[] = [
|
||||
{ key: 'c', label: 'K1 중심 피복 c (mm)' },
|
||||
{ key: 'ctcP3', label: '띠철근 간격 K3 (mm)' },
|
||||
{ key: 'ctcP5', label: '띠철근 간격 K5 (mm)' },
|
||||
{ key: 'ctcP4', label: '띠철근 간격 K4 (mm)' },
|
||||
{ key: 'ctcP6', label: '크로스타이 K6 간격 (mm)' },
|
||||
{ key: 'ctcCoupler', label: '커플러 간격 ctcOfcoupler (mm)' },
|
||||
{ key: 'dzCp2', label: 'P2 커플러 상승 Δz (mm)' },
|
||||
{ key: 'nDiv', label: '주철근 원주 등분 수 n_div' },
|
||||
];
|
||||
|
||||
/** 적용: the values go to the draft and the model is rebuilt only when every check passes (CL01·CL02). */
|
||||
function applyColumnRebar(name: string, next: ColumnRebarSettings): void {
|
||||
const p = state.piers.find((q) => q.input.name === name);
|
||||
if (!p) return;
|
||||
p.draft = { ...p.draft, columnRebar: next };
|
||||
regenerateOne(name);
|
||||
}
|
||||
|
||||
function renderColumnSettings(box: HTMLDivElement, pier: Pier): void {
|
||||
if (!pier.model) return;
|
||||
const wrap = el('div', undefined, 'bearing-ref');
|
||||
const current: ColumnRebarSettings = { ...DEFAULT_COLUMN_REBAR, ...pier.draft.columnRebar };
|
||||
wrap.appendChild(el('p', '기둥 배근 입력 (기본값 = 기둥철근 (1).md · 적용을 눌러야 반영)', 'lbl'));
|
||||
const grid = el('div', undefined, 'edit-fields');
|
||||
const inputs = new Map<keyof ColumnRebarSettings, HTMLInputElement>();
|
||||
for (const f of COLUMN_REBAR_FIELDS) {
|
||||
const row = el('div', undefined, 'edit-row');
|
||||
const label = el('label', f.label);
|
||||
const input = el('input');
|
||||
input.type = 'number';
|
||||
input.step = 'any';
|
||||
input.value = String(current[f.key]);
|
||||
input.id = `column-${f.key}`;
|
||||
label.htmlFor = input.id;
|
||||
inputs.set(f.key, input);
|
||||
const [lo, hi] = COLUMN_REBAR_RANGES[f.key];
|
||||
const changed = current[f.key] !== DEFAULT_COLUMN_REBAR[f.key] ? ' · 기본과 다름' : '';
|
||||
row.append(label, input, el('span', `범위 ${lo}–${hi} · 기본 ${DEFAULT_COLUMN_REBAR[f.key]}${changed}`, 'muted small'));
|
||||
grid.appendChild(row);
|
||||
}
|
||||
wrap.appendChild(grid);
|
||||
// Read-only results of the current model (계산 값).
|
||||
const col = columnRebar(columnInputFor(pier.model));
|
||||
wrap.appendChild(el('p', `K2 내측 r ${col.r2} mm · P1 ${col.mainP1}본 · P2 ${col.mainP2}본 · 주철근 커플러 ${col.couplers}개`, 'muted small'));
|
||||
const msg = el('p', undefined, 'muted small');
|
||||
const apply = el('button', '적용', 'btn small');
|
||||
apply.type = 'button';
|
||||
apply.addEventListener('click', () => {
|
||||
const next = { ...current };
|
||||
for (const f of COLUMN_REBAR_FIELDS) next[f.key] = Number(inputs.get(f.key)?.value);
|
||||
const issues = columnSettingsIssues(next);
|
||||
if (issues.length > 0) {
|
||||
msg.textContent = issues.map((i) => i.message).join(' · ');
|
||||
setError('기둥 배근 입력을 확인하세요. 값은 반영되지 않았습니다.');
|
||||
return;
|
||||
}
|
||||
applyColumnRebar(pier.input.name, next);
|
||||
});
|
||||
wrap.append(msg, apply);
|
||||
box.appendChild(wrap);
|
||||
}
|
||||
|
||||
function renderCopingDrawings(box: HTMLDivElement, pier: Pier): void {
|
||||
if (!pier.model || !rebar3d) return;
|
||||
const L = pier.model.copingL;
|
||||
@@ -1258,6 +1324,7 @@ function renderRebar(): void {
|
||||
if (state.rebarMember === 'bearing') renderBlockRebarSettings(box, pier);
|
||||
if (state.rebarMember === 'coping' && rebar3d) renderCopingDrawings(box, pier);
|
||||
if (state.rebarMember === 'coping') renderCopingSettings(box, pier);
|
||||
if (state.rebarMember === 'column') renderColumnSettings(box, pier);
|
||||
const shown = rows.filter((r) => r.member === state.rebarMember);
|
||||
box.appendChild(rebarSelectBar(shown.map((r) => r.name)));
|
||||
const table = el('table', undefined, 'grid-table rebar-table');
|
||||
|
||||
+7
-7
@@ -4,7 +4,7 @@ import { assemblyEndOffset, assemblyJs, b10Levels, b9Bars, FOOTING_DEFAULTS, gri
|
||||
import { bottomPiece, MAIN, topSplicePieces, widthLayout } from '../core/rebar/coping-main';
|
||||
import { C14_INSET, c14Bars, CAP, COPING_REBAR, SHEAR_LOOP_STEP, shearBars, shearBarsMulti, shearUHeight, copingSideBars, SIDE_HOOK_LEG, stairBars, undersideAt } from '../core/rebar/coping';
|
||||
import { sideRowLevels } from '../core/coping-geom';
|
||||
import { columnRebar, columnInputFor, COLUMN_P1 } from '../core/rebar/column';
|
||||
import { columnRebar, columnInputFor } from '../core/rebar/column';
|
||||
import { barDepths, barsAcross } from '../core/rebar/bearing-block';
|
||||
import { blockFramePoint } from '../core/geometry';
|
||||
import { INTEGRATED_BLOCK } from '../core/integrated-block';
|
||||
@@ -294,8 +294,8 @@ export function buildRebar3D(m: PierModel, common: Material = DEFAULT_MATERIAL,
|
||||
const sc = c.s;
|
||||
const base = c.bottom;
|
||||
const rt = mm(col.tieRadius);
|
||||
for (let i = 0; i < COLUMN_P1.nDiv; i++) {
|
||||
const th = (2 * Math.PI * i) / COLUMN_P1.nDiv;
|
||||
for (let i = 0; i < colInput.nDiv; i++) {
|
||||
const th = (2 * Math.PI * i) / colInput.nDiv;
|
||||
const r1 = mm(col.r1);
|
||||
addBar('P1', c.k, [sc + r1 * Math.cos(th), base + mm(zBot), r1 * Math.sin(th)], [sc + r1 * Math.cos(th), base + mm(col.zTop1), r1 * Math.sin(th)], NOMINAL_DIAMETER.S32, COLOR.column);
|
||||
// 90° bottom hook of P1, outward (기둥철근.md §3.2, Q-C5): the 12·d tail is drawn, the bend is approximated by the tail's start.
|
||||
@@ -312,8 +312,8 @@ export function buildRebar3D(m: PierModel, common: Material = DEFAULT_MATERIAL,
|
||||
// Main bar couplers (D32, L150 Ø60, 4단 × 46줄 × 2열 = 368개): P1 at col.couplerP1, P2 at col.couplerP2 (+150 mm)
|
||||
const r1 = mm(col.r1);
|
||||
const r2 = mm(col.r2);
|
||||
for (let i = 0; i < COLUMN_P1.nDiv; i++) {
|
||||
const th = (2 * Math.PI * i) / COLUMN_P1.nDiv;
|
||||
for (let i = 0; i < colInput.nDiv; i++) {
|
||||
const th = (2 * Math.PI * i) / colInput.nDiv;
|
||||
const cosTh = Math.cos(th);
|
||||
const sinTh = Math.sin(th);
|
||||
// P1 couplers (184)
|
||||
@@ -334,7 +334,7 @@ export function buildRebar3D(m: PierModel, common: Material = DEFAULT_MATERIAL,
|
||||
|
||||
// Tie couplers (D19, L100 Ø40, 총 35개): P5 1개 (19개) · P4 2개 (16개)
|
||||
col.p5.forEach((z, j) => {
|
||||
const th = (2 * Math.PI * (j * 7 + 0.5)) / COLUMN_P1.nDiv;
|
||||
const th = (2 * Math.PI * (j * 7 + 0.5)) / colInput.nDiv;
|
||||
const cx = sc + rt * Math.cos(th);
|
||||
const cz = rt * Math.sin(th);
|
||||
const cy = base + mm(z);
|
||||
@@ -343,7 +343,7 @@ export function buildRebar3D(m: PierModel, common: Material = DEFAULT_MATERIAL,
|
||||
addBar('띠철근 커플러', c.k, [cx - dx, cy, cz - dz], [cx + dx, cy, cz + dz], 40, COLOR.couplerTie);
|
||||
});
|
||||
col.p4.forEach((z) => {
|
||||
const angles = [(2 * Math.PI * 0.5) / COLUMN_P1.nDiv, (2 * Math.PI * 0.5) / COLUMN_P1.nDiv + Math.PI];
|
||||
const angles = [(2 * Math.PI * 0.5) / colInput.nDiv, (2 * Math.PI * 0.5) / colInput.nDiv + Math.PI];
|
||||
angles.forEach((th) => {
|
||||
const cx = sc + rt * Math.cos(th);
|
||||
const cz = rt * Math.sin(th);
|
||||
|
||||
Reference in new issue
Block a user