Truncated-octahedron-based 3D-space-filling curve
This is an attempt to answer the question "is there a 3D analogue of the Gosper curve?", posed independently by Jeffrey Ventrella and Carlo Séquin. I don't claim to have found an exact analogue. I'm inclined to believe none such exists. But I have found a self-avoiding 3D-space-filling curve base on edge replacement, that uses non-orthogonal segment directions (unlike, say, 3D versions of the Hilbert curve), with all segments at a given level being of equal lengths — all (other than 3D) properties that the Gosper curve shares. I'm not aware of any other curves that check all these boxes; if anyone knows of any, please let me know.
It is based on Nan Ma's 27-cell recursive tiling of the stellated rhombic dodecahedron, using the body-centered cubic (bcc) lattice. My observation was that the Voronoi cell of this lattice is actually the truncated octahedron (TO), so the same tiling should work with TOs. It does, producing the same fractal surface (analogous to the Gosper island), with fractal dimension ( \log(13)/\log(3) \approx 2.3347 ).
Then, analogously to the way the Gosper curve uses edges between vertices of a hexagon (see below), we use edges between vertices of a TO. This is a plausible starting point, because in the 27-cell replacement scheme, the large TO vertices are coincident with small TO vertices (as you can see by checking the appropriate boxes below). Computer search verifies that there is an edge selection that admits a 27-segment path (yellow below) that traces similar edges on each component TO, starting and ending at the original edge (red) endpoints. In fact, there are two possible edges that work. Each has tens of thousands of path solutions; one of each is shown here. The edge is allowed to be rotated, reflected, and reversed. (Disallowing either reflection or reversal yields no solutions.) This path is the generator for a self-avoiding space-filling fractal curve, the first three levels of which are shown here. The red segment is replaced by the yellow path; each segment of that path is replaced recursively to yield the orange path; one level further yields the blue path.
Curves
Level 0
Level 1
Level 2
Level 3
Truncated octahedra
Level 0
Level 1
Level 2
For comparison, here is the generator for the Gosper curve, and some fractal Gosper islands (from Jeffrey Ventrella's post).
curve = ƒ(level)truncatedOctahedron = ƒ(color, scale, center, opacity)toCluster = ƒ(color, level, scale, center, opacity)triangulate = ƒ(vertices)makeVector3 = ƒ(scale, offset)curves = ƒ()colors = Array(4) [16711680, 16776960, 16744448, 255]shortEdgePoints = Array(4) [Array(2), Array(28), Array(730), Array(19684)]longEdgePoints = Array(4) [Array(2), Array(28), Array(730), Array(19684)]allPoints = Array(2) [Array(4), Array(4)]toVertices = Array(24) [Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), …]toFaces = Array(14) [Array(4), Array(4), Array(4), Array(4), Array(4), Array(4), Array(6), Array(6), Array(6), Array(6), Array(6), Array(6), Array(6), Array(6)]nodes = Array(27) [Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), Array(3), …]
Import statements:
import { [reusable3dCanvas](/content/@vorth/reusable-three-js-canvas#reusable3dCanvas/index.html), [THREE](/content/@vorth/reusable-three-js-canvas#THREE/index.html)} from ["@vorth/reusable-three-js-canvas"](/content/@vorth/reusable-three-js-canvas/index.html)
import { [slider](/content/@jashkenas/inputs#slider/index.html), [color](/content/@jashkenas/inputs#color/index.html), [radio](/content/@jashkenas/inputs#radio/index.html), [checkbox](/content/@jashkenas/inputs#checkbox/index.html)} from ["@jashkenas/inputs"](/content/@jashkenas/inputs/index.html)
import { [imageInput](/content/@mbostock/file-input#imageInput/index.html)} from ["@mbostock/file-input"](/content/@mbostock/file-input/index.html)