Overlap

Overlap :: # (opaque)

Placement-independent overlap removal: move node centers as little as possible so no two node boxes overlap, keeping the shape of the placement intact.

remove : List({ x : F64, y : F64 }), List({ width : F64, height : F64 }), F64 -> List({ x : F64, y : F64 })

Minimally move node centers so no two boxes overlap and every pair clears the given gap, preserving each pair's relative order on the axis that separates them. Positions and sizes are index-aligned and the result follows input order; a position without a matching size is treated as a zero-size point, which only counts as overlapping when it sits strictly inside another gap-expanded box, so waypoints on a box edge stay put. A non-finite or negative gap behaves as 0 — this pass has no build step, so it stays total instead of validating.

Two projection passes give a guaranteed-clean result in bounded work:

  1. Every pair overlapping on both axes whose horizontal resolving movement is no larger than its vertical one gets a horizontal separation requirement (the node with the smaller x stays left; coordinate ties keep the smaller index left), and one per-axis projection satisfies all of them exactly with the least total movement.
  2. Every pair still too close horizontally — whether or not it currently overlaps — gets a vertical separation requirement (the node with the smaller y stays above, ties by index), and a second projection satisfies those exactly. Requirements that already hold move nothing.

After the second pass every pair is either clear horizontally (the vertical pass never changes x) or was given a vertical requirement the projection satisfied — so no overlapping pair can remain, dense pileups included. Overlaps of at most 1e-9 units count as resolved so floating-point round-off never generates work.

Deterministic: pairs are scanned in index order and identical input produces identical output, bit for bit — already-separated input is returned exactly unchanged. The pair scans are quadratic in the node count, which suits the placement sizes this pass serves.