Platonic rings

We called our createRing program with a scene graph obj representing a 2D slab of cubes. The program cloned obj multiple times and rotated each copy into place. In effect, it added each rotated copy of obj into a larger scene graph. But suppose we want a series of objects rotated around a common axis but we want the objects to vary. In this case, repeatedly adding clones of the same object will not do.

One way to achieve this is to write a createRingF function that gets called with an ‘object construction’ function fnc. Every time createRingF needs to rotate another object into place, it calls fnc to get a new object. The difference is that createRingF gets new objects by calling fnc rather than cloning the same object repeatedly as is done in createRing.

function createRingF(fnc, n, t) {
    let root = new THREE.Object3D();
    let angleStep = 2 * Math.PI / n;
    for (let i = 0, a = 0; i < n; i++, a += angleStep) {
        let s = new THREE.Object3D();
        s.rotation.y = a;
        let m = fnc(i, n);
        m.position.x = t;
        s.add(m);
        root.add(s);
    }
    return root;
}

Note createRingF‘s similarity to createRing. Really, the only difference is in the object-creation call on line 7.

To test createRingF, we write an object-creation function that generates each of the five Platonic solids in turn.

function makeSolidsFnc() {
    const solids = [
           new THREE.TetrahedronGeometry(1),
           new THREE.BoxGeometry(1, 1, 1),
           new THREE.OctahedronGeometry(1),
           new THREE.IcosahedronGeometry(1),
           new THREE.DodecahedronGeometry(1)
    ];
    const nbrSolids = solids.length;
    function f(i, n) {
        let geom = solids[i % nbrSolids];
        let color = new THREE.Color().setHSL(i/n, 1.0, 0.5);
        let args = {color: color, opacity: 0.8, transparent: true};
        let mat = new THREE.MeshLambertMaterial(args);
        return new THREE.Mesh(geom, mat);
    }
    return f;
}

let solidsFnc = makeSolidsFnc();

Here, solidsFnc(i, n) returns the Platonic solid indexed by i%5 (the array solids is indexed by integers 0 through 4). Where n meshes are produced in total, the i’th mesh is assigned the hue i/n, where hues range across the color spectrum as values go from 0 to 1. This is how we get the rainbow effect.

Calling createRing(solidsFnc, 20, 10) produces the ring shown in this program:

Platonic ring