Cantor snowflakes

To produce 3D Sierpinski cubes and other fractals, we used this process: A level 0 set is defined by some shape P. To construct a level n+1 fractal, recursively construct a level n fractal and then translate scaled-down copies of it, guided by P. For example, for the 2D Cantor set, P is a square, and level n+1 Cantor sets are formed by translating scaled-down level n Cantor sets to the four vertices of the square.

In fact, where P is any convex polyhedron, and we can translate scaled-down copies of a fractal built on P to the vertices of P.1a[/latex] and b belonging to the shape, the line segment \bar{ab} also lies in the shape. Filled circles (disks), filled spheres (balls), and filled Platonic solids are convex, whereas circles, spheres, toroids, and human bodies are non-convex.] The following program builds fractals in this way on different convex polyhedra.

Cantor snowflakes

We construct fractals in this way using the makeSnowflake function, which gets called with the level of the target fractal, the scale-down factor, and the geometry of polyhedron P. The geometry is used for two purposes. First, we construct a mesh on it for the level 0 set. Second, the geometry’s vertices are the positions to which we translate scaled-down copies of the level n sets. In the following function, the global variable mat (line 3) references a shared material.

function makeSnowflake(level, scale, geom) {
    if (level === 0) {
        return new THREE.Mesh(geom, mat);
    } else {
        let root = new THREE.Object3D();
        root.scale.set(scale, scale, scale);
        let tf = (1 - scale) / scale;
        for (let v of geom.vertices) {
            let root2 = new THREE.Object3D();
            let v2 = v.clone().multiplyScalar(tf);
            root2.position.set(v2.x, v2.y, v2.z); 
            root2.add(makeSnowflake(level-1, scale, geom));
            root.add(root2);
        }
        return root;
    }
}

In the previous function, root is the scaled-down space to which the recursively constructed fractals F are added, one for each vertex v of the geometry. Fractal F is translated by \frac{1-s}{s}v for every vertex v, where s equals scale. Since F is scaled down by a factor of s, we translate it by (1-s)v; but we must also divide by s since translation occurs in the scaled-down space of root (lines 7 and 10).

The program constructs fractals for a range of convex polyhedra: The five Platonic solids, two Archimidean solids, and three Johnson solids (from the top of the shape dropdown menu). Geometry for Platonic solids are included in threejs, whereas geometry for the Archimidean and Johnson solids are from two super web sites: Lee Stemkoski’s polyhedra page, which in turn credits George W. Hart’s Virtual Polyhedra: The Encyclopedia of Polyhedra site for the data.

  1. A shape is convex if, for any two points [latex