A pyramid

There are three main sources of geometries. You can import them as a model in some standard 3D format. Imported models are usually complex and are usually developed using a modeling program. Or you can use a library function for generating geometries. Such functions exist for highly regular geometries such as spheres, cylinders, icosahedra, and teapots. Or you can define them yourself using the Geometry class. When we create them ourselves by hand so to speak, we take advantage of whatever pattern and regularity the geometry might have.

As an example, we’ll write a function that generates the geometry of an n-sided pyramid. It is centered at the origin and aligned with the vertical y-axis, and its base, a regular n-gon, lies below the xz-plane (or floor) and its apex lies above. We’ll start with just the n sides and add the bottom in the page that follows. In the scene below I’ve added labels indicating each vertex’s index. This is the order in which they get added to the geometry’s vertices array and (hence) how we refer to the vertices when we build the faces.

A pyramid

In total, there are n+1 vertices. The vertex at the apex is labelled 0, and the remaining vertices 1, 2, …, n occur at regular intervals around the base. The function that follows first creates the n+1 vertices and pushes them into the vertices array, and then builds the n triangles on these vertices. These triangles are built on n triples of vertices: 2,1,0; 3,2,0; 4,3,0; …, n,n-1,0; 1,n,0. They form a fan centered on the apex 0. Here’s the code:

function createPyramid(n, rad, len) {
    let len2 = len / 2;  // half the pyramid's height
    let geom = new THREE.Geometry();
    // push n + 1 vertices
    //  first the apex...
    geom.vertices.push(new THREE.Vector3(0, len2, 0));
    //  ... and then the n vertices of the base
    let inc = 2 * Math.PI / n;
    for (let i = 0, a = 0; i < n; i++, a += inc) {
        let cos = Math.cos(a);
        let sin = Math.sin(a);
        geom.vertices.push(new THREE.Vector3(rad*cos, -len2, rad*sin));
    }
    // push the n triangular faces...
    for (let i = 1; i < n; i++) {
        let face = new THREE.Face3(i+1, i, 0);
        geom.faces.push(face);
    }
    let face = new THREE.Face3(1, n, 0);
    geom.faces.push(face);

    // BASE CODE GOES HERE

    // set face normals and return the geometry
    geom.computeFaceNormals();
    return geom;
}

To turn the open pyramid into a closed pyramid, we add the faces that make up the base. An n-sided base is formed from n-2 triangles: A 3-sided base is made of 1 triangle, and whenever we increase the number of sides by one we add one more triangle. Structurally, we form a fan of triangles originating at some vertex (here we use vertex 1 as the fan’s center). The n-2 base triangles are built on n-2 triples of vertices: 2,3,1; 3,4,1; 4,5,1; …; n-1,n,1. Note each triangle has a counter-clockwise sense of rotation when viewed from outside (below) the pyramid.

To construct the base, we replace the BASE CODE GOES HERE comment that appears in the code above:

    for (let i = 2; i < n; i++) {
        let face = new THREE.Face3(i, i+1, 1);
        geom.faces.push(face);
    }

Here is the completed closed pyramid, with its triangulation.

Closed pyramid