feat(abut): 흉벽 배면 헌치를 삽도 A-A대로 추가 (날개벽 내측면)
- 흉벽 배면(t −0.5)과 브라켓 상면이 만나는 곳에 (t, EL) 직각삼각형 헌치 (다리 0.3 m) - 날개벽 내측면에서 중앙 방향으로 0.3 m 밀어 만듦. 브라켓 상면이 s 방향으로 기울어 있어 두 끝 중 높은 쪽에 맞춤 - 테스트: 헌치 개수 4 (흉벽 배면 + 저판 상면), 흉벽 배면 헌치가 브라켓 상면 위에 있음. 전체 638건 통과, 타입 검사·빌드 통과. 브라우저 시각 확인은 미실시 Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
61ef001034
commit
aaa9f57908
3 files changed
+25
-2
No files matched your search
@@ -284,6 +284,20 @@ export function buildAbutGroup(
|
||||
const lower = prism(clipBelowX(below, members.shape.wallBackM / dir.wt), WING_THICKNESS_M, new THREE.Vector3(sEnd, 0, 0), ax, ey, new THREE.Vector3(a, 0, 0));
|
||||
add('wings', upper, 0xc9a77c);
|
||||
add('wings', lower, 0xc9a77c);
|
||||
// 흉벽 배면 헌치 (삽도 A-A, 2026-11-03): a right triangle in the plane t–EL where the 흉벽 배면 (t −0.5) meets the 브라켓 상면.
|
||||
// Legs 0.3 m: up the 흉벽 배면 and back along the 브라켓 상면 to the 벽체 배면 (t −0.8). Extruded 0.3 m from the 날개벽 내측면 toward the centre.
|
||||
const sInner = sEnd + a * WING_THICKNESS_M + (dir.ws / dir.wt) * members.shape.parapetBackM;
|
||||
const bracketHigh = Math.max(
|
||||
members.parapetTopStartEl + ((members.parapetTopEndEl - members.parapetTopStartEl) * sInner) / L - members.shape.bracketHeightM,
|
||||
members.parapetTopStartEl + ((members.parapetTopEndEl - members.parapetTopStartEl) * (sInner + a * HAUNCH_LEG_M)) / L - members.shape.bracketHeightM,
|
||||
);
|
||||
const ledge: [number, number][] = [
|
||||
[members.shape.parapetBackM, bracketHigh],
|
||||
[members.shape.parapetBackM, bracketHigh + HAUNCH_LEG_M],
|
||||
[members.shape.wallBackM, bracketHigh],
|
||||
];
|
||||
add('haunches', prism(ledge, HAUNCH_LEG_M, new THREE.Vector3(sInner, 0, 0), ez, ey, new THREE.Vector3(a, 0, 0)), 0xc9a77c);
|
||||
|
||||
// 저판 상면 헌치 (수평, 2026-11-03): a right triangle in the plane EL–s on the 저판 상면, next to the 날개벽 내측면,
|
||||
// extruded along the wing from the 벽체 배면 to the 뒷굽.
|
||||
if (wing.footingHaunch) {
|
||||
|
||||
@@ -96,4 +96,13 @@ describe('교대 3D: 받침블럭과 접속슬래브 (spec §4.2, §4.8)', () =>
|
||||
if (pos.getZ(i) >= members.shape.wallBackM) expect(pos.getY(i)).toBeGreaterThanOrEqual(backTop(pos.getX(i)) - 1e-6);
|
||||
}
|
||||
});
|
||||
|
||||
it('the 흉벽 배면 헌치 sits on the 브라켓 상면 against the 흉벽 back, not in it', () => {
|
||||
const backTop = (s: number) => members.parapetTopStartEl + ((members.parapetTopEndEl - members.parapetTopStartEl) * s) / model.length - members.shape.bracketHeightM;
|
||||
for (const h of (named('haunches') as THREE.Group).children) {
|
||||
const b = new THREE.Box3().setFromObject(h);
|
||||
if (b.max.z > members.shape.parapetBackM + 1e-6 || b.min.z < members.shape.wallBackM - 1e-6) continue; // not the 흉벽 배면 헌치
|
||||
expect(b.min.y).toBeGreaterThanOrEqual(Math.max(backTop(b.min.x), backTop(b.max.x)) - 1e-6);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -21,13 +21,13 @@ const group = buildAbutGroup(model, members, wings);
|
||||
const count = (name: string) => (group.getObjectByName(name) as THREE.Group | undefined)?.children.length ?? 0;
|
||||
|
||||
describe('교대 A1 3D 장면 (AA3·AA3b·AA3c)', () => {
|
||||
it('has the members: 5 wall blocks, 10 parapet parts (2 per step), 1 footing, 18 piles, 2 wings, 2 haunches (저판 상면)', () => {
|
||||
it('has the members: 5 wall blocks, 10 parapet parts (2 per step), 1 footing, 18 piles, 2 wings, 4 haunches (흉벽 배면 + 저판 상면)', () => {
|
||||
expect(count('wall')).toBe(5); // one 벽체 block per 교좌면 step (삽도)
|
||||
expect(count('parapet')).toBe(10); // per step: back strip (흉벽 배면 단차) and the 흉벽 (삽도)
|
||||
expect(count('footing')).toBe(1);
|
||||
expect(count('piles')).toBe(18);
|
||||
expect(count('wings')).toBe(4); // upper and lower part per wing
|
||||
expect(count('haunches')).toBe(2); // per wing: the 저판 상면 헌치
|
||||
expect(count('haunches')).toBe(4); // per wing: the 흉벽 배면 헌치 (삽도 A-A) and the 저판 상면 헌치
|
||||
});
|
||||
|
||||
it('spans from the pile tip (19.295 m) up to the highest parapet end (47.18 m)', () => {
|
||||
|
||||
Reference in new issue
Block a user