@pascal-app/core 0.9.2 → 1.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -10
- package/dist/events/bus.d.ts +21 -2
- package/dist/events/bus.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/floor-placed-elevation.d.ts +17 -1
- package/dist/hooks/spatial-grid/floor-placed-elevation.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/floor-placed-elevation.js +61 -8
- package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts +116 -66
- package/dist/hooks/spatial-grid/spatial-grid-manager.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/spatial-grid-manager.js +319 -441
- package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts +46 -1
- package/dist/hooks/spatial-grid/spatial-grid-sync.d.ts.map +1 -1
- package/dist/hooks/spatial-grid/spatial-grid-sync.js +204 -12
- package/dist/hooks/spatial-grid/support-host-id.d.ts +3 -0
- package/dist/hooks/spatial-grid/support-host-id.d.ts.map +1 -0
- package/dist/hooks/spatial-grid/support-host-id.js +2 -0
- package/dist/hooks/spatial-grid/support-host-patch.d.ts +51 -0
- package/dist/hooks/spatial-grid/support-host-patch.d.ts.map +1 -0
- package/dist/hooks/spatial-grid/support-host-patch.js +164 -0
- package/dist/index.d.ts +23 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -10
- package/dist/lib/measurement-geometry.d.ts +4 -0
- package/dist/lib/measurement-geometry.d.ts.map +1 -1
- package/dist/lib/measurement-geometry.js +27 -10
- package/dist/lib/slab-polygon.d.ts.map +1 -1
- package/dist/lib/slab-polygon.js +33 -1
- package/dist/lib/space-detection.d.ts +15 -4
- package/dist/lib/space-detection.d.ts.map +1 -1
- package/dist/lib/space-detection.js +232 -91
- package/dist/lib/terrain-brush.d.ts +163 -0
- package/dist/lib/terrain-brush.d.ts.map +1 -0
- package/dist/lib/terrain-brush.js +359 -0
- package/dist/lib/terrain-codec.d.ts +51 -0
- package/dist/lib/terrain-codec.d.ts.map +1 -0
- package/dist/lib/terrain-codec.js +167 -0
- package/dist/lib/terrain-field.d.ts +150 -0
- package/dist/lib/terrain-field.d.ts.map +1 -0
- package/dist/lib/terrain-field.js +248 -0
- package/dist/lib/terrain-raycast.d.ts +44 -0
- package/dist/lib/terrain-raycast.d.ts.map +1 -0
- package/dist/lib/terrain-raycast.js +188 -0
- package/dist/lib/terrain-source.d.ts +60 -0
- package/dist/lib/terrain-source.d.ts.map +1 -0
- package/dist/lib/terrain-source.js +90 -0
- package/dist/lib/terrain-support.d.ts +85 -0
- package/dist/lib/terrain-support.d.ts.map +1 -0
- package/dist/lib/terrain-support.js +218 -0
- package/dist/lib/zone-quantities.d.ts +1 -1
- package/dist/lib/zone-quantities.d.ts.map +1 -1
- package/dist/lib/zone-quantities.js +311 -66
- package/dist/material-library.d.ts +9 -1
- package/dist/material-library.d.ts.map +1 -1
- package/dist/material-library.js +56 -4
- package/dist/registry/handles.d.ts +16 -1
- package/dist/registry/handles.d.ts.map +1 -1
- package/dist/registry/index.d.ts +1 -1
- package/dist/registry/index.d.ts.map +1 -1
- package/dist/registry/subtree.d.ts.map +1 -1
- package/dist/registry/subtree.js +5 -2
- package/dist/registry/types.d.ts +83 -1
- package/dist/registry/types.d.ts.map +1 -1
- package/dist/schema/index.d.ts +6 -3
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +6 -3
- package/dist/schema/nodes/cabinet.d.ts +2 -0
- package/dist/schema/nodes/cabinet.d.ts.map +1 -1
- package/dist/schema/nodes/cabinet.js +4 -2
- package/dist/schema/nodes/ceiling.d.ts +1 -1
- package/dist/schema/nodes/ceiling.d.ts.map +1 -1
- package/dist/schema/nodes/ceiling.js +7 -1
- package/dist/schema/nodes/column.d.ts +1 -0
- package/dist/schema/nodes/column.d.ts.map +1 -1
- package/dist/schema/nodes/column.js +2 -0
- package/dist/schema/nodes/construction-dimension.d.ts +195 -0
- package/dist/schema/nodes/construction-dimension.d.ts.map +1 -0
- package/dist/schema/nodes/construction-dimension.js +151 -0
- package/dist/schema/nodes/door.d.ts +29 -0
- package/dist/schema/nodes/door.d.ts.map +1 -1
- package/dist/schema/nodes/door.js +20 -0
- package/dist/schema/nodes/duct-terminal.d.ts +1 -0
- package/dist/schema/nodes/duct-terminal.d.ts.map +1 -1
- package/dist/schema/nodes/duct-terminal.js +2 -0
- package/dist/schema/nodes/fence.d.ts +2 -0
- package/dist/schema/nodes/fence.d.ts.map +1 -1
- package/dist/schema/nodes/fence.js +8 -0
- package/dist/schema/nodes/hvac-equipment.d.ts +1 -0
- package/dist/schema/nodes/hvac-equipment.d.ts.map +1 -1
- package/dist/schema/nodes/hvac-equipment.js +2 -0
- package/dist/schema/nodes/item.d.ts +1 -0
- package/dist/schema/nodes/item.d.ts.map +1 -1
- package/dist/schema/nodes/item.js +13 -0
- package/dist/schema/nodes/level.d.ts +2 -1
- package/dist/schema/nodes/level.d.ts.map +1 -1
- package/dist/schema/nodes/level.js +12 -33
- package/dist/schema/nodes/shelf.d.ts +1 -0
- package/dist/schema/nodes/shelf.d.ts.map +1 -1
- package/dist/schema/nodes/shelf.js +2 -0
- package/dist/schema/nodes/site.d.ts +9 -0
- package/dist/schema/nodes/site.d.ts.map +1 -1
- package/dist/schema/nodes/site.js +8 -6
- package/dist/schema/nodes/slab.d.ts +5 -0
- package/dist/schema/nodes/slab.d.ts.map +1 -1
- package/dist/schema/nodes/slab.js +14 -2
- package/dist/schema/nodes/spawn.d.ts +1 -0
- package/dist/schema/nodes/spawn.d.ts.map +1 -1
- package/dist/schema/nodes/spawn.js +2 -0
- package/dist/schema/nodes/stair.d.ts +3 -1
- package/dist/schema/nodes/stair.d.ts.map +1 -1
- package/dist/schema/nodes/stair.js +8 -1
- package/dist/schema/nodes/structural-grid.d.ts +27 -0
- package/dist/schema/nodes/structural-grid.d.ts.map +1 -0
- package/dist/schema/nodes/structural-grid.js +17 -0
- package/dist/schema/nodes/wall.d.ts +5 -2
- package/dist/schema/nodes/wall.d.ts.map +1 -1
- package/dist/schema/nodes/wall.js +13 -4
- package/dist/schema/nodes/window.d.ts +29 -0
- package/dist/schema/nodes/window.d.ts.map +1 -1
- package/dist/schema/nodes/window.js +18 -0
- package/dist/schema/nodes/zone.d.ts +20 -0
- package/dist/schema/nodes/zone.d.ts.map +1 -1
- package/dist/schema/nodes/zone.js +15 -0
- package/dist/schema/terrain.d.ts +28 -0
- package/dist/schema/terrain.d.ts.map +1 -0
- package/dist/schema/terrain.js +30 -0
- package/dist/schema/types.d.ts +211 -3
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/types.js +4 -0
- package/dist/services/__fixtures__/wall-plane-top-boundary-repro.d.ts +80 -0
- package/dist/services/__fixtures__/wall-plane-top-boundary-repro.d.ts.map +1 -0
- package/dist/services/__fixtures__/wall-plane-top-boundary-repro.js +89 -0
- package/dist/services/index.d.ts +2 -1
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +2 -1
- package/dist/services/level-height.d.ts +8 -9
- package/dist/services/level-height.d.ts.map +1 -1
- package/dist/services/level-height.js +48 -16
- package/dist/services/storey.d.ts +103 -0
- package/dist/services/storey.d.ts.map +1 -0
- package/dist/services/storey.js +296 -0
- package/dist/store/actions/node-actions.d.ts.map +1 -1
- package/dist/store/actions/node-actions.js +47 -3
- package/dist/store/history-control.d.ts +20 -0
- package/dist/store/history-control.d.ts.map +1 -1
- package/dist/store/history-control.js +110 -13
- package/dist/store/use-live-terrain.d.ts +65 -0
- package/dist/store/use-live-terrain.d.ts.map +1 -0
- package/dist/store/use-live-terrain.js +31 -0
- package/dist/store/use-live-transforms.d.ts +8 -0
- package/dist/store/use-live-transforms.d.ts.map +1 -1
- package/dist/store/use-scene.d.ts +31 -2
- package/dist/store/use-scene.d.ts.map +1 -1
- package/dist/store/use-scene.js +638 -8
- package/dist/systems/elevator/elevator-opening-system.d.ts +1 -0
- package/dist/systems/elevator/elevator-opening-system.d.ts.map +1 -1
- package/dist/systems/elevator/elevator-opening-system.js +27 -21
- package/dist/systems/elevator/elevator-service.d.ts +0 -2
- package/dist/systems/elevator/elevator-service.d.ts.map +1 -1
- package/dist/systems/elevator/elevator-service.js +2 -24
- package/dist/systems/slab/slab-placement.d.ts +11 -0
- package/dist/systems/slab/slab-placement.d.ts.map +1 -0
- package/dist/systems/slab/slab-placement.js +14 -0
- package/dist/systems/slab/slab-support.d.ts +150 -0
- package/dist/systems/slab/slab-support.d.ts.map +1 -0
- package/dist/systems/slab/slab-support.js +575 -0
- package/dist/systems/stair/stair-opening-preview.d.ts +1060 -935
- package/dist/systems/stair/stair-opening-preview.d.ts.map +1 -1
- package/dist/systems/stair/stair-opening-sync.d.ts.map +1 -1
- package/dist/systems/stair/stair-opening-sync.js +18 -15
- package/dist/systems/stair/stair-opening-system.d.ts.map +1 -1
- package/dist/systems/stair/stair-opening-system.js +32 -4
- package/dist/systems/stair/stair-rise.d.ts +22 -0
- package/dist/systems/stair/stair-rise.d.ts.map +1 -0
- package/dist/systems/stair/stair-rise.js +79 -0
- package/dist/systems/wall/wall-curve.d.ts +10 -0
- package/dist/systems/wall/wall-curve.d.ts.map +1 -1
- package/dist/systems/wall/wall-curve.js +1 -1
- package/dist/systems/wall/wall-mitering.js +6 -6
- package/dist/systems/wall/wall-top.d.ts +40 -0
- package/dist/systems/wall/wall-top.d.ts.map +1 -0
- package/dist/systems/wall/wall-top.js +46 -0
- package/dist/utils/clone-scene-graph.d.ts.map +1 -1
- package/dist/utils/clone-scene-graph.js +34 -3
- package/dist/utils/heal-scene-graph.d.ts +1 -1
- package/dist/utils/heal-scene-graph.d.ts.map +1 -1
- package/dist/utils/heal-scene-graph.js +25 -9
- package/dist/validation/validate-build-json.d.ts +2 -0
- package/dist/validation/validate-build-json.d.ts.map +1 -1
- package/dist/validation/validate-build-json.js +59 -3
- package/package.json +2 -2
- package/dist/hooks/scene-registry/scene-registry.test.d.ts +0 -2
- package/dist/hooks/scene-registry/scene-registry.test.d.ts.map +0 -1
- package/dist/hooks/scene-registry/scene-registry.test.js +0 -26
- package/dist/hooks/spatial-grid/floor-placed-elevation.test.d.ts +0 -2
- package/dist/hooks/spatial-grid/floor-placed-elevation.test.d.ts.map +0 -1
- package/dist/hooks/spatial-grid/floor-placed-elevation.test.js +0 -366
- package/dist/hooks/spatial-grid/wall-slab-overlap.test.d.ts +0 -2
- package/dist/hooks/spatial-grid/wall-slab-overlap.test.d.ts.map +0 -1
- package/dist/hooks/spatial-grid/wall-slab-overlap.test.js +0 -363
- package/dist/lib/measurement-geometry.test.d.ts +0 -2
- package/dist/lib/measurement-geometry.test.d.ts.map +0 -1
- package/dist/lib/measurement-geometry.test.js +0 -102
- package/dist/lib/slab-polygon.test.d.ts +0 -2
- package/dist/lib/slab-polygon.test.d.ts.map +0 -1
- package/dist/lib/slab-polygon.test.js +0 -635
- package/dist/lib/space-detection-pause.test.d.ts +0 -2
- package/dist/lib/space-detection-pause.test.d.ts.map +0 -1
- package/dist/lib/space-detection-pause.test.js +0 -42
- package/dist/lib/space-detection.test.d.ts +0 -2
- package/dist/lib/space-detection.test.d.ts.map +0 -1
- package/dist/lib/space-detection.test.js +0 -376
- package/dist/lib/zone-quantities.test.d.ts +0 -2
- package/dist/lib/zone-quantities.test.d.ts.map +0 -1
- package/dist/lib/zone-quantities.test.js +0 -82
- package/dist/registry/registry.test.d.ts +0 -2
- package/dist/registry/registry.test.d.ts.map +0 -1
- package/dist/registry/registry.test.js +0 -196
- package/dist/registry/relations-resolver.test.d.ts +0 -2
- package/dist/registry/relations-resolver.test.d.ts.map +0 -1
- package/dist/registry/relations-resolver.test.js +0 -183
- package/dist/registry/scene-api.test.d.ts +0 -2
- package/dist/registry/scene-api.test.d.ts.map +0 -1
- package/dist/registry/scene-api.test.js +0 -183
- package/dist/registry/subtree.test.d.ts +0 -2
- package/dist/registry/subtree.test.d.ts.map +0 -1
- package/dist/registry/subtree.test.js +0 -163
- package/dist/schema/asset-url.test.d.ts +0 -2
- package/dist/schema/asset-url.test.d.ts.map +0 -1
- package/dist/schema/asset-url.test.js +0 -134
- package/dist/schema/material.test.d.ts +0 -2
- package/dist/schema/material.test.d.ts.map +0 -1
- package/dist/schema/material.test.js +0 -43
- package/dist/schema/nodes/measurement.test.d.ts +0 -2
- package/dist/schema/nodes/measurement.test.d.ts.map +0 -1
- package/dist/schema/nodes/measurement.test.js +0 -139
- package/dist/schema/nodes/ridge-vent-defaults.test.d.ts +0 -2
- package/dist/schema/nodes/ridge-vent-defaults.test.d.ts.map +0 -1
- package/dist/schema/nodes/ridge-vent-defaults.test.js +0 -205
- package/dist/schema/nodes/roof-segment-shape.test.d.ts +0 -2
- package/dist/schema/nodes/roof-segment-shape.test.d.ts.map +0 -1
- package/dist/schema/nodes/roof-segment-shape.test.js +0 -175
- package/dist/schema/nodes/roof-segment-surface.test.d.ts +0 -2
- package/dist/schema/nodes/roof-segment-surface.test.d.ts.map +0 -1
- package/dist/schema/nodes/roof-segment-surface.test.js +0 -48
- package/dist/schema/nodes/roof-segment-trim.test.d.ts +0 -2
- package/dist/schema/nodes/roof-segment-trim.test.d.ts.map +0 -1
- package/dist/schema/nodes/roof-segment-trim.test.js +0 -107
- package/dist/schema/nodes/roof-segment-walls.test.d.ts +0 -2
- package/dist/schema/nodes/roof-segment-walls.test.d.ts.map +0 -1
- package/dist/schema/nodes/roof-segment-walls.test.js +0 -92
- package/dist/schema/nodes/wall.test.d.ts +0 -2
- package/dist/schema/nodes/wall.test.d.ts.map +0 -1
- package/dist/schema/nodes/wall.test.js +0 -208
- package/dist/services/alignment-anchors.test.d.ts +0 -2
- package/dist/services/alignment-anchors.test.d.ts.map +0 -1
- package/dist/services/alignment-anchors.test.js +0 -383
- package/dist/services/alignment.test.d.ts +0 -2
- package/dist/services/alignment.test.d.ts.map +0 -1
- package/dist/services/alignment.test.js +0 -92
- package/dist/services/drag-session.test.d.ts +0 -2
- package/dist/services/drag-session.test.d.ts.map +0 -1
- package/dist/services/drag-session.test.js +0 -219
- package/dist/services/hosting.test.d.ts +0 -2
- package/dist/services/hosting.test.d.ts.map +0 -1
- package/dist/services/hosting.test.js +0 -230
- package/dist/services/movement.test.d.ts +0 -2
- package/dist/services/movement.test.d.ts.map +0 -1
- package/dist/services/movement.test.js +0 -133
- package/dist/services/opening-guides.test.d.ts +0 -2
- package/dist/services/opening-guides.test.d.ts.map +0 -1
- package/dist/services/opening-guides.test.js +0 -208
- package/dist/services/port-connectivity.test.d.ts +0 -2
- package/dist/services/port-connectivity.test.d.ts.map +0 -1
- package/dist/services/port-connectivity.test.js +0 -297
- package/dist/services/riser-diagram.test.d.ts +0 -2
- package/dist/services/riser-diagram.test.d.ts.map +0 -1
- package/dist/services/riser-diagram.test.js +0 -66
- package/dist/services/single-undo-dance.test.d.ts +0 -2
- package/dist/services/single-undo-dance.test.d.ts.map +0 -1
- package/dist/services/single-undo-dance.test.js +0 -210
- package/dist/services/snap.test.d.ts +0 -2
- package/dist/services/snap.test.d.ts.map +0 -1
- package/dist/services/snap.test.js +0 -137
- package/dist/services/system-graph.test.d.ts +0 -2
- package/dist/services/system-graph.test.d.ts.map +0 -1
- package/dist/services/system-graph.test.js +0 -138
- package/dist/services/validate-dwv.test.d.ts +0 -2
- package/dist/services/validate-dwv.test.d.ts.map +0 -1
- package/dist/services/validate-dwv.test.js +0 -109
- package/dist/store/actions/node-mutation-sanitize.test.d.ts +0 -2
- package/dist/store/actions/node-mutation-sanitize.test.d.ts.map +0 -1
- package/dist/store/actions/node-mutation-sanitize.test.js +0 -147
- package/dist/store/actions/reparent.test.d.ts +0 -2
- package/dist/store/actions/reparent.test.d.ts.map +0 -1
- package/dist/store/actions/reparent.test.js +0 -212
- package/dist/store/actions/ridge-vent-update.test.d.ts +0 -2
- package/dist/store/actions/ridge-vent-update.test.d.ts.map +0 -1
- package/dist/store/actions/ridge-vent-update.test.js +0 -264
- package/dist/store/use-scene-dirty-tracking.test.d.ts +0 -2
- package/dist/store/use-scene-dirty-tracking.test.d.ts.map +0 -1
- package/dist/store/use-scene-dirty-tracking.test.js +0 -68
- package/dist/store/use-scene-elevator-migration.test.d.ts +0 -2
- package/dist/store/use-scene-elevator-migration.test.d.ts.map +0 -1
- package/dist/store/use-scene-elevator-migration.test.js +0 -109
- package/dist/store/use-scene-measurement-roundtrip.test.d.ts +0 -2
- package/dist/store/use-scene-measurement-roundtrip.test.d.ts.map +0 -1
- package/dist/store/use-scene-measurement-roundtrip.test.js +0 -97
- package/dist/store/use-scene-plugins.test.d.ts +0 -2
- package/dist/store/use-scene-plugins.test.d.ts.map +0 -1
- package/dist/store/use-scene-plugins.test.js +0 -51
- package/dist/store/use-scene-wall-slot-migration.test.d.ts +0 -2
- package/dist/store/use-scene-wall-slot-migration.test.d.ts.map +0 -1
- package/dist/store/use-scene-wall-slot-migration.test.js +0 -210
- package/dist/store/use-scene-window-migration.test.d.ts +0 -2
- package/dist/store/use-scene-window-migration.test.d.ts.map +0 -1
- package/dist/store/use-scene-window-migration.test.js +0 -85
- package/dist/systems/elevator/elevator-opening-sync.test.d.ts +0 -2
- package/dist/systems/elevator/elevator-opening-sync.test.d.ts.map +0 -1
- package/dist/systems/elevator/elevator-opening-sync.test.js +0 -146
- package/dist/systems/elevator/elevator-runtime.test.d.ts +0 -2
- package/dist/systems/elevator/elevator-runtime.test.d.ts.map +0 -1
- package/dist/systems/elevator/elevator-runtime.test.js +0 -64
- package/dist/systems/fence/fence-spline.test.d.ts +0 -2
- package/dist/systems/fence/fence-spline.test.d.ts.map +0 -1
- package/dist/systems/fence/fence-spline.test.js +0 -136
- package/dist/systems/stair/stair-opening-preview.test.d.ts +0 -2
- package/dist/systems/stair/stair-opening-preview.test.d.ts.map +0 -1
- package/dist/systems/stair/stair-opening-preview.test.js +0 -80
- package/dist/systems/stair/stair-opening-sync.test.d.ts +0 -2
- package/dist/systems/stair/stair-opening-sync.test.d.ts.map +0 -1
- package/dist/systems/stair/stair-opening-sync.test.js +0 -485
- package/dist/systems/wall/wall-mitering.test.d.ts +0 -2
- package/dist/systems/wall/wall-mitering.test.d.ts.map +0 -1
- package/dist/systems/wall/wall-mitering.test.js +0 -63
- package/dist/utils/clone-scene-graph.test.d.ts +0 -2
- package/dist/utils/clone-scene-graph.test.d.ts.map +0 -1
- package/dist/utils/clone-scene-graph.test.js +0 -62
- package/dist/utils/heal-scene-graph.test.d.ts +0 -2
- package/dist/utils/heal-scene-graph.test.d.ts.map +0 -1
- package/dist/utils/heal-scene-graph.test.js +0 -88
|
@@ -1,363 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'bun:test';
|
|
2
|
-
import { SlabNode, WallNode } from '../../schema';
|
|
3
|
-
import { computeWallSlabElevation, computeWallSlabSupport, wallOverlapsPolygon, } from './spatial-grid-manager';
|
|
4
|
-
// 4×4 square slab, like an auto-slab derived from a room's wall centerlines.
|
|
5
|
-
const SLAB = [
|
|
6
|
-
[0, 0],
|
|
7
|
-
[4, 0],
|
|
8
|
-
[4, 4],
|
|
9
|
-
[0, 4],
|
|
10
|
-
];
|
|
11
|
-
const wall = (start, end, curveOffset = 0) => ({
|
|
12
|
-
start,
|
|
13
|
-
end,
|
|
14
|
-
curveOffset,
|
|
15
|
-
thickness: 0.1,
|
|
16
|
-
});
|
|
17
|
-
describe('wallOverlapsPolygon', () => {
|
|
18
|
-
it('excludes perpendicular walls butting into the slab, on every side', () => {
|
|
19
|
-
// Regression: side-dependent ray-cast tie-breaking used to push some of
|
|
20
|
-
// these walls (depending on which slab edge they touched) but not others.
|
|
21
|
-
expect(wallOverlapsPolygon(wall([2, 4], [2, 7]), SLAB)).toBe(false); // top
|
|
22
|
-
expect(wallOverlapsPolygon(wall([2, 0], [2, -3]), SLAB)).toBe(false); // bottom
|
|
23
|
-
expect(wallOverlapsPolygon(wall([0, 2], [-3, 2]), SLAB)).toBe(false); // left
|
|
24
|
-
expect(wallOverlapsPolygon(wall([4, 2], [7, 2]), SLAB)).toBe(false); // right
|
|
25
|
-
// Reversed direction (endpoint order must not matter)
|
|
26
|
-
expect(wallOverlapsPolygon(wall([2, 7], [2, 4]), SLAB)).toBe(false);
|
|
27
|
-
expect(wallOverlapsPolygon(wall([-3, 2], [0, 2]), SLAB)).toBe(false);
|
|
28
|
-
});
|
|
29
|
-
it('includes walls lying on the slab boundary, on every side', () => {
|
|
30
|
-
expect(wallOverlapsPolygon(wall([0, 0], [4, 0]), SLAB)).toBe(true); // bottom
|
|
31
|
-
expect(wallOverlapsPolygon(wall([4, 0], [4, 4]), SLAB)).toBe(true); // right
|
|
32
|
-
expect(wallOverlapsPolygon(wall([4, 4], [0, 4]), SLAB)).toBe(true); // top
|
|
33
|
-
expect(wallOverlapsPolygon(wall([0, 4], [0, 0]), SLAB)).toBe(true); // left
|
|
34
|
-
// Partial edge coverage still counts
|
|
35
|
-
expect(wallOverlapsPolygon(wall([1, 0], [3, 0]), SLAB)).toBe(true);
|
|
36
|
-
});
|
|
37
|
-
it('includes a wall running past the slab if enough of it lies on the edge', () => {
|
|
38
|
-
// 4m on the edge + 6m beyond: whole wall follows the slab.
|
|
39
|
-
expect(wallOverlapsPolygon(wall([0, 0], [10, 0]), SLAB)).toBe(true);
|
|
40
|
-
});
|
|
41
|
-
it('excludes corner-only contact', () => {
|
|
42
|
-
expect(wallOverlapsPolygon(wall([4, 4], [6, 6]), SLAB)).toBe(false);
|
|
43
|
-
expect(wallOverlapsPolygon(wall([0, 0], [-2, -2]), SLAB)).toBe(false);
|
|
44
|
-
});
|
|
45
|
-
it('includes walls inside or crossing through the slab', () => {
|
|
46
|
-
expect(wallOverlapsPolygon(wall([1, 1], [3, 3]), SLAB)).toBe(true); // fully inside
|
|
47
|
-
expect(wallOverlapsPolygon(wall([-1, 2], [5, 2]), SLAB)).toBe(true); // crossing
|
|
48
|
-
});
|
|
49
|
-
it('uses wall thickness: a face grazing the slab counts, clear separation does not', () => {
|
|
50
|
-
// Centerline 4cm outside, body (half thickness 5cm) reaches the slab.
|
|
51
|
-
expect(wallOverlapsPolygon(wall([0, -0.04], [4, -0.04]), SLAB)).toBe(true);
|
|
52
|
-
// Centerline 1m outside: no contact.
|
|
53
|
-
expect(wallOverlapsPolygon(wall([0, -1], [4, -1]), SLAB)).toBe(false);
|
|
54
|
-
});
|
|
55
|
-
it('handles curved walls by their sampled body', () => {
|
|
56
|
-
// Chord below the slab, bowing into the slab interior (negative offset
|
|
57
|
-
// bows toward +z here).
|
|
58
|
-
expect(wallOverlapsPolygon(wall([0, -0.5], [4, -0.5], -1), SLAB)).toBe(true);
|
|
59
|
-
// Same chord bowing away from the slab: never touches it.
|
|
60
|
-
expect(wallOverlapsPolygon(wall([0, -0.5], [4, -0.5], 1), SLAB)).toBe(false);
|
|
61
|
-
});
|
|
62
|
-
it('supports the legacy (start, end, polygon) call shape', () => {
|
|
63
|
-
expect(wallOverlapsPolygon([1, 1], [3, 3], SLAB)).toBe(true);
|
|
64
|
-
expect(wallOverlapsPolygon([2, 4], [2, 7], SLAB)).toBe(false);
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
describe('computeWallSlabElevation', () => {
|
|
68
|
-
const parseWall = (start, end, thickness = 0.1) => WallNode.parse({ start, end, thickness });
|
|
69
|
-
it('lifts a wall standing on an auto slab stored at the centerlines', () => {
|
|
70
|
-
const walls = [
|
|
71
|
-
parseWall([0, 0], [4, 0]),
|
|
72
|
-
parseWall([4, 0], [4, 4]),
|
|
73
|
-
parseWall([4, 4], [0, 4]),
|
|
74
|
-
parseWall([0, 4], [0, 0]),
|
|
75
|
-
];
|
|
76
|
-
const slab = SlabNode.parse({ polygon: SLAB, elevation: 0.1 });
|
|
77
|
-
const bottom = walls[0];
|
|
78
|
-
expect(computeWallSlabElevation({ start: bottom.start, end: bottom.end, thickness: bottom.thickness }, [slab], walls)).toBeCloseTo(0.1);
|
|
79
|
-
});
|
|
80
|
-
it('lifts a wall whose body a legacy stored polygon falls short of', () => {
|
|
81
|
-
// Legacy hand-adjusted slab: edges 6cm inside the wall centerlines —
|
|
82
|
-
// 1cm short of even the inner faces, so the STORED polygon never
|
|
83
|
-
// touches the wall body and the old stored-polygon test returned 0.
|
|
84
|
-
// The rendered footprint band-adopts the edges out to the outer
|
|
85
|
-
// faces, so the wall stands on the slab.
|
|
86
|
-
const walls = [
|
|
87
|
-
parseWall([0, 0], [4, 0]),
|
|
88
|
-
parseWall([4, 0], [4, 4]),
|
|
89
|
-
parseWall([4, 4], [0, 4]),
|
|
90
|
-
parseWall([0, 4], [0, 0]),
|
|
91
|
-
];
|
|
92
|
-
const slab = SlabNode.parse({
|
|
93
|
-
polygon: [
|
|
94
|
-
[0.06, 0.06],
|
|
95
|
-
[3.94, 0.06],
|
|
96
|
-
[3.94, 3.94],
|
|
97
|
-
[0.06, 3.94],
|
|
98
|
-
],
|
|
99
|
-
elevation: 0.1,
|
|
100
|
-
});
|
|
101
|
-
const bottom = walls[0];
|
|
102
|
-
expect(computeWallSlabElevation({ start: bottom.start, end: bottom.end, thickness: bottom.thickness }, [slab], walls)).toBeCloseTo(0.1);
|
|
103
|
-
});
|
|
104
|
-
it('does not lift a wall clearly off the slab', () => {
|
|
105
|
-
const walls = [parseWall([0, 0], [4, 0])];
|
|
106
|
-
const slab = SlabNode.parse({ polygon: SLAB, elevation: 0.1 });
|
|
107
|
-
expect(computeWallSlabElevation({ start: [0, -1], end: [4, -1], thickness: 0.1 }, [slab], walls)).toBe(0);
|
|
108
|
-
});
|
|
109
|
-
it('ignores a slab when the wall runs entirely inside a hole', () => {
|
|
110
|
-
const walls = [parseWall([1, 2], [3, 2])];
|
|
111
|
-
const slab = SlabNode.parse({
|
|
112
|
-
polygon: SLAB,
|
|
113
|
-
elevation: 0.1,
|
|
114
|
-
holes: [
|
|
115
|
-
[
|
|
116
|
-
[0.5, 0.5],
|
|
117
|
-
[3.5, 0.5],
|
|
118
|
-
[3.5, 3.5],
|
|
119
|
-
[0.5, 3.5],
|
|
120
|
-
],
|
|
121
|
-
],
|
|
122
|
-
});
|
|
123
|
-
expect(computeWallSlabElevation({ start: [1, 2], end: [3, 2], thickness: 0.1 }, [slab], walls)).toBe(0);
|
|
124
|
-
});
|
|
125
|
-
it('keeps a wall on the lower slab when a higher slab only reaches one endpoint', () => {
|
|
126
|
-
// The floating-wall bug: a wall standing on the low room whose far
|
|
127
|
-
// endpoint pokes 0.2m onto a raised platform must NOT lift wholesale.
|
|
128
|
-
const low = SlabNode.parse({ polygon: SLAB, elevation: 0.05 });
|
|
129
|
-
const high = SlabNode.parse({
|
|
130
|
-
polygon: [
|
|
131
|
-
[4, 0],
|
|
132
|
-
[8, 0],
|
|
133
|
-
[8, 4],
|
|
134
|
-
[4, 4],
|
|
135
|
-
],
|
|
136
|
-
elevation: 0.6,
|
|
137
|
-
});
|
|
138
|
-
expect(computeWallSlabElevation({ start: [0.5, 2], end: [4.2, 2], thickness: 0.1 }, [low, high], [])).toBeCloseTo(0.05);
|
|
139
|
-
});
|
|
140
|
-
it('keeps a curved wall on the lower slab when a higher slab only reaches its end', () => {
|
|
141
|
-
const low = SlabNode.parse({ polygon: SLAB, elevation: 0.05 });
|
|
142
|
-
const high = SlabNode.parse({
|
|
143
|
-
polygon: [
|
|
144
|
-
[4, 0],
|
|
145
|
-
[8, 0],
|
|
146
|
-
[8, 4],
|
|
147
|
-
[4, 4],
|
|
148
|
-
],
|
|
149
|
-
elevation: 0.6,
|
|
150
|
-
});
|
|
151
|
-
expect(computeWallSlabElevation({ start: [0.5, 2], end: [4.2, 2], curveOffset: 0.5, thickness: 0.1 }, [low, high], [])).toBeCloseTo(0.05);
|
|
152
|
-
});
|
|
153
|
-
it('lifts a wall standing fully on a raised platform', () => {
|
|
154
|
-
const platform = SlabNode.parse({ polygon: SLAB, elevation: 0.6 });
|
|
155
|
-
expect(computeWallSlabElevation({ start: [1, 2], end: [3, 2], thickness: 0.1 }, [platform], [])).toBeCloseTo(0.6);
|
|
156
|
-
});
|
|
157
|
-
it('lifts a wall half on a raised platform, half in the air, onto the platform', () => {
|
|
158
|
-
// No elevation reaches majority (only 39% supported), so the
|
|
159
|
-
// best-covered slab wins — the only alternative would bury the
|
|
160
|
-
// supported half inside the platform.
|
|
161
|
-
const platform = SlabNode.parse({ polygon: SLAB, elevation: 0.6 });
|
|
162
|
-
expect(computeWallSlabElevation({ start: [0.1, 2], end: [10.1, 2], thickness: 0.1 }, [platform], [])).toBeCloseTo(0.6);
|
|
163
|
-
});
|
|
164
|
-
it('pools same-elevation slabs so a shared wall follows their common level', () => {
|
|
165
|
-
// Rooms A and B at the same elevation each cover exactly half the
|
|
166
|
-
// wall (interior edges seam at the x=2 midline); a raised slab covers
|
|
167
|
-
// just under half. Pooled, the common level covers 100% and must
|
|
168
|
-
// win — without pooling the raised slab's 0.4975 would beat either
|
|
169
|
-
// half alone.
|
|
170
|
-
const roomA = SlabNode.parse({
|
|
171
|
-
polygon: [
|
|
172
|
-
[0, 0],
|
|
173
|
-
[2, 0],
|
|
174
|
-
[2, 4],
|
|
175
|
-
[0, 4],
|
|
176
|
-
],
|
|
177
|
-
elevation: 0.1,
|
|
178
|
-
});
|
|
179
|
-
const roomB = SlabNode.parse({
|
|
180
|
-
polygon: [
|
|
181
|
-
[2, 0],
|
|
182
|
-
[4, 0],
|
|
183
|
-
[4, 4],
|
|
184
|
-
[2, 4],
|
|
185
|
-
],
|
|
186
|
-
elevation: 0.1,
|
|
187
|
-
});
|
|
188
|
-
const raised = SlabNode.parse({
|
|
189
|
-
polygon: [
|
|
190
|
-
[1.0, 1],
|
|
191
|
-
[2.99, 1],
|
|
192
|
-
[2.99, 3],
|
|
193
|
-
[1.0, 3],
|
|
194
|
-
],
|
|
195
|
-
elevation: 0.6,
|
|
196
|
-
});
|
|
197
|
-
expect(computeWallSlabElevation({ start: [0, 2], end: [4, 2], thickness: 0.1 }, [roomA, roomB, raised], [])).toBeCloseTo(0.1);
|
|
198
|
-
});
|
|
199
|
-
it('prefers the higher of two majority-supporting slabs (platform stacked on a floor)', () => {
|
|
200
|
-
const floor = SlabNode.parse({
|
|
201
|
-
polygon: [
|
|
202
|
-
[0, 0],
|
|
203
|
-
[8, 0],
|
|
204
|
-
[8, 4],
|
|
205
|
-
[0, 4],
|
|
206
|
-
],
|
|
207
|
-
elevation: 0.05,
|
|
208
|
-
});
|
|
209
|
-
const platform = SlabNode.parse({
|
|
210
|
-
polygon: [
|
|
211
|
-
[0, 0],
|
|
212
|
-
[5, 0],
|
|
213
|
-
[5, 4],
|
|
214
|
-
[0, 4],
|
|
215
|
-
],
|
|
216
|
-
elevation: 0.6,
|
|
217
|
-
});
|
|
218
|
-
// Wall 6m long: floor covers all of it, platform covers ~2/3 — both
|
|
219
|
-
// majorities, and the wall physically rests on the platform.
|
|
220
|
-
expect(computeWallSlabElevation({ start: [1, 2], end: [7, 2], thickness: 0.1 }, [floor, platform], [])).toBeCloseTo(0.6);
|
|
221
|
-
});
|
|
222
|
-
it('keeps a wall pushed up on a raised platform above a coincident floor', () => {
|
|
223
|
-
const floor = SlabNode.parse({ polygon: SLAB, elevation: 0.05 });
|
|
224
|
-
const platform = SlabNode.parse({ polygon: SLAB, elevation: 0.6 });
|
|
225
|
-
expect(computeWallSlabSupport({ start: [1, 2], end: [3, 2], thickness: 0.1 }, [floor, platform], [])).toEqual({
|
|
226
|
-
elevation: 0.6,
|
|
227
|
-
baseElevation: 0.6,
|
|
228
|
-
baseSegments: [{ start: 0, end: 1, elevation: 0.6 }],
|
|
229
|
-
});
|
|
230
|
-
});
|
|
231
|
-
it('fills down only when a lower support is exposed beyond a partial platform', () => {
|
|
232
|
-
const floor = SlabNode.parse({ polygon: SLAB, elevation: 0.05 });
|
|
233
|
-
const platform = SlabNode.parse({
|
|
234
|
-
polygon: [
|
|
235
|
-
[0, 0],
|
|
236
|
-
[2.5, 0],
|
|
237
|
-
[2.5, 4],
|
|
238
|
-
[0, 4],
|
|
239
|
-
],
|
|
240
|
-
elevation: 0.6,
|
|
241
|
-
});
|
|
242
|
-
expect(computeWallSlabSupport({ start: [0.5, 2], end: [3.5, 2], thickness: 0.1 }, [floor, platform], [])).toEqual({
|
|
243
|
-
elevation: 0.6,
|
|
244
|
-
baseElevation: 0.05,
|
|
245
|
-
baseSegments: [
|
|
246
|
-
{ start: 0, end: 2 / 3, elevation: 0.6 },
|
|
247
|
-
{ start: 2 / 3, end: 1, elevation: 0.05 },
|
|
248
|
-
],
|
|
249
|
-
});
|
|
250
|
-
});
|
|
251
|
-
it('keeps a shared wall on the higher slab that carries the full wall band', () => {
|
|
252
|
-
const sharedWall = parseWall([4, 0], [4, 4]);
|
|
253
|
-
const low = SlabNode.parse({ polygon: SLAB, elevation: 0.05 });
|
|
254
|
-
const high = SlabNode.parse({
|
|
255
|
-
polygon: [
|
|
256
|
-
[4, 0],
|
|
257
|
-
[8, 0],
|
|
258
|
-
[8, 4],
|
|
259
|
-
[4, 4],
|
|
260
|
-
],
|
|
261
|
-
elevation: 0.6,
|
|
262
|
-
});
|
|
263
|
-
expect(computeWallSlabSupport({ start: sharedWall.start, end: sharedWall.end, thickness: sharedWall.thickness }, [low, high], [sharedWall])).toEqual({
|
|
264
|
-
elevation: 0.6,
|
|
265
|
-
baseElevation: 0.6,
|
|
266
|
-
baseSegments: [{ start: 0, end: 1, elevation: 0.6 }],
|
|
267
|
-
});
|
|
268
|
-
});
|
|
269
|
-
it('profiles an offset-room wall as high-only, shared, then low-only', () => {
|
|
270
|
-
const sharedWall = parseWall([4, 0], [4, 4.5]);
|
|
271
|
-
const walls = [
|
|
272
|
-
parseWall([0, 0], [4, 0]),
|
|
273
|
-
parseWall([0, 3], [0, 0]),
|
|
274
|
-
parseWall([0, 3], [4, 3]),
|
|
275
|
-
sharedWall,
|
|
276
|
-
parseWall([4, 1.5], [8, 1.5]),
|
|
277
|
-
parseWall([8, 1.5], [8, 4.5]),
|
|
278
|
-
parseWall([8, 4.5], [4, 4.5]),
|
|
279
|
-
];
|
|
280
|
-
const high = SlabNode.parse({
|
|
281
|
-
polygon: [
|
|
282
|
-
[0, 0],
|
|
283
|
-
[4, 0],
|
|
284
|
-
[4, 3],
|
|
285
|
-
[0, 3],
|
|
286
|
-
],
|
|
287
|
-
elevation: 0.6,
|
|
288
|
-
});
|
|
289
|
-
const low = SlabNode.parse({
|
|
290
|
-
polygon: [
|
|
291
|
-
[4, 1.5],
|
|
292
|
-
[8, 1.5],
|
|
293
|
-
[8, 4.5],
|
|
294
|
-
[4, 4.5],
|
|
295
|
-
],
|
|
296
|
-
elevation: 0.05,
|
|
297
|
-
});
|
|
298
|
-
expect(computeWallSlabSupport({ start: sharedWall.start, end: sharedWall.end, thickness: sharedWall.thickness }, [high, low], walls)).toEqual({
|
|
299
|
-
elevation: 0.6,
|
|
300
|
-
baseElevation: 0.05,
|
|
301
|
-
baseSegments: [
|
|
302
|
-
{ start: 0, end: 3.05 / 4.5, elevation: 0.6 },
|
|
303
|
-
{ start: 3.05 / 4.5, end: 1, elevation: 0.05 },
|
|
304
|
-
],
|
|
305
|
-
});
|
|
306
|
-
});
|
|
307
|
-
it('lifts a tiny stub wall standing fully on a slab', () => {
|
|
308
|
-
const slab = SlabNode.parse({ polygon: SLAB, elevation: 0.3 });
|
|
309
|
-
expect(computeWallSlabElevation({ start: [2, 2], end: [2.08, 2], thickness: 0.1 }, [slab], [])).toBeCloseTo(0.3);
|
|
310
|
-
});
|
|
311
|
-
it('does not lift a wall whose run over a higher slab is mostly inside a hole', () => {
|
|
312
|
-
const low = SlabNode.parse({
|
|
313
|
-
polygon: [
|
|
314
|
-
[0, 0],
|
|
315
|
-
[8, 0],
|
|
316
|
-
[8, 4],
|
|
317
|
-
[0, 4],
|
|
318
|
-
],
|
|
319
|
-
elevation: 0.05,
|
|
320
|
-
});
|
|
321
|
-
const high = SlabNode.parse({
|
|
322
|
-
polygon: [
|
|
323
|
-
[0, 0],
|
|
324
|
-
[8, 0],
|
|
325
|
-
[8, 4],
|
|
326
|
-
[0, 4],
|
|
327
|
-
],
|
|
328
|
-
elevation: 0.6,
|
|
329
|
-
holes: [
|
|
330
|
-
[
|
|
331
|
-
[0.5, 0],
|
|
332
|
-
[8, 0],
|
|
333
|
-
[8, 4],
|
|
334
|
-
[0.5, 4],
|
|
335
|
-
],
|
|
336
|
-
],
|
|
337
|
-
});
|
|
338
|
-
// Net high support is only x ∈ [0, 0.5]; the low slab carries the wall.
|
|
339
|
-
expect(computeWallSlabElevation({ start: [0, 2], end: [8, 2], thickness: 0.1 }, [low, high], [])).toBeCloseTo(0.05);
|
|
340
|
-
});
|
|
341
|
-
it('keeps support for a wall running along a hole rim', () => {
|
|
342
|
-
// Hole boundaries count as solid: the wall ringing a stairwell sits
|
|
343
|
-
// on the rim, its outer face on solid slab.
|
|
344
|
-
const slab = SlabNode.parse({
|
|
345
|
-
polygon: [
|
|
346
|
-
[0, 0],
|
|
347
|
-
[6, 0],
|
|
348
|
-
[6, 6],
|
|
349
|
-
[0, 6],
|
|
350
|
-
],
|
|
351
|
-
elevation: 0.4,
|
|
352
|
-
holes: [
|
|
353
|
-
[
|
|
354
|
-
[2, 2],
|
|
355
|
-
[4, 2],
|
|
356
|
-
[4, 4],
|
|
357
|
-
[2, 4],
|
|
358
|
-
],
|
|
359
|
-
],
|
|
360
|
-
});
|
|
361
|
-
expect(computeWallSlabElevation({ start: [2, 2], end: [4, 2], thickness: 0.1 }, [slab], [])).toBeCloseTo(0.4);
|
|
362
|
-
});
|
|
363
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"measurement-geometry.test.d.ts","sourceRoot":"","sources":["../../src/lib/measurement-geometry.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from 'bun:test';
|
|
2
|
-
import { areMeasurementPointsCoplanar, closestMeasurementFeatureBinding, measurementAngle, measurementArea, measurementAreaVector, measurementCentroid, measurementDistance, measurementNormal, measurementPerimeter, measurementPrismVolume, } from './measurement-geometry';
|
|
3
|
-
const expectPointCloseTo = (actual, expected) => {
|
|
4
|
-
expect(actual).not.toBeNull();
|
|
5
|
-
for (let index = 0; index < 3; index++) {
|
|
6
|
-
expect(actual[index]).toBeCloseTo(expected[index]);
|
|
7
|
-
}
|
|
8
|
-
};
|
|
9
|
-
describe('measurement geometry', () => {
|
|
10
|
-
test('measures full 3D distance', () => {
|
|
11
|
-
expect(measurementDistance([1, 2, 3], [4, 6, 15])).toBe(13);
|
|
12
|
-
});
|
|
13
|
-
test('measures the smaller 3D angle and a closed perimeter', () => {
|
|
14
|
-
expect(measurementAngle([1, 0, 0], [0, 0, 0], [0, 1, 0])).toBeCloseTo(Math.PI / 2);
|
|
15
|
-
expect(measurementAngle([0, 0, 0], [0, 0, 0], [1, 0, 0])).toBe(0);
|
|
16
|
-
expect(measurementPerimeter([
|
|
17
|
-
[0, 0, 0],
|
|
18
|
-
[3, 0, 0],
|
|
19
|
-
[3, 0, 4],
|
|
20
|
-
])).toBe(12);
|
|
21
|
-
});
|
|
22
|
-
test('matches the closest semantic feature with a normalized path position', () => {
|
|
23
|
-
const features = [
|
|
24
|
-
{
|
|
25
|
-
id: 'boundary',
|
|
26
|
-
label: 'Boundary',
|
|
27
|
-
snapKind: 'edge',
|
|
28
|
-
geometry: {
|
|
29
|
-
kind: 'polygon',
|
|
30
|
-
points: [
|
|
31
|
-
[0, 0, 0],
|
|
32
|
-
[2, 0, 0],
|
|
33
|
-
[2, 0, 2],
|
|
34
|
-
[0, 0, 2],
|
|
35
|
-
],
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
];
|
|
39
|
-
const match = closestMeasurementFeatureBinding(features, [1.9, 0, 1], 0.2);
|
|
40
|
-
expect(match?.featureId).toBe('boundary');
|
|
41
|
-
expect(match?.point).toEqual([2, 0, 1]);
|
|
42
|
-
expect(match?.parameters?.t).toBeCloseTo(0.375);
|
|
43
|
-
expect(match?.distance).toBeCloseTo(0.1);
|
|
44
|
-
});
|
|
45
|
-
test('computes a Newell area vector, area, and winding-aware normal', () => {
|
|
46
|
-
const base = [
|
|
47
|
-
[0, 0, 0],
|
|
48
|
-
[2, 0, 0],
|
|
49
|
-
[2, 1, 1],
|
|
50
|
-
[0, 1, 1],
|
|
51
|
-
];
|
|
52
|
-
expectPointCloseTo(measurementAreaVector(base), [0, -2, 2]);
|
|
53
|
-
expect(measurementArea(base)).toBeCloseTo(2 * Math.sqrt(2));
|
|
54
|
-
expectPointCloseTo(measurementNormal(base), [0, -Math.SQRT1_2, Math.SQRT1_2]);
|
|
55
|
-
expectPointCloseTo(measurementNormal([...base].reverse()), [0, Math.SQRT1_2, -Math.SQRT1_2]);
|
|
56
|
-
});
|
|
57
|
-
test('checks coplanarity against the Newell normal', () => {
|
|
58
|
-
const base = [
|
|
59
|
-
[0, 0, 0],
|
|
60
|
-
[2, 0, 0],
|
|
61
|
-
[2, 1, 1],
|
|
62
|
-
[0, 1, 1],
|
|
63
|
-
];
|
|
64
|
-
expect(areMeasurementPointsCoplanar(base)).toBe(true);
|
|
65
|
-
expect(areMeasurementPointsCoplanar([...base, [1, 0.5, 0.51]])).toBe(false);
|
|
66
|
-
expect(areMeasurementPointsCoplanar([
|
|
67
|
-
[0, 0, 0],
|
|
68
|
-
[1, 0, 0],
|
|
69
|
-
[2, 0, 0],
|
|
70
|
-
])).toBe(false);
|
|
71
|
-
});
|
|
72
|
-
test('computes the area-weighted centroid of a planar 3D polygon', () => {
|
|
73
|
-
expectPointCloseTo(measurementCentroid([
|
|
74
|
-
[0, 0, 0],
|
|
75
|
-
[2, 0, 0],
|
|
76
|
-
[2, 1, 1],
|
|
77
|
-
[0, 1, 1],
|
|
78
|
-
]), [1, 0.5, 0.5]);
|
|
79
|
-
});
|
|
80
|
-
test('computes area and centroid for a concave polygon', () => {
|
|
81
|
-
const base = [
|
|
82
|
-
[0, 0, 0],
|
|
83
|
-
[2, 0, 0],
|
|
84
|
-
[2, 0, 1],
|
|
85
|
-
[1, 0, 1],
|
|
86
|
-
[1, 0, 2],
|
|
87
|
-
[0, 0, 2],
|
|
88
|
-
];
|
|
89
|
-
expect(measurementArea(base)).toBeCloseTo(3);
|
|
90
|
-
expectPointCloseTo(measurementCentroid(base), [5 / 6, 0, 5 / 6]);
|
|
91
|
-
});
|
|
92
|
-
test('computes prism volume from normal extrusion and ignores tangential extrusion', () => {
|
|
93
|
-
const base = [
|
|
94
|
-
[0, 0, 0],
|
|
95
|
-
[3, 0, 0],
|
|
96
|
-
[3, 2, 0],
|
|
97
|
-
[0, 2, 0],
|
|
98
|
-
];
|
|
99
|
-
expect(measurementPrismVolume(base, [5, 7, 4])).toBeCloseTo(24);
|
|
100
|
-
expect(measurementPrismVolume([...base].reverse(), [5, 7, 4])).toBeCloseTo(24);
|
|
101
|
-
});
|
|
102
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"slab-polygon.test.d.ts","sourceRoot":"","sources":["../../src/lib/slab-polygon.test.ts"],"names":[],"mappings":""}
|