Stick Puzzles

Generates a range of interlocking puzzles.  G. Hart.  Jan 2011, updated 2024
(Software to accompany my Bridges 2011 paper, “Symmetric Stick Puzzles”.)

Prism to connect two endpoints

mag[v_]:=Sqrt[v.v];
unit[v_]:=v/mag[v];
vP[i_,n_, r_, z_,alpha_]:=With[{p=(1/n-1/2)Pi},{r Cos[2 Pi i/n+p],alpha r Sin[2 Pi i/n+p],z}]//N;  (* vertex i of n-gon parallel to XY plane.  Phase p chosen so a flat is parallel to x axis *)
prism[n_,r_,h_,alpha_]:={      (* prism on polygon, from z=+/-h.  2 bases and n sides *)
Polygon[Table[vP[i,n,r,-h,alpha],{i,n,1,-1}]],
Polygon[Table[vP[i,n,r,h,alpha],{i,1,n}]],
Table[Polygon[{vP[i,n,r,-h,alpha],vP[i+1,n,r,-h,alpha],vP[i+1,n,r,h,alpha],vP[i,n,r,h,alpha]}],{i,1,n}]};
stick[{v0_,v1_},r_,n_,alpha_]:=Module[{newX,newY,newZ,transform},(
newY=unit[v0+v1];
newZ=unit[v1-v0];
newX=Cross[newY,newZ];
transform=Transpose[{newX,newY,newZ}];
GeometricTransformation[prism[n,r,mag[v1-v0],alpha],{transform,(v0+v1)/2}])]
polyChoices={"Cube","Dodecahedron","Tetrahedron","TruncatedIcosahedron"};
 sticks[nSides_,rad_,len_,rot_,alpha_]:=Table[Rotate[stick[{mid[i]+len dir[i],mid[i]-len dir[i]},rad,nSides,alpha ],rot Degree,mid[i]],{i,Length[e]}];
end[i_,j_]:=2v[[e[[i,j]]]];  (* edge i.  j is 1 or 2 for two ends *)
mid[i_]:=(end[i,1]+end[i,2])/2;  (* midpoint of edge i *)
dir[i_]:=end[i,1]-mid[i];  (* direction from midpoint to one end *)

Manipulate[(
v=PolyhedronData[p,"VertexCoordinates"]//N;   (* XYZ coords of vertices *)
     e=PolyhedronData[p,"EdgeIndices"];  (* list of edges, as pairs of indices into v *)
     g=Graphics3D[
{sticks[nSides,rad,len,rot,alpha],If[mirror,sticks[nSides,rad/2,len,-rot,alpha],{}]},
Boxed->False,SphericalRegion->True]
),
{{rad,.2},0.001,2},{{len,1},0.001,5},{{rot,0},-180,180,Appearance->"Labeled"},{{nSides,4},3,24,1,Appearance->"Labeled"},{p,polyChoices},{{alpha,1},0.1,10},{mirror,{False,True}}]

Export["stick-demo.stl",g]