- 한 변 = 코핑 길이 + 2 m, 교각 축에 맞춰 코핑 중심에 둠, 지반고 높이 - 패드는 교각별 추정이며 서로 잇지 않음 (지형 면 아님) - 테스트: 상면 네 모서리로 한 변과 대각선 길이 확인 Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
48 lines
2.4 KiB
TypeScript
48 lines
2.4 KiB
TypeScript
import * as THREE from 'three';
|
|
import { describe, expect, it } from 'vitest';
|
|
import { buildPier } from '../src/core/geometry';
|
|
import type { TerrainGrid } from '../src/core/ground-model';
|
|
import { buildPierScene } from '../src/view/scene';
|
|
import { loadP1 } from './helpers';
|
|
|
|
const model = buildPier(loadP1());
|
|
|
|
const terrain: TerrainGrid = { origin: [259815.676, 179088.094], step: 5, nx: 2, ny: 2, z: [30, 31, 32, 33] };
|
|
|
|
describe('지반 표시 (지형 모델이 없을 때)', () => {
|
|
it('draws a thin square pad at the pier 지반고, side = coping length + 2 m', () => {
|
|
const scene = buildPierScene(model);
|
|
const mesh = scene.parts.ground.children[0] as THREE.Mesh;
|
|
mesh.updateMatrixWorld(true);
|
|
const pos = mesh.geometry.getAttribute('position');
|
|
const pts: THREE.Vector3[] = [];
|
|
for (let i = 0; i < pos.count; i++) pts.push(new THREE.Vector3().fromBufferAttribute(pos, i).applyMatrix4(mesh.matrixWorld));
|
|
const top = Math.max(...pts.map((p) => p.y));
|
|
const corners = pts.filter((p) => Math.abs(p.y - top) < 1e-6);
|
|
// Four corners of the top face, with a distinct set of positions.
|
|
const unique = corners.filter((p, i) => corners.findIndex((q) => q.distanceTo(p) < 1e-6) === i);
|
|
expect(unique).toHaveLength(4);
|
|
const side = model.copingL + 2;
|
|
const edges = unique.flatMap((a, i) => unique.slice(i + 1).map((b) => a.distanceTo(b))).sort((a, b) => a - b);
|
|
// Four sides of length `side`, two diagonals of length side·√2.
|
|
for (const e of edges.slice(0, 4)) expect(e).toBeCloseTo(side, 3);
|
|
for (const e of edges.slice(4)) expect(e).toBeCloseTo(side * Math.SQRT2, 3);
|
|
// Thin: a pad, not a solid block. Centred on the ground EL.
|
|
const box = new THREE.Box3().setFromObject(scene.parts.ground);
|
|
expect(box.getSize(new THREE.Vector3()).y).toBeLessThan(0.1);
|
|
expect(box.getCenter(new THREE.Vector3()).y).toBeCloseTo(model.groundEl, 2);
|
|
});
|
|
|
|
it('keeps the ground group out of the pier size', () => {
|
|
const scene = buildPierScene(model);
|
|
expect(scene.size).toBeLessThan(60);
|
|
});
|
|
|
|
it('does not draw the line when the terrain grid is present (the terrain replaces it)', () => {
|
|
const scene = buildPierScene(model, terrain);
|
|
expect(scene.parts.ground.children.length).toBe(1);
|
|
const mesh = scene.parts.ground.children[0] as THREE.Mesh;
|
|
expect(mesh.geometry.type).toBe('BufferGeometry');
|
|
});
|
|
});
|