GATE_ARC = 17 # odd, so a sample lands exactly on the nose
GATE_CORNERS = 3 # an AND outline's back and top corners, before the arc
#| Sample x along a quadratic Bezier from x0 through the control x1 to x2.
def bez(p0, p1, p2, n) {
out = zeros(n)
for i to n {
t = i / (n - 1.0)
u = 1.0 - t
out[i] = u * u * p0 + 2.0 * u * t * p1 + t * t * p2
}
return out
}
#| Concatenate two arrays.
def joined(a, b) {
out = zeros(len(a) + len(b))
for i to len(a) {
out[i] = a[i]
}
for j to len(b) {
out[len(a) + j] = b[j]
}
return out
}
#| The x of an AND outline: back at x, nose reaching x + w, height h, centered on y.
def and_x(x, y, w, h) {
r = 0.5 * h
straight = x + w - r
xs = zeros(GATE_CORNERS + GATE_ARC)
xs[0] = x
xs[1] = x
xs[2] = straight
for i to GATE_ARC {
ang = 1.5707963267948966 * (1.0 - 2.0 * i / (GATE_ARC - 1.0))
xs[GATE_CORNERS + i] = straight + r * cos(ang)
}
return joined(xs, [x, x])
}
#| The y of that outline.
def and_y(x, y, w, h) {
r = 0.5 * h
ys = zeros(GATE_CORNERS + GATE_ARC)
ys[0] = y - r
ys[1] = y + r
ys[2] = y + r
for i to GATE_ARC {
ang = 1.5707963267948966 * (1.0 - 2.0 * i / (GATE_ARC - 1.0))
ys[GATE_CORNERS + i] = y + r * sin(ang)
}
return joined(ys, [y - r, y - r])
}
#| The x of an OR outline: concave back at x, nose at x + w.
def or_x(x, y, w, h) {
r = 0.5 * h
back = bez(x, x + 0.45 * w, x, GATE_ARC)
top = bez(x, x + 0.55 * w, x + w, GATE_ARC)
bot = bez(x + w, x + 0.55 * w, x, GATE_ARC)
return joined(joined(back, top), bot)
}
#| The y of that outline.
def or_y(x, y, w, h) {
r = 0.5 * h
back = bez(y - r, y, y + r, GATE_ARC)
top = bez(y + r, y + r, y, GATE_ARC)
bot = bez(y, y - r, y - r, GATE_ARC)
return joined(joined(back, top), bot)
}
#| The second arc behind an XOR, a little to the left of the body.
def xor_arc_x(x, y, w, h, gap) {
return bez(x - gap, x - gap + 0.45 * w, x - gap, GATE_ARC)
}
#| The y of that arc.
def xor_arc_y(x, y, w, h, gap) {
r = 0.5 * h
return bez(y - r, y, y + r, GATE_ARC)
}
#| An inverter: a triangle from the back at x to a point at x + w.
def not_x(x, y, w, h) {
return [x, x, x + w, x]
}
#| The y of that triangle.
def not_y(x, y, w, h) {
r = 0.5 * h
return [y - r, y + r, y, y - r]
}
#| An orthogonal wire: out of (x1, y1) to the right, one turn at `xm`, into
#| (x2, y2) from the left. Four points; a straight run repeats the last.
def wire_x(x1, y1, xm, x2, y2) {
return [x1, xm, xm, x2]
}
#| The y of that wire.
def wire_y(x1, y1, xm, x2, y2) {
return [y1, y1, y2, y2]
}
#| A net that feeds two inputs: out of (x1, y1), along to the branch at `xm`, up
#| or down to the first input's height, into it, back to the branch, down to the
#| second, into it. Every run is horizontal or vertical, and the retrace draws
#| over itself, so the net is one path with a junction where it splits.
def net2_x(x1, y1, xm, xa, ya, xb, yb) {
return [x1, xm, xm, xa, xm, xm, xb]
}
#| The y of that net.
def net2_y(x1, y1, xm, xa, ya, xb, yb) {
return [y1, y1, ya, ya, ya, yb, yb]
}
#| A path parked off the picture: the same point count, far enough away that a
#| keyframed player jumps rather than sliding it back in.
def parked(n) {
out = zeros(n)
for i to n {
out[i] = -40.0
}
return out
}
test "an AND outline is closed, and spans the box it was asked for" {
xs = and_x(1.0, 2.0, 1.6, 1.0)
ys = and_y(1.0, 2.0, 1.6, 1.0)
assert_near(xs[0], xs[len(xs) - 1], 1.0e-12)
assert_near(ys[0], ys[len(ys) - 1], 1.0e-12)
assert_near(min(xs), 1.0, 1.0e-12)
assert_near(max(xs), 2.6, 1.0e-12)
assert_near(min(ys), 1.5, 1.0e-12)
assert_near(max(ys), 2.5, 1.0e-12)
}
test "an OR outline reaches its nose and its back sits inside the box" {
xs = or_x(0.0, 0.0, 2.0, 1.2)
ys = or_y(0.0, 0.0, 2.0, 1.2)
assert_near(max(xs), 2.0, 1.0e-12)
assert_near(min(xs), 0.0, 1.0e-12)
assert_near(max(ys), 0.6, 1.0e-12)
assert_near(min(ys), -0.6, 1.0e-12)
}
test "a branching net runs only horizontally and vertically" {
xs = net2_x(0.0, 1.0, 2.0, 4.0, 3.0, 4.0, -1.0)
ys = net2_y(0.0, 1.0, 2.0, 4.0, 3.0, 4.0, -1.0)
for i to len(xs) - 1 {
moved_x = abs(xs[i + 1] - xs[i])
moved_y = abs(ys[i + 1] - ys[i])
assert_true(moved_x < 1.0e-12 or moved_y < 1.0e-12)
}
}
test "a wire turns once: two horizontal runs joined by a vertical one" {
xs = wire_x(0.0, 1.0, 2.0, 4.0, 3.0)
ys = wire_y(0.0, 1.0, 2.0, 4.0, 3.0)
assert_near(ys[0], ys[1], 1.0e-12)
assert_near(xs[1], xs[2], 1.0e-12)
assert_near(ys[2], ys[3], 1.0e-12)
}
# SPDX-License-Identifier: MIT OR Apache-2.0
# SPDX-FileCopyrightText: 2026 The Viv authors