Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Jigsaw puzzle generator for DrawBot
def translatePoints(points, dx, dy):
return [(x + dx, y + dy) for x, y in points]
def transposePoints(points):
return [(y, x) for x, y in points]
def pairs(seq):
it = iter(seq)
prev = next(it)
for item in it:
yield prev, item
prev = item
def makePaths(paths):
for p1, p2 in pairs(paths):
bez = BezierPath()
bez.moveTo(p1[0])
bez.qCurveTo(*p1[1:])
p2 = list(reversed(p2))
bez.lineTo(p2[0])
bez.qCurveTo(*p2[1:])
bez.closePath()
yield bez
def wobble(wob):
return wob * (random() - 0.5)
X1 = 0.44
X2 = 0.33
def puzzleLine(length, numPieces, amplitude, wob):
points = []
points.append((0, wobble(wob)))
step = length / numPieces
for i in range(0, numPieces):
if random() > 0.5:
amplitude = -amplitude
for fx, fy in [(X1, -0.15), (X2, 1), (1 - X2, 1), (1 - X1, -0.15)]:
x = (i + fx) * step + wobble(wob)
y = (amplitude * fy) + wobble(wob)
points.append((x, y))
points.append((length, wobble(wob)))
return points
margin = 50
puzzleWidth = 1000
puzzleHeight = 500
canvasWidth = puzzleWidth + 2 * margin
canvasHeight = puzzleHeight + 2 * margin
numPiecesH = 10
numPiecesV = 5
stepH = puzzleWidth / numPiecesH
stepV = puzzleHeight / numPiecesV
amp = 0.3
amplitudeH = amp * puzzleHeight / numPiecesV
amplitudeV = amp * puzzleWidth / numPiecesH
wobbleFactor = 0.06
# collect points
hPoints = []
vPoints = []
hPoints.append([(0, 0), (puzzleWidth, 0)])
for i in range(numPiecesV - 1):
points = puzzleLine(puzzleWidth, numPiecesH, amplitudeH, wobbleFactor * stepH)
points = translatePoints(points, 0, (i + 1) * stepV)
hPoints.append(points)
hPoints.append([(0, puzzleHeight), (puzzleWidth, puzzleHeight)])
vPoints.append([(0, 0), (0, puzzleHeight)])
for i in range(numPiecesH - 1):
points = puzzleLine(puzzleHeight, numPiecesV, amplitudeV, wobbleFactor * stepV)
points = transposePoints(points)
points = translatePoints(points, (i + 1) * stepH, 0)
vPoints.append(points)
vPoints.append([(puzzleWidth, 0), (puzzleWidth, puzzleHeight)])
# assemble horizontal and vertical paths
hPaths = list(makePaths(hPoints))
vPaths = list(makePaths(vPoints))
# start drawing
size(canvasWidth, canvasHeight)
fill(1) # white background
rect(0, 0, canvasWidth, canvasHeight)
translate(margin, margin)
shadow((4, -4), 4, (0, 0, 0, 0.6))
for hPath in hPaths:
for vPath in vPaths:
piece = hPath & vPath # intersect
fill(random(), 0.7, random())
with savedState():
translate(wobble(10), wobble(10))
drawPath(piece)
saveImage("Puzzle.png")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.