Files
Pier_v1/src/core/bearing-ref.ts
T
ypshimandClaude Haiku 5.5 e4e141c801 feat(rebar,view): 받침 기준 — project-wide choice between Excel z (default) and drawing EL.X, with per-bearing drawing input on ②
The project has one basis: 엑셀 z (default) or 도면 EL.X. On ②, the bearing card lists EL.X, h1 and h2 for each bearing
(per pier), with a button to fill the reference values. With the drawing basis the model takes the drawing EL.X as the
bearing height; the coping tops stay within the 5 mm tolerance, the front block is 164 mm and the back 139 mm (excluding the
pad). The check compares EL.X − h1 − h2 with the Excel-basis coping top. The basis and the drawing values are saved in the
project file (optional fields). Changes regenerate every pier at once.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
2026-10-23 14:25:44 +09:00

145 lines
6.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { PierInput } from './types';
import type { PierModel } from './geometry';
/**
* 교량받침 reference tables from the P1 상세도 (도면값, 읽기 전용, 2026-10-23). They are not used in the model:
* the model keeps the imported values (Q16). EL.X is the drawing's bearing level; E = h1 + h2 + h3 + h4.
*/
export interface BearingRefRow {
no: number;
row: '전열' | '후열';
/** EL.X (m). */
elx: number;
/** 블럭 높이 h1 (mm, 도면). */
h1: number;
/** 모르타르 h2 (mm). */
h2: number;
/** 받침 h3 (mm). */
h3: number;
/** 솔플레이트 h4 (mm). */
h4: number;
/** E (mm, 도면). */
E: number;
A: number;
B: number;
C1: number;
C2: number | null;
C3: number | null;
C4: number | null;
C5: number | null;
C6: number | null;
S1: number;
}
export interface SolplateRefRow {
no: number;
/** 기울기 S (%), negative as drawn. */
s: number;
L: number;
W: number;
/** 중심 두께 T (mm). The solplate tapers along the bridge axis. */
T: number;
/** 두께 at the 교각축 직각 (−) side (mm). */
T1: number;
/** 두께 at the 교각축 직각 (+) side (mm). */
T2: number;
}
const FRONT = { h1: 164, h2: 50, h3: 181, h4: 30, E: 425 };
const BACK = { h1: 139, h2: 50, h3: 181, h4: 30, E: 400 };
export const BEARING_ELEVATION_REF: BearingRefRow[] = [
{ no: 1, row: '전열', elx: 43.625, ...FRONT, A: 700, B: 640, C1: 600, C2: 1298, C3: 2500, C4: 600, C5: 600, C6: 1200, S1: 852 },
{ no: 2, row: '전열', elx: 43.697, ...FRONT, A: 700, B: 640, C1: 600, C2: 1298, C3: 2500, C4: 600, C5: 600, C6: 1200, S1: 852 },
{ no: 3, row: '전열', elx: 43.768, ...FRONT, A: 700, B: 790, C1: 600, C2: 1298, C3: 2500, C4: 600, C5: 600, C6: 1200, S1: 852 },
{ no: 4, row: '전열', elx: 43.840, ...FRONT, A: 700, B: 640, C1: 600, C2: 1298, C3: 2500, C4: 600, C5: 600, C6: 1200, S1: 852 },
{ no: 5, row: '전열', elx: 43.912, ...FRONT, A: 700, B: 640, C1: 600, C2: 1298, C3: 2500, C4: 600, C5: 600, C6: 1200, S1: 852 },
{ no: 6, row: '후열', elx: 43.600, ...BACK, A: 700, B: 540, C1: 602, C2: null, C3: null, C4: null, C5: null, C6: null, S1: 950 },
{ no: 7, row: '후열', elx: 43.672, ...BACK, A: 700, B: 540, C1: 602, C2: null, C3: null, C4: null, C5: null, C6: null, S1: 950 },
{ no: 8, row: '후열', elx: 43.744, ...BACK, A: 700, B: 650, C1: 602, C2: null, C3: null, C4: null, C5: null, C6: null, S1: 950 },
{ no: 9, row: '후열', elx: 43.816, ...BACK, A: 700, B: 540, C1: 602, C2: null, C3: null, C4: null, C5: null, C6: null, S1: 950 },
{ no: 10, row: '후열', elx: 43.887, ...BACK, A: 700, B: 540, C1: 602, C2: null, C3: null, C4: null, C5: null, C6: null, S1: 950 },
];
export const SOLPLATE_REF: SolplateRefRow[] = [
{ no: 1, s: -1.910, L: 800, W: 740, T: 30, T1: 38, T2: 22 },
{ no: 2, s: -1.907, L: 800, W: 740, T: 30, T1: 38, T2: 22 },
{ no: 3, s: -1.905, L: 800, W: 890, T: 30, T1: 38, T2: 22 },
{ no: 4, s: -1.903, L: 800, W: 740, T: 30, T1: 38, T2: 22 },
{ no: 5, s: -1.901, L: 800, W: 740, T: 30, T1: 38, T2: 22 },
{ no: 6, s: -1.910, L: 800, W: 640, T: 30, T1: 38, T2: 22 },
{ no: 7, s: -1.907, L: 800, W: 640, T: 30, T1: 38, T2: 22 },
{ no: 8, s: -1.905, L: 800, W: 750, T: 30, T1: 38, T2: 22 },
{ no: 9, s: -1.903, L: 800, W: 640, T: 30, T1: 38, T2: 22 },
{ no: 10, s: -1.901, L: 800, W: 640, T: 30, T1: 38, T2: 22 },
];
/** 중심 두께 T of the 공통 규칙 (30 mm). T1 = T + L·|S|/2 (−측), T2 = T − L·|S|/2 (+측), so T1 + T2 = 2T. */
export const SOLPLATE_T_RULE = 30;
/** T1 / T2 by the drawing's rule: T ± L·|S|/2, rounded to mm (S in %). */
export function solplateTs(T: number, L: number, s: number): { T1: number; T2: number } {
const half = (L * Math.abs(s)) / 200;
return { T1: Math.round(T + half), T2: Math.round(T - half) };
}
/** 공통 규칙 (2단계, 승인 2026-10-23): inputs that drive E, L, W, T1, T2. Defaults are the drawing's values. */
export interface BearingRules {
/** 모르타르 h2 (mm). */
h2: number;
/** 받침 높이 h3 (mm). */
h3: number;
/** 솔플레이트 중심 두께 T (mm). */
T: number;
/** 솔플 여유 (mm): L = A + margin, W = B + margin. */
margin: number;
}
export const BEARING_RULES_DEFAULT: BearingRules = { h2: 50, h3: 181, T: SOLPLATE_T_RULE, margin: 100 };
/** Values of one bearing with the 공통 규칙 applied: E = h1 + h2 + h3 + h4, L = A + margin, W = B + margin, T1/T2 from T. */
export function applyBearingRules(row: BearingRefRow, rules: BearingRules): { E: number; L: number; W: number; T1: number; T2: number } {
const sp = SOLPLATE_REF[row.no - 1];
const L = row.A + rules.margin;
const { T1, T2 } = solplateTs(rules.T, L, sp.s);
return { E: row.h1 + rules.h2 + rules.h3 + row.h4, L, W: row.B + rules.margin, T1, T2 };
}
/** 받침 기준 (Q16, 승인 2026-10-23): 'excel' = 엑셀 z (기본), 'drawing' = 도면 EL.X. Project-wide. */
export type BearingBasis = 'excel' | 'drawing';
/** One bearing's drawing values entered on ② (mm for h1, h2; m for EL.X). */
export interface DrawingBearing {
no: number;
elx: number;
h1: number;
h2: number;
}
/** Tolerance for the coping top check against the drawing (승인 2026-10-23: 5 mm). */
export const DRAWING_TOL_MM = 5;
/** The input with each bearing's z replaced by the drawing EL.X, for bearings that have a drawing value. */
export function withDrawingBasis(input: PierInput, drawing: DrawingBearing[]): PierInput {
const byNo = new Map(drawing.map((d) => [d.no, d]));
return {
...input,
bearings: input.bearings.map((b) => {
const d = byNo.get(b.no);
return d ? { ...b, z: d.elx } : b;
}),
};
}
/** Coping top implied by each drawing row (EL.X − h1 − h2) against the model's coping top; differences in mm. */
export function drawingCopingCheck(model: PierModel, drawing: DrawingBearing[]): { no: number; diffMm: number; ok: boolean }[] {
const front = model.blocks.filter((b) => b.row === '전열');
const back = model.blocks.filter((b) => b.row === '후열');
return drawing.map((d) => {
const implied = d.elx - (d.h1 + d.h2) / 1000;
const modelTop = d.no <= 5 ? model.segments[d.no - 1]?.top : back[d.no - 6]?.bottom;
const diffMm = modelTop === undefined ? NaN : Math.round((modelTop - implied) * 1000 * 10) / 10;
return { no: d.no, diffMm, ok: Number.isFinite(diffMm) && Math.abs(diffMm) <= DRAWING_TOL_MM };
});
}