Wall Detection

"/home/yossef/notes/git/projects/maplibra/flows/Wall Detection.md"

path: maplibra/flows/Wall Detection.md

- **fileName**: Wall Detection
- **Created on**: 2026-06-16 00:48:42

Wall Detection

Purpose: How the system determines if a path segment crosses walls or obstacles.

Related: ../Home.md, ../Architecture.md, ../modules/Route Smoothing.md, ../decisions/Sampling vs Intersection.md

Three Layers of Wall Detection

1. Offline Graph Build (scripts/build-routing-graph.js)

During graph construction, candidate edges are rejected if any sampled point lands inside a buffered obstacle:

2. Runtime JS (src/pathfinding/walkable-areas.js)

During smoothing, shortcut segments are validated:

3. WASM Kernel (native/routing/route_smoothing.c)

C equivalent for performance-critical paths:

The Fundamental Approach: Point Sampling

All three layers use the SAME technique: sample discrete points along a segment and check each one.

This is NOT geometric line-polygon intersection. It has a known weakness:

If a wall is thinner than the sample step, it can slip between sample points undetected.

See ../decisions/Sampling vs Intersection.md for why this was chosen and what the tradeoffs are.

Blocker Buffer Sizes

Kind Buffer Distance Applied When
Wall 0.6m kinds/{floor}.json has "wall"
Object 0.4m kinds/{floor}.json has "object"
Nonwalkable 0.4m Listed in nonwalkable/{floor}.json
Inaccessible 0.4m (merged into nonwalkable) Style anchors in InaccessibleRooms etc.

Flow Diagram

isSegmentWalkable(start, end, floorId)
  │
  ├── compute sampleStep = min(smoothSampleDistance, 0.2)
  ├── steps = max(2, ceil(distance / sampleStep))
  │
  └── for i = 0 to steps:
        t = i / steps
        coords = lerp(start, end, t)
        │
        ├── isPointWalkable(coords, floorId)?
        │     └── booleanPointInPolygon vs walkable polygons
        │
        └── isPointBlockedSmooth(coords, floorId)?
              └── booleanPointInPolygon vs buffered blockers

Important Files