feat(shape): 다주형 코핑 하면을 오목형으로 (Level D+200 · 오목 500 · 헌치 1500)
spec §3·§4.4(2026-11-06 개정)와 3주형형상배근.md §2.2(2주형 DWG 실측)를 따른다. - 기둥 사이 하면: Level 끝에서 헌치 수평 1500 동안 500 올라가 평탄, 다음 기둥 앞에서 내려옴 (이전 Level + 300, 헌치 300 × 300 대체) - 다주형 Level 폭 기본값 = D + 200 (입력값이 있으면 입력 우선). T형은 2100 유지 - 오목 평탄부가 없으면 RB-M01 오류 - 3주형 테스트는 오목형이 성립하는 20 m 코핑으로 바꿈 (P1 길이 12 m는 RB-M01) - 2주형 DWG 치수(L 24200, D 3000) 하면 꺾임점 테스트 추가 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
42316104df
commit
370bd3d7cd
8 files changed
+79
-34
No files matched your search
+22
-7
@@ -10,14 +10,25 @@ import { SOLPLATE_RULE_DEFAULT, solplatePlan } from './solplate-rule';
|
||||
import { type CopingGeom, P1_COPING_GEOM } from './coping-geom';
|
||||
import { castShape } from './cast-in-place-shape';
|
||||
|
||||
/** Default Level width (mm) when no input: T형 2100 (P1), 2·3주형 D + 200 (spec §3, 2주형 DWG 2026-11-06). */
|
||||
export function defaultLevelWidthMm(type: PierInput['type'], columnDiameterMm: number): number {
|
||||
return type === 'T형' ? P1_COPING_GEOM.levelWidth : columnDiameterMm + DIM.multiLevelExtra * 1000;
|
||||
}
|
||||
|
||||
/** Dimensions in m. Sources: intent.PR sheet (P1 rules) and spec.md §3 defaults. */
|
||||
export const DIM = {
|
||||
columnDiameter: 2.0,
|
||||
copingH1: 1.0,
|
||||
copingH2: 1.5,
|
||||
levelWidth: 2.1,
|
||||
/** Multi-column coping: underside between columns sits this far above Level, with 45° haunches of the same size (spec §4.4, Q3). */
|
||||
haunch: 0.3,
|
||||
/**
|
||||
* Multi-column coping, 오목형 underside (spec §4.4, 3주형형상배근.md §2.2, 2주형 DWG 2026-11-06):
|
||||
* from each Level end it rises concaveRise over the horizontal haunch length concaveHaunch, stays flat, and comes back down.
|
||||
*/
|
||||
concaveRise: 0.5,
|
||||
concaveHaunch: 1.5,
|
||||
/** Multi-column Level width = D + this (spec §3, 2주형 DWG). T형 keeps levelWidth (= D + 100 for P1). */
|
||||
multiLevelExtra: 0.2,
|
||||
padThickness: 0.05,
|
||||
padSize: 1.0,
|
||||
blockSize: 1.2,
|
||||
@@ -251,9 +262,9 @@ export function buildPier(input: PierInput): PierModel {
|
||||
// Coping heights and Level width (m): inputs, with the P1 values when absent (1단계).
|
||||
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 levelW = (input.levelWidthMm ?? defaultLevelWidthMm(input.type, colD * 1000)) / 1000;
|
||||
const planHalfB = B / 2;
|
||||
const ip1v: Vec2 = { e: ip1.x, n: ip1.y };
|
||||
const ip2v: Vec2 = { e: ip2.x, n: ip2.y };
|
||||
@@ -346,7 +357,8 @@ export function buildPier(input: PierInput): PierModel {
|
||||
const levelEnd = Math.max(...colG) + levelW / 2;
|
||||
if (levelStart < 0 || levelEnd > L) throw new Error('코핑 길이가 Level 구간보다 짧습니다.');
|
||||
|
||||
// Underside from the right end to the left end. Between columns (2·3주형) it rises 300 above Level with 300 × 300 haunches (spec §4.4, Q3).
|
||||
// Underside from the right end to the left end. Between columns (2·3주형) it is 오목형: from each Level end it rises
|
||||
// h_r (500) over the horizontal haunch l_h (1500), stays flat, and comes back down (spec §4.4, 3주형형상배근.md §2.2).
|
||||
const underside: [number, number][] = [[L, endBottom]];
|
||||
const levelZones = [...colG].sort((a, b) => b - a).map((s) => [s - levelW / 2, s + levelW / 2] as const);
|
||||
levelZones.forEach(([zoneStart, zoneEnd], k) => {
|
||||
@@ -354,9 +366,12 @@ export function buildPier(input: PierInput): PierModel {
|
||||
const next = levelZones[k + 1];
|
||||
if (!next) return;
|
||||
const gap = zoneStart - next[1];
|
||||
if (gap <= 2 * DIM.haunch) throw new Error('기둥 사이 간격이 헌치(300 × 2)보다 좁아 코핑 하면을 만들 수 없습니다.');
|
||||
const raisedEl = levelBottom + DIM.haunch;
|
||||
underside.push([zoneStart - DIM.haunch, raisedEl], [next[1] + DIM.haunch, raisedEl], [next[1], levelBottom]);
|
||||
// RB-M01: no flat part left between the two haunches.
|
||||
if (gap <= 2 * DIM.concaveHaunch + 1e-9) {
|
||||
throw new Error(`기둥 사이 간격 ${Math.round(gap * 1000)} mm가 오목형 헌치(${DIM.concaveHaunch * 1000} × 2)보다 짧아 코핑 하면을 만들 수 없습니다 (RB-M01).`);
|
||||
}
|
||||
const raisedEl = levelBottom + DIM.concaveRise;
|
||||
underside.push([zoneStart - DIM.concaveHaunch, raisedEl], [next[1] + DIM.concaveHaunch, raisedEl], [next[1], levelBottom]);
|
||||
});
|
||||
|
||||
// Elevation outline in coping coordinates for one row of tops, closed by the shared underside.
|
||||
|
||||
Reference in new issue
Block a user