# teaching machines

## Figure Out

One of my favorite illusion mechanics is figure-ground reversal. What was the foreground becomes the background, and what was the background becomes the foreground. I went for a subtle figure-ground reversal in this checkerboard animation. It’s subtle because I don’t think checkerboards have an obvious figure and ground. We are trained to accept that both colors are equal. The initial movement makes the cornflower squares appear to be the figure, but then we see the white squares move.

When I watch this, I get some intriguing after-image effects. Diagonal lines appear on the axis-aligned checkerboard.

The original Twoville code for this animation was too long. I added a new construct to eliminate repetitive code. Using the with block and an array, once can now set properties on multiple objects at once. For example, here we set the size of a and b at the same time:

with [a, b]
size = [10, 10]

The code still clocks in at 130 lines. What would it take in a language like Processing?



step = 20

with gif
size = [512, ~]

with time
start = 0
stop = step * 4
delay = 0.05

// Backdrop
with rectangle()
corner = :zero2
size = [100, ~]
0 -> t -> step * 2 - 1
color = :white
step * 2 -> t -> step * 4
color = :cornflower

for r in -1..11
for c in -1..11
if abs(r) % 2 != abs(c) % 2

// Stasis A rectangle
with rectangle()
corner = [c, r] * 10
size = [10, ~]
color = :cornflower
enabled = false
0 -> t -> step
enabled = true

// Rotating A triangles
ab = with polygon()
vertex().position = [c, r] * 10
vertex().position = [c + 1, r] * 10
vertex().position = [c + 0.5, r + 0.5] * 10
with rotate()
pivot = [c, r] * 10
0 -> step * 1 -> t
degrees = 0
t -> step * 2
degrees = -90

at = with polygon()
vertex().position = [c, r + 1] * 10
vertex().position = [c + 1, r + 1] * 10
vertex().position = [c + 0.5, r + 0.5] * 10
with rotate()
pivot = [c + 1, r + 1] * 10
0 -> step * 1 -> t
degrees = 0
t -> step * 2
degrees = -90

ar = with polygon()
vertex().position = [c + 1, r] * 10
vertex().position = [c + 1, r + 1] * 10
vertex().position = [c + 0.5, r + 0.5] * 10

al = with polygon()
vertex().position = [c, r] * 10
vertex().position = [c, r + 1] * 10
vertex().position = [c + 0.5, r + 0.5] * 10

with [al, at, ar, ab]
color = :cornflower
0 -> t -> step
enabled = false
step * 2 -> t
enabled = false

// Stasis B rectangles
bRectangle1 = with rectangle()
corner = [c, r] * 10
with rotate()
degrees = -45
pivot = [c, r] * 10

bRectangle2 = with rectangle()
corner = [c + 1, r] * 10
with rotate()
degrees = -45
pivot = [c + 1, r] * 10

with [bRectangle1, bRectangle2]
size = [sqrt(50), ~]
color = :white
enabled = false
step * 2 -> t -> step * 3
enabled = true

// Rotating B triangles
bl = with polygon()
vertex().position = [c - 1, r] * 10
vertex().position = [c - 1, r + 1] * 10
vertex().position = [c - 0.5, r + 0.5] * 10
with rotate()
pivot = [c - 1, r] * 10
step * 3 -> t
degrees = 90
t -> step * 4
degrees = 0

br = with polygon()
vertex().position = [c, r] * 10
vertex().position = [c, r + 1] * 10
vertex().position = [c - 0.5, r + 0.5] * 10
with rotate()
pivot = [c, r + 1] * 10
step * 3 -> t
degrees = 90
t -> step * 4
degrees = 0

bt = with polygon()
vertex().position = [c - 1, r + 1] * 10
vertex().position = [c, r + 1] * 10
vertex().position = [c - 0.5, r + 0.5] * 10

bb = with polygon()
vertex().position = [c - 1, r] * 10
vertex().position = [c, r] * 10
vertex().position = [c - 0.5, r + 0.5] * 10

with [bl, br, bb, bt]
color = :white
0 -> t -> step * 3
enabled = false

var twovilleDiv = jQuery('#twoville_figure_ground_checkers');
twovilleDiv.closest('pre').replaceWith(twovilleDiv);
document.getElementById('twoville_form_figure_ground_checkers').submit();

step = 20

with gif
size = [512, ~]

with time
start = 0
stop = step * 4
delay = 0.05

// Backdrop
with rectangle()
corner = :zero2
size = [100, ~]
0 -> t -> step * 2 - 1
color = :white
step * 2 -> t -> step * 4
color = :cornflower

for r in -1..11
for c in -1..11
if abs(r) % 2 != abs(c) % 2

// Stasis A rectangle
with rectangle()
corner = [c, r] * 10
size = [10, ~]
color = :cornflower
enabled = false
0 -> t -> step
enabled = true

// Rotating A triangles
ab = with polygon()
vertex().position = [c, r] * 10
vertex().position = [c + 1, r] * 10
vertex().position = [c + 0.5, r + 0.5] * 10
with rotate()
pivot = [c, r] * 10
0 -> step * 1 -> t
degrees = 0
t -> step * 2
degrees = -90

at = with polygon()
vertex().position = [c, r + 1] * 10
vertex().position = [c + 1, r + 1] * 10
vertex().position = [c + 0.5, r + 0.5] * 10
with rotate()
pivot = [c + 1, r + 1] * 10
0 -> step * 1 -> t
degrees = 0
t -> step * 2
degrees = -90

ar = with polygon()
vertex().position = [c + 1, r] * 10
vertex().position = [c + 1, r + 1] * 10
vertex().position = [c + 0.5, r + 0.5] * 10

al = with polygon()
vertex().position = [c, r] * 10
vertex().position = [c, r + 1] * 10
vertex().position = [c + 0.5, r + 0.5] * 10

with [al, at, ar, ab]
color = :cornflower
0 -> t -> step
enabled = false
step * 2 -> t
enabled = false

// Stasis B rectangles
bRectangle1 = with rectangle()
corner = [c, r] * 10
with rotate()
degrees = -45
pivot = [c, r] * 10

bRectangle2 = with rectangle()
corner = [c + 1, r] * 10
with rotate()
degrees = -45
pivot = [c + 1, r] * 10

with [bRectangle1, bRectangle2]
size = [sqrt(50), ~]
color = :white
enabled = false
step * 2 -> t -> step * 3
enabled = true

// Rotating B triangles
bl = with polygon()
vertex().position = [c - 1, r] * 10
vertex().position = [c - 1, r + 1] * 10
vertex().position = [c - 0.5, r + 0.5] * 10
with rotate()
pivot = [c - 1, r] * 10
step * 3 -> t
degrees = 90
t -> step * 4
degrees = 0

br = with polygon()
vertex().position = [c, r] * 10
vertex().position = [c, r + 1] * 10
vertex().position = [c - 0.5, r + 0.5] * 10
with rotate()
pivot = [c, r + 1] * 10
step * 3 -> t
degrees = 90
t -> step * 4
degrees = 0

bt = with polygon()
vertex().position = [c - 1, r + 1] * 10
vertex().position = [c, r + 1] * 10
vertex().position = [c - 0.5, r + 0.5] * 10

bb = with polygon()
vertex().position = [c - 1, r] * 10
vertex().position = [c, r] * 10
vertex().position = [c - 0.5, r + 0.5] * 10

with [bl, br, bb, bt]
color = :white
0 -> t -> step * 3
enabled = false