RPIC

Positioning

pic lays out a picture the way you would describe it aloud: there is a current position and a current direction, every object advances them, and you only reach for coordinates when you want them.

Direction words

up, down, left and right set the direction for everything that follows — as a statement on their own, or as an attribute of one object.

.PS
box "1" wid 0.45 ht 0.4
arrow
box "2" wid 0.45 ht 0.4
arrow down 0.4 from last box.s
box "3" wid 0.45 ht 0.4
arrow left 0.8 from last box.w
box "4" wid 0.45 ht 0.4
.PE
1 2 3 4

Compass anchors

Every object exposes compass corners — .n .ne .e .se .s .sw .w .nw — plus .c (center), and .start/.end on paths. They are positions you can draw from, to, or at.

.PS
A: box "A" wid 0.9 ht 0.7
circle rad 0.05 fill 0 at A.ne
circle rad 0.05 fill 0 at A.sw
arrow from A.e right 0.5
.PE
A

at and with

at places an object’s center on a position. with chooses which corner lands there instead — read it as “with this corner at that point”.

.PS
A: box "A" wid 0.8 ht 0.6
box "at A.ne" ht 0.4 fill 1 at A.ne
box "with .sw" ht 0.4 with .sw at A.ne + (0.9, 0)
circle rad 0.035 fill 0 at A.ne + (0.9, 0)
.PE
A at A.ne with .sw

from / to, and expressions on positions

Open objects take explicit endpoints. Positions compose with vector arithmetic — A.e + (0.2, -0.1) — and with between:

.PS
A: circle "A" rad 0.25
B: circle "B" rad 0.25 at A + (1.8, 0)
line from A.e to B.w
M: 0.5 between A.e and B.w
circle rad 0.04 fill 0 at M
arrow from M + (0, -0.45) to M "midpoint" ljust
.PE
A B midpoint

0.5 between P and Q is the midpoint; any fraction works, and fraction of the way between P and Q reads even closer to English.

chop

chop shortens a line by a fixed length at each end — it is not boundary-aware. Bare chop trims circlerad (default 0.25 in), which lands exactly on the boundary of default-sized circles; for anything else, say how much: chop expr for both ends, or chop a chop b for start and end.

.PS
A: circle "A" rad 0.3
B: circle "B" rad 0.3 at A + (1.5, 0.5)
line from A to B chop 0.3
.PE
A B

With circles of different sizes, give each end its own amount:

.PS
A: circle "A" rad 0.2
B: circle "B" rad 0.4 at A + (1.5, 0.5)
line from A to B chop 0.2 chop 0.4
.PE
A B

Where to go next