Skip to contents

A small physical solver behind geom_sketch_text_repel() / geom_sketch_label_repel(). Each label starts near its anchor and is pushed by three forces, iterated to rest: boxes that overlap shove each other apart along their axis of least penetration (preferring an axis with room left inside the bounds, so pairs pressed into a panel corner escape along the edge instead of staying stuck); a box covering any anchor point slides off it; and a weak spring pulls each box back toward its own anchor so labels stay close to what they name. Positions are clamped to xlim / ylim.

Usage

repel_layout(
  ax,
  ay,
  w,
  h,
  xlim = c(-Inf, Inf),
  ylim = c(-Inf, Inf),
  box_padding = 0.1,
  point_padding = 0.05,
  max_iter = 2000L,
  seed = NULL
)

Arguments

ax, ay

Anchor points (one per label), in a single isotropic space (e.g. device inches).

w, h

Label box width and height (same units), recycled to the anchors.

xlim, ylim

Length-2 bounds the box centres are kept within.

box_padding, point_padding

Extra clearance around boxes and around anchor points, in the same units.

max_iter

Maximum solver iterations. Default 2000.

seed

Integer seed (for the tiny start jitter that separates labels sharing an anchor).

Value

A list with x, y (the resolved box centres) and iter (iterations actually run).

Examples

repel_layout(c(0, 0.1, 0.1), c(0, 0, 0.05), w = 0.4, h = 0.2, seed = 1L)
#> $x
#> [1] 3.197873e-05 1.000208e-01 4.491272e-01
#> 
#> $y
#> [1] -0.6580096 -0.2480149  0.1619851
#> 
#> $iter
#> [1] 2000
#>