Computational geometry · interactive

Polygon offset, and why the obvious method is wrong

Offsetting a polygon looks like moving every vertex outward along its angle bisector. It is the first thing you would write, and it is wrong. At a sharp corner the bisector runs away toward infinity; at a concave corner the curve folds back through the shape. What you get is not at the distance you asked for — and in CAD or cutting, that distance is the point: it is the seam allowance, the tool radius, the kerf. The readout measures how far each method actually lands from the requested offset. Drag any vertex and move the slider.

Offset distance

+68 px

Show

Shape

Readout

What the robust pass actually does

  1. Offset every edge along its own normal, instead of moving vertices along the angle bisector.
  2. Close the gap at convex turns with a circular arc, and let reflex turns overrun — they will be cleaned up next.
  3. Discard every point of the raw offset curve whose distance to the original polygon is less than the offset distance. This is what removes the inverted lobes, and it is the step the naive method has no equivalent for.
  4. Re-stitch the surviving runs into closed loops. A shape with a narrow neck legitimately splits into two loops — try the neck preset and push the distance past −30.

On the star at +68 the naive result misses the requested distance by more than 120 px at the points, while the robust one is exact. The yellow markers appear when the raw curve genuinely crosses itself. Everything here is plain JavaScript on a canvas — no geometry library.