Skip to main content

Module outline

Module outline 

Source
Expand description

An outline of lines, arcs and circles fitted around a silhouette, clear of it by a play and within a tolerance band.

The band is every point whose signed distance from the silhouette, positive outside it and negative inside, lies between play and play + 2 tolerance. The fit has three stages, and only the last one decides what is returned.

  1. The middle of the band. The silhouette is first traced afresh as a region, so its loops bound it exactly, and with fill_below set it is closed (see Filling) and stands for the silhouette from then on. Its offset by play + tolerance is then the union of the silhouette with a rectangle along each edge, on the outside, and a sector at each convex corner, or for a negative offset the silhouette less such rectangles inside and sectors at the reflex corners. The sectors’ arcs are chords sagging a quarter of the tolerance, the offset is taken an eighth further out to centre the sag, and the region engine of ogeom_mesh::planar traces the result: loops whose every point is within an eighth of the tolerance, and the engine’s snapping, of the middle of the band. Holes the band closes over and parts it pinches off are gone from them, and as the boundary of a region they never run out and back.
  2. The fit. Each loop is split into runs a line or a circle follows within three quarters of the tolerance, less the snapping: the whole loop as one circle where that holds. A line or an arc spanning a run lies that close to the loop, so within the band. Consecutive pieces are joined where their curves meet: a corner turning less than round_below takes the largest tangent arc found to fit the band, a sharper one stays a corner where that fits and takes an arc where it does not, and a joint where neither fits is bridged by the short line between the pieces’ ends, which lies near the loop too. No piece is moved past its middle by a joint, so the joints at its two ends never meet.
  3. The check. Every piece is sampled at a quarter of the tolerance and every sample’s signed distance from the silhouette must lie an eighth of the tolerance inside the band. Distance is 1-Lipschitz, so the whole piece then lies in the band. A loop with any piece failing is returned as the polygon of its middle-of-the-band loop, which is checked the same way.

§Filling

With fill_below = w > 0 the silhouette S is replaced by its morphological closing by a disc of radius r = w / 2: dilated by r, then eroded by r. A point outside S stays out of the exact closing C exactly when some closed disc of radius r holds it and misses S. So a hole, or a notch, whose largest inscribed circle is no wider than w across is filled, and one wider keeps the points such discs reach: a round hole wider than w stays whole, a slot of width s < w closes but for a dent where the disc dips into its mouth, r - sqrt(r^2 - s^2/4) deep. A convex corner with nothing else of S within w of it is kept sharp, every point outside it near it lying in such a disc, while a reflex corner takes a fillet of radius r, the disc’s own.

Both steps are offsets as in stage 1, their arcs chords sagging sigma = min(tolerance, r) / 32: the dilation by r + sigma, its chords covering the disc of radius r, and the erosion by r, its chords removing at least the disc of radius r - sigma. The result F therefore holds C, and lies within the closing by r - sigma of S dilated by 2 sigma: everything C fills is filled, a hole or notch more than w + 2 sigma across is kept, and a straight side moves out by sigma at most; all to within the engine’s snapping. F holds S, so the outline clears S by the play wherever it clears F, and the band holds about F.

Structs§

Outline
How an outline is fitted around a silhouette.
Wire2d
A closed outline: pieces end to end, each starting where the one before ends and the last ending where the first starts. An outer boundary runs counter-clockwise and a hole clockwise.

Enums§

Piece2
One piece of a fitted outline.

Functions§

fit_outline
Fit an outline of lines, tangent arcs and circles around a silhouette, every point of it between play and play + 2 tolerance outside the region the loops bound. See the module documentation.