# teaching machines

## Random Splats with Lobes

Earlier I discussed my silly dream of generating random splats. That dream had a sequel that the recent break afforded me time to pursue: generating random splats with lobes.

I had a hunch that this task would be easier if I had a utility function for generating a random curve that netted a turn of a certain number of degrees. So, I wrote this function, which turns a random angle in [minAngle, maxAngle], moves a bit, and keeps on doing that until the target curvature is reached:

to meanderCurve minAngle, maxAngle, targetAngle, stepDistance
net = 0
while |net| < targetAngle
delta = random minAngle, maxAngle
yaw delta
move stepDistance
net = net + delta
end
end


A left turn is made by skewing the distribution of angles negative. A right turn, by skewing positive. I created a random undulation by alternating between left and right curves:



seed = 140

to meanderCurve minAngle, maxAngle, targetAngle, stepDistance
net = 0
while |net| < targetAngle
delta = random minAngle, maxAngle
yaw delta
move stepDistance
net = net + delta
end
end

moveto 0, 0
repeat 4
-- Right then left
meanderCurve -5, 10, 180, 0.1
meanderCurve -10, 5, 180, 0.1
end

dowel

var mupDiv = jQuery('#mup_wave');
mupDiv.closest('pre').replaceWith(mupDiv);
document.getElementById('mup_form_wave').submit();

seed = 140

to meanderCurve minAngle, maxAngle, targetAngle, stepDistance
net = 0
while |net| < targetAngle
delta = random minAngle, maxAngle
yaw delta
move stepDistance
net = net + delta
end
end

moveto 0, 0
repeat 4
-- Right then left
meanderCurve -5, 10, 180, 0.1
meanderCurve -10, 5, 180, 0.1
end

dowel



To turn this undulating pattern into the perimeter of a lobed splat, I shrunk the target angle of the left curves—so they didn’t fully cancel out the right turn. The net effect was that we were carried a little way around the circular pattern:



seed = 140

to meanderCurve minAngle, maxAngle, targetAngle, stepDistance
net = 0
while |net| < targetAngle
delta = random minAngle, maxAngle
yaw delta
move stepDistance
net = net + delta
end
end

moveto 0, 0
repeat 4
-- Right then left
meanderCurve -5, 10, 180, 0.1
meanderCurve -10, 5, 120, 0.1
end

dowel

var mupDiv = jQuery('#mup_turned');
mupDiv.closest('pre').replaceWith(mupDiv);
document.getElementById('mup_form_turned').submit();

seed = 140

to meanderCurve minAngle, maxAngle, targetAngle, stepDistance
net = 0
while |net| < targetAngle
delta = random minAngle, maxAngle
yaw delta
move stepDistance
net = net + delta
end
end

moveto 0, 0
repeat 4
-- Right then left
meanderCurve -5, 10, 180, 0.1
meanderCurve -10, 5, 120, 0.1
end

dowel



Each iteration of the repeat loop netted us a turn of 60 degrees. To go around a complete circle, I repeated 6 times. But to make the ends of the path meet, I employed the same trick as I did with the simple splats. I distribute the gap between the endpoints across all intermediate vertices. The end result is the lobed splat that I had in mind:



seed = 130

to meanderCurve minAngle, maxAngle, targetAngle, stepDistance
net = 0
while |net| < targetAngle
delta = random minAngle, maxAngle
yaw delta
move stepDistance
net = net + delta
end
end

-- Go for a random walk.
moveto 0, 0

repeat 6
meanderCurve -5, 10, 180, 10
meanderCurve -15, 5, 120, 7
end

-- Convert the path into an
-- array of vertices.
vertices = path

-- How much space is between
-- the start and end?
gap = vertices[-1] - vertices

-- Let's divide that gap by
-- the number of vertices we
-- have...
shift = -gap / size vertices

-- Shift each vertex over by
-- a fraction of the gap.
moveto 0, 0
for i to size vertices
vertex = vertices[i]
translate shift, shift, 0
moveto vertex, vertex, vertex
end

extrude 0, 0, 1, 100

var mupDiv = jQuery('#mup_lobed');
mupDiv.closest('pre').replaceWith(mupDiv);
document.getElementById('mup_form_lobed').submit();

seed = 130

to meanderCurve minAngle, maxAngle, targetAngle, stepDistance
net = 0
while |net| < targetAngle
delta = random minAngle, maxAngle
yaw delta
move stepDistance
net = net + delta
end
end

-- Go for a random walk.
moveto 0, 0

repeat 6
meanderCurve -5, 10, 180, 10
meanderCurve -15, 5, 120, 7
end

-- Convert the path into an
-- array of vertices.
vertices = path

-- How much space is between
-- the start and end?
gap = vertices[-1] - vertices

-- Let's divide that gap by
-- the number of vertices we
-- have...
shift = -gap / size vertices

-- Shift each vertex over by
-- a fraction of the gap.
moveto 0, 0
for i to size vertices
vertex = vertices[i]
translate shift, shift, 0
moveto vertex, vertex, vertex
end

extrude 0, 0, 1, 100



Now time to print some and hang them on our Christmas tree.