donut

radius = 300 circle_size = 300 step = 3 x, y = 500, 500 fill(1) stroke(0) for d in range(0, 360, step): circle1 = BezierPath() circle1.oval(x  circle_size / 2, y  circle_size / 2, circle_size, circle_size) circle1.translate(0, radius) circle1.rotate(d, (x, y)) circle2 = BezierPath() circle2.oval(x  circle_size / 2, y  circle_size / 2, circle_size, circle_size) circle2.translate(0, radius) circle2.rotate(d + step, (x, y)) dif = circle2.difference(circle1) drawPath(dif)
In response to https://twitter.com/MauriceMeilleur/status/1242196482717110274

Wim, thanks—as soon as I get a chance I'll see if this works for me. A potential problem is that I'll have polygons (not just triangles but squares, pentagons, etc) rotating, which means that any given shape in the larger figure will be interacting with multiple other shapes in changing ways.

An arbitrary amount of circles seemingly overlapping:
import random number_of_circles = 10 radius = 100 wobble = 400 canvas_size = 1000 circles = [] drawn_circles = [] center = canvas_size / 2 # Create circles for i in range(number_of_circles): x = center  (wobble * 0.5) + random.random() * wobble y = center  (wobble * 0.5) + random.random() * wobble circle = BezierPath() circle.oval(x  radius, y  radius, radius * 2, radius * 2) circles.append(circle) # Check if circles overlap for circle in circles: for i in range(len(drawn_circles)): intersecting_shape = circle.intersection(circles[i]) if len(intersecting_shape.points) > 0: circle = circle.difference(circles[i]) drawn_circles.append(circle) # Draw circles, or what’s left of them newPage(canvas_size, canvas_size) fill(None) stroke(0) for circle in drawn_circles: drawPath(circle)