Geometry

Geometry

Change shape without comparing two layers. sized works per shape; overlapping results are not merged automatically.

← Language overview

sized(a, d)

Available · yields polygons

layer g = sized(a, 0.05 um)

Isotropic: d > 0 grows, d < 0 shrinks. Per shape. The first result of the size step replaces the original; further pieces are appended. There is no automatic merge across shapes.

Input Result Dashed = original, green = grown

Notes

  • d = 0: unchanged.
  • A shrink larger than half the width can remove the shape.
  • Growing until two neighbours touch: two overlapping polygons — not a union until merged or |.
  • Holes shrink when the hull grows (the hole becomes tighter) and grow when the hull shrinks.
  • Very sharp inner corners can produce extra polygons while growing.

sized(a, dx, dy)

Available · yields polygons

layer g = sized(a, 0.1 um, 0.0 um)

Anisotropic: X and Y offsets of the edges are independent. dy = 0 moves only vertical edges (width in X).

Input Result

Notes

  • One sign positive and one negative: grow on one axis, shrink on the other.
  • Both negative and |dx|, |dy| too large: the shape disappears.
  • Diagonal edges: 45° edges do not move purely axis-aligned.

sized(a, l, b, r, t)

Available · yields polygons

layer g = sized(a, 0.1 um, 0.05 um, 0.1 um, 0.05 um)

Four independent sides (left, bottom, right, top) in the unrotated bounding sense. A Manhattan rectangle: the box grows or shrinks per side.

Input Result

Notes

  • Negative on one side: only that side pulls in; the shape disappears if the side crosses the opposite one.
  • A non-rectangle falls back to the mean of opposite pairs ((l+r)/2, (b+t)/2).

sized(…, corners=)

Available · yields polygons

layer g = sized(a, 0.05 um, corners=octagon)

Corner treatment when growing a Manhattan rectangle: square (axis-aligned cap), octagon / diamond (45° chamfer), acute (default size step), none (open corner: side strips only, no corner squares).

Input Result

Notes

  • Shrinking (d < 0): corners=square / octagon / none fall back to the default size step.
  • none on a 1×1 rectangle with d=0.2: area 1.8 (a cross), box like square.

sized(…, inside= / outside=)

Available · yields polygons

layer g = sized(a, 0.05 um, inside=well, steps=8)
layer g = sized(a, 0.05 um, outside=keep)

Incremental growth: inside=well stays in well (latch-up dummy), outside=keep avoids keep. steps splits d into n steps (the last step gets the remainder in dbu).

Input Result Growth only inside well (orange)

Notes

  • If one step would leave well: AND with well after each step; the seed stays (clip, not drop).
  • outside=keep: after each step grown - keep. Keep that fully surrounds the seed blocks growth into keep.
  • A convex well: steps=n gives the same area as one step plus AND.

merged(a)

Available · yields polygons

layer m = merged(a)

OR of all polygons one after another, then a stitch at shared vertices until nothing changes. A single polygon is unchanged.

Input Result

Notes

  • An empty layer or one shape: identity.
  • Only a shared corner, no edge, no area: stitched to one (possibly self-touching) ring.
  • Separate components without a shared vertex stay separate.
  • merged(a, n) keeps only n-fold overlap.

merged(a, n)

Available · yields polygons

layer m = merged(a, 2)

Only regions where at least n original shapes overlap (n-fold coverage). n=1 is union.

Input Result

Notes

  • n=2, two overlapping boxes: only the AND rectangle.
  • n larger than the maximum coverage: empty.
  • Kissing without area: coverage 1, not 2.

extents(a)

Available · yields polygons

layer e = extents(a)

Axis-aligned bounding box of each polygon, as a rectangle shape.

Input Result

Notes

  • An empty layer: empty.
  • An already axis-aligned rectangle: the box equals the shape (up to identical corners).
  • A rotated rectangle or an L-shape: the box is larger than the area; box corners lie outside the original.
  • An edge layer is turned into polygons first (a 1 dbu tube around the edge).

bounds(a)

Available · yields polygons

layer b = bounds(a)

One bounding box around the union of all shapes of a (not per shape).

Input Result

Notes

  • An empty layer: empty (no zero rectangle).
  • Two distant boxes: one huge rectangle between them that is not original area.
  • bounds() without an argument: bounding box of the cell, even if individual layers are empty.

bounds()

Available · yields polygons

layer die = bounds()

Cell box: union of the geometry of the start cell, independent of the current layer expression.

Input Result

Notes

  • A cell without shapes: empty.
  • Only texts/labels: bounds() does not see texts; use texts(...) for a text layer.
  • Instances: included after flatten.

hulls(a)

Available · yields polygons

layer h = hulls(a)

Outer contours: rings that are not clockwise. Holes are dropped.

Input Result

Notes

  • A simple polygon without a hole: identity.
  • A donut: only the outer ring, as a filled rectangle without a hole (the area includes the former hole).
  • Several components: one hull per outer ring.
  • A clockwise-only leftover ring is classified as a hole and does not appear in hulls.

holes(a)

Available · yields polygons

layer h = holes(a)

Only clockwise rings after the rings are separated. Each hole becomes its own polygon (now as area, not as a negative).

Input Result

Notes

  • No hole: empty.
  • Two holes: two polygons.
  • A self-touching polygon that is not split into hull/hole can count as 0 holes.
  • area(holes(m1)) is the usual hole-area check.

snap(a, g)

Available · yields polygons

layer s = snap(a, 0.005 um)

Every vertex onto the nearest multiple of g. snap(a, gx, gy) independently in X and Y.

Input Result

Notes

  • g ≤ 0: unchanged.
  • A vertex exactly in the middle follows the platform lround of .5.
  • Two different vertices can land on the same grid point → a degenerate edge or a self-touch.
  • Off-grid by less than g/2 moves onto the grid; ongrid afterwards is clean, the shape can change visibly.

flatten(a)

Available · yields polygons

layer f = flatten(a)

Polygon copy of the layer (already-flat shapes). Hierarchy flatten stays with input() / mode.

Input Result

Notes

  • Edges/pairs are polygonized first.
  • An empty layer: empty.

moved / rotated / scaled

Available · yields polygons

layer t = moved(a, 1 um, 0)
layer t = rotated(a, 90)
layer t = scaled(a, 2)

Affine move about the cell origin (not the shape centre). Angle in degrees.

Input Result

Notes

  • rotated by 0: identity.
  • scaled by 0: degenerate / empty.
  • A negative scale: mirror about the origin.

rounded_corners

Available · yields polygons

layer r = rounded_corners(a, 0.05 um, 0.08 um, 8)

Inner corners with radius inner, outer corners outer, n segments per arc.

Input Result

Notes

  • A radius larger than the adjacent edge: the corner stays sharp.
  • n=1: one intermediate point (faceted).
  • inner=0: only outer corners round.

smoothed

Available · yields polygons

layer s = smoothed(a, 0.02 um)

Drop vertices whose distance to the neighbouring chord is below d (collinear/jog clean-up). Related: snap.

Input Result

Notes

  • d=0: identity.
  • A d that is too large can delete narrow jogs and necks.