Engineering Journal
Schema Editor
Schema Editor

The Magic of Manhattan: Implementing Intelligent Orthogonal Routing in Vanilla JS

2026-05-11

TLDR

In engineering schematics, wire routing must follow clean 90° orthogonal paths ("Manhattan routing") to prevent messy, unreadable "spaghetti" diagrams. The GINEXYS Schema Editor implements a modified A* pathfinding algorithm on a dynamic grid with heavy turn penalization (favoring long straight segments over staircase steps) and optional 45° chamfered corners. Real-time net tracing uses a spatial KD-tree to traverse connectivity graphs at 60fps in pure Vanilla JS SVG.
Feature ComponentRouting MechanismEngineering Benefit
A* Orthogonal RouterTurn penalization cost functionEliminates staircase wire bends
45° Corner ChamferingSVG path corner smoothingReduces visual clutter & reflects PCB practices
Real-time Net TracingKD-Tree spatial index traversalInstant 60fps signal path highlighting

Problem statement: the spaghetti wire problem in visual CAD

In open-source diagramming tools, wires are often rendered as simple straight diagonal lines or basic Bezier curves.

In complex electrical, architectural, or software schematics, diagonal wires crossing over components create unreadable "spaghetti" layouts. Wires must route orthogonally around component bounding boxes while maintaining clean 90° bends.


Technical failure mode: staircase bends in standard A* pathfinding

Standard A* pathfinding evaluates path cost based purely on Euclidean or Manhattan distance.

When routing between two pins that are offset both horizontally and vertically, standard A* treats a series of small 1-unit staircase steps (right-down-right-down) as identical in cost to a clean two-segment elbow (right-then-down). This results in jagged, unreadable wire paths.


The fix & architecture: turn penalization & spatial net tracing

1. Turn penalization in pathfinding cost

We modified the A* pathfinding heuristic to add a heavy cost penalty whenever a step changes direction by 90°:
// Heuristic Cost: Distance + Heavy Turn Penalty
function calculateStepCost(currentDirection, nextDirection, baseDistance) {
  const isTurn = currentDirection !== nextDirection;
  const turnPenalty = isTurn ? 50 : 0; // Heavy penalty forces long straight segments
  return baseDistance + turnPenalty;
}

2. Direct SVG DOM manipulation for 60fps dragging

Rather than using virtual DOM frameworks (React/Vue) that introduce rendering latency during component dragging, wire paths mutate SVG d attributes directly:
// Direct DOM mutation during component drag
function updateWirePath(wireSvgPathEl, pointArray) {
  const pathData = generateManhattanPathD(pointArray); // Generates 'M x y L x y...'
  wireSvgPathEl.setAttribute('d', pathData);
}

3. Spatial KD-tree net tracing

When a user clicks a wire in Trace Mode, the engine executes a recursive graph traversal using a spatial KD-tree index, highlighting the entire electrical net (source, resistors, IC pins) instantly across thousands of elements.
Rule of thumb: Add heavy turn penalties to A* pathfinding heuristics when building schematic wire routers to force clean orthogonal paths over staircase steps.
Read this post in the full Engineering Journal →