A spider web is mostly a 2D drawing. A 3D-printable bowl is a 3D shape. The trick in this post is to draw the web as a flat CrossSection, extrude it straight down, and subtract it from a bowl shell. The same trick works for any pattern: leaves, stars, bats. Everything uses manifold3d and plain Python.
1. A bowl from two spheres
A shallow bowl is a spherical cap. For a cap of rim radius Rb and height H, the sphere radius is Rs = (Rb^2 + H^2) / (2 H).
from manifold3d import Manifold, CrossSection as CS
Rb, H = 52.0, 30.0
Rs = (Rb * Rb + H * H) / (2 * H)
def sph(r, zc):
return Manifold.sphere(r, 96).translate([0, 0, zc])
shell = (sph(Rs, Rs) - sph(Rs - 2.8, Rs)).trim_by_plane([0, 0, -1], -H)
shell = shell + Manifold.cylinder(2.8, 16, 16, 64) # flat foot to print on
trim_by_plane keeps the side the normal points to. The normal [0, 0, -1] with offset -H keeps everything below z = H.
2. Draw the web in 2D
A thread is a thin rectangle rotated to an angle. Spokes run from the centre. Each ring is a polygon with a small inward kink on every segment, so the threads sag like a real web.
import math
def thread(a, b, w=2.6):
dx, dy = b[0] - a[0], b[1] - a[1]
ang = math.degrees(math.atan2(dy, dx))
return CS.square([math.hypot(dx, dy), w]).translate([0, -w / 2]).rotate(ang).translate(list(a))
web = CS()
n = 12
for i in range(n):
a = math.radians(i * 360 / n)
web = web + thread((0, 0), (70 * math.cos(a), 70 * math.sin(a)))
for rr in (11, 20, 29, 38):
for i in range(n):
a0, a1 = math.radians(i * 360 / n), math.radians((i + 1) * 360 / n)
am = (a0 + a1) / 2
p = (rr * math.cos(a0), rr * math.sin(a0))
q = (rr * math.cos(a1), rr * math.sin(a1))
m = (rr * 0.93 * math.cos(am), rr * 0.93 * math.sin(am)) # sag
web = web + thread(p, m) + thread(m, q)
web = web + CS.circle(7, 48) + (CS.circle(60, 128) - CS.circle(45, 128)) # hub and rim
3. Cut it through the bowl
The holes are everything inside the rim that is not thread.
holes = CS.circle(46, 128) - web
bowl = shell - holes.extrude(H + 10).translate([0, 0, -3])
bowl = max(bowl.decompose(), key=lambda m: m.volume()) # drop loose bits
Because the cut goes straight down, the threads on the steep sides look slightly flattened and thicker. That is fine for a bowl and gives the web depth.
Gotchas
- Every thread must touch the hub or the rim. A thread that touches nothing becomes a loose piece, and
decomposethrows it away. -
Manifoldhas no.intersectmethod. Use^for intersection,+for union and-for difference. - Keep thread width at 2.4 mm or more for a 0.4 mm nozzle (six perimeters is overkill, but anything under 1.6 mm snaps).
- Swap the web for 26 leaf shapes placed at the golden angle (
137.508degrees, radius6 + 40 * sqrt((i + 0.5) / n)) and you get a fall leaf bowl from the same code.
I have not test printed these yet. The renders look right and the meshes are one manifold solid. The finished spider web bowl and the leaf bowl are on Cults3D.
Top comments (0)