feat(core): lateral coping step (Q1·Q2) and IP4 bend-point solve (spec §4.1)

- Front and back coping tops that differ by 5 mm or more in any segment are
  drawn as two coping parts split at the midline between the bearing rows.
  Tolerance 5 mm and midline position are the draft assumptions (Q1·Q2).
- Scene extrudes each coping part across its own width.
- solveIp4 computes IP4 as the intersection of the IP1→IP2 line with the
  line through IP3 turned by the bend angle (positive = counter-clockwise,
  sign convention to be confirmed). Bent coping geometry remains 미실시.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
ypshimandClaude Haiku 5.5 committed 2026-10-22 09:04:12 +09:00
1 parent ad59c0c74d
commit d0fa9b94eb
4 files changed
+118 -26

No files matched your search

+7 -5
View File
@@ -65,11 +65,13 @@ export function buildPierScene(m: PierModel): PierScene {
parts[part].add(new THREE.Mesh(geometry, material));
};
// Coping: the elevation outline extruded across the width (no boolean operations).
const shape = new THREE.Shape(m.profile.map(([s, z]) => new THREE.Vector2(s, z)));
const coping = new THREE.ExtrudeGeometry(shape, { depth: m.copingB, bevelEnabled: false });
coping.translate(0, 0, -m.copingB / 2);
add('coping', coping);
// Coping: each part's elevation outline extruded across its width (no boolean operations).
for (const part of m.copingParts) {
const shape = new THREE.Shape(part.profile.map(([s, z]) => new THREE.Vector2(s, z)));
const coping = new THREE.ExtrudeGeometry(shape, { depth: part.nTo - part.nFrom, bevelEnabled: false });
coping.translate(0, 0, part.nFrom);
add('coping', coping);
}
for (const c of m.columns) {
const g = new THREE.CylinderGeometry(c.diameter / 2, c.diameter / 2, c.top - c.bottom, 48);