JSXGraph logo
JSXGraph
JSXGraph share

Share

3D subdivided icosahedron
QR code
<iframe 
    src="https://www.jsxgraph.org/share/iframe/3d-subdivided-icosahedron" 
    style="border: 1px solid black; overflow: hidden; width: 550px; aspect-ratio: 55 / 65;" 
    name="JSXGraph example: 3D subdivided icosahedron" 
    allowfullscreen
></iframe>
This code has to
<div id="board-0-wrapper" class="jxgbox-wrapper " style="width: 100%; ">
   <div id="board-0" class="jxgbox" style="aspect-ratio: 1 / 1; width: 100%;" data-ar="1 / 1"></div>
</div>

<script type = "text/javascript"> 
    /*
    This example is licensed under a 
    Creative Commons Attribution ShareAlike 4.0 International License.
    https://creativecommons.org/licenses/by-sa/4.0/
    
    Please note you have to mention 
    The Center of Mobile Learning with Digital Technology
    in the credits.
    */
    
    const BOARDID = 'board-0';

    const board = JXG.JSXGraph.initBoard(BOARDID, {
        boundingbox: [-8, 8, 8, -8],
        minimizeReflow: 'svg',
        axis: false,
        zoom: {
            enabled: false
        },
        pan: {
            enabled: false
        }
    });
    
    var view = board.create(
        'view3d',
                [[-5, -3], [8, 8],
                [[-3, 3], [-3, 3], [-3, 3]]],
        {
            projection: 'central',
            trackball: { enabled: true },
            depthOrder: {
                enabled: true
            },
            xPlaneRear: { visible: false },
            yPlaneRear: { visible: false },
            zPlaneRear: { fillOpacity: 0.2, visible: true }
        }
    );
    
    // Basic icosahedron
    let rho = 1.6180339887;
    let vertexList = [
                [0, -1, -rho], [0, +1, -rho], [0, -1, rho], [0, +1, rho],
                [1, rho, 0], [-1, rho, 0], [1, -rho, 0], [-1, -rho, 0],
                [-rho, 0, 1], [-rho, 0, -1], [rho, 0, 1], [rho, 0, -1]
            ];
    let faceArray = [
                [4, 1, 11],
                [11, 1, 0],
                [6, 11, 0],
                [0, 1, 9],
                [11, 10, 4],
                [9, 1, 5],
                [8, 9, 5],
                [5, 3, 8],
                [6, 10, 11],
                [2, 3, 10],
                [2, 10, 6],
                [8, 3, 2],
                [3, 4, 10],
                [7, 8, 2],
                [9, 8, 7],
                [0, 9, 7],
                [4, 3, 5],
                [5, 1, 4],
                [0, 7, 6],
                [7, 2, 6]
            ];
    
    // Midpoint between two vertices
    let midPoint = (p1, p2) => [(p2[0] + p1[0]) * 0.5, (p2[1] + p1[1]) * 0.5, (p2[2] + p1[2]) * 0.5];
    
    // Normalize a vector (set it to length 1)
    let v3Unit = (v) => {
        let len = JXG.Math.hypot(v[0], v[1], v[2]);
        return [v[0] / len, v[1] / len, v[2] / len];
    };
    
    let newFaceArray = [];
    
    // Iterate the construction
    let iterations = 3;
    for (let j = 0; j < iterations; j++) {
        newFaceArray = [];
        for (let i = 0; i < faceArray.length; i++) {
            let f = faceArray[i];
    
            // Add three new points at the midpoint of each vertex
            let m0 = midPoint(vertexList[f[1]], vertexList[f[2]]);
            let m1 = midPoint(vertexList[f[0]], vertexList[f[2]]);
            let m2 = midPoint(vertexList[f[0]], vertexList[f[1]]);
    
            let radius = 2;
    
            let p0 = vertexList.push(v3Unit(m0).map((n) => n * radius)) -
                1; // New vertex point on surface of sphere through centroid and origin
            let p1 = vertexList.push(v3Unit(m1).map((n) => n * radius)) - 1;
            let p2 = vertexList.push(v3Unit(m2).map((n) => n * radius)) - 1;
    
            // now four faces - the three corner-to-midpoints and then all three midpoints
            newFaceArray.push([f[0], p2, p1]);
            newFaceArray.push([f[1], p0, p2]);
            newFaceArray.push([f[2], p1, p0]);
            newFaceArray.push([p0, p1, p2]);
        }
        faceArray = newFaceArray; // In case we go around again
    }
    
    var ico = view.create('polyhedron3d', [vertexList, faceArray], {
        fillColorArray: [],
        fillOpacity: 1,
        strokeWidth: 0.1,
        layer: 12,
        shader: {
            enabled: true,
            type: 'angle',
            hue: 0,
            saturation: 90,
            minlightness: 60,
            maxLightness: 80
        }
    });
 </script> 
/*
This example is licensed under a 
Creative Commons Attribution ShareAlike 4.0 International License.
https://creativecommons.org/licenses/by-sa/4.0/

Please note you have to mention 
The Center of Mobile Learning with Digital Technology
in the credits.
*/

const BOARDID = 'your_div_id'; // Insert your id here!

const board = JXG.JSXGraph.initBoard(BOARDID, {
    boundingbox: [-8, 8, 8, -8],
    minimizeReflow: 'svg',
    axis: false,
    zoom: {
        enabled: false
    },
    pan: {
        enabled: false
    }
});

var view = board.create(
    'view3d',
            [[-5, -3], [8, 8],
            [[-3, 3], [-3, 3], [-3, 3]]],
    {
        projection: 'central',
        trackball: { enabled: true },
        depthOrder: {
            enabled: true
        },
        xPlaneRear: { visible: false },
        yPlaneRear: { visible: false },
        zPlaneRear: { fillOpacity: 0.2, visible: true }
    }
);

// Basic icosahedron
let rho = 1.6180339887;
let vertexList = [
            [0, -1, -rho], [0, +1, -rho], [0, -1, rho], [0, +1, rho],
            [1, rho, 0], [-1, rho, 0], [1, -rho, 0], [-1, -rho, 0],
            [-rho, 0, 1], [-rho, 0, -1], [rho, 0, 1], [rho, 0, -1]
        ];
let faceArray = [
            [4, 1, 11],
            [11, 1, 0],
            [6, 11, 0],
            [0, 1, 9],
            [11, 10, 4],
            [9, 1, 5],
            [8, 9, 5],
            [5, 3, 8],
            [6, 10, 11],
            [2, 3, 10],
            [2, 10, 6],
            [8, 3, 2],
            [3, 4, 10],
            [7, 8, 2],
            [9, 8, 7],
            [0, 9, 7],
            [4, 3, 5],
            [5, 1, 4],
            [0, 7, 6],
            [7, 2, 6]
        ];

// Midpoint between two vertices
let midPoint = (p1, p2) => [(p2[0] + p1[0]) * 0.5, (p2[1] + p1[1]) * 0.5, (p2[2] + p1[2]) * 0.5];

// Normalize a vector (set it to length 1)
let v3Unit = (v) => {
    let len = JXG.Math.hypot(v[0], v[1], v[2]);
    return [v[0] / len, v[1] / len, v[2] / len];
};

let newFaceArray = [];

// Iterate the construction
let iterations = 3;
for (let j = 0; j < iterations; j++) {
    newFaceArray = [];
    for (let i = 0; i < faceArray.length; i++) {
        let f = faceArray[i];

        // Add three new points at the midpoint of each vertex
        let m0 = midPoint(vertexList[f[1]], vertexList[f[2]]);
        let m1 = midPoint(vertexList[f[0]], vertexList[f[2]]);
        let m2 = midPoint(vertexList[f[0]], vertexList[f[1]]);

        let radius = 2;

        let p0 = vertexList.push(v3Unit(m0).map((n) => n * radius)) -
            1; // New vertex point on surface of sphere through centroid and origin
        let p1 = vertexList.push(v3Unit(m1).map((n) => n * radius)) - 1;
        let p2 = vertexList.push(v3Unit(m2).map((n) => n * radius)) - 1;

        // now four faces - the three corner-to-midpoints and then all three midpoints
        newFaceArray.push([f[0], p2, p1]);
        newFaceArray.push([f[1], p0, p2]);
        newFaceArray.push([f[2], p1, p0]);
        newFaceArray.push([p0, p1, p2]);
    }
    faceArray = newFaceArray; // In case we go around again
}

var ico = view.create('polyhedron3d', [vertexList, faceArray], {
    fillColorArray: [],
    fillOpacity: 1,
    strokeWidth: 0.1,
    layer: 12,
    shader: {
        enabled: true,
        type: 'angle',
        hue: 0,
        saturation: 90,
        minlightness: 60,
        maxLightness: 80
    }
});
<jsxgraph width="100%" aspect-ratio="1 / 1" title="3D subdivided icosahedron" description="This construction was copied from JSXGraph examples database: BTW HERE SHOULD BE A GENERATED LINKuseGlobalJS="false">
   /*
   This example is licensed under a 
   Creative Commons Attribution ShareAlike 4.0 International License.
   https://creativecommons.org/licenses/by-sa/4.0/
   
   Please note you have to mention 
   The Center of Mobile Learning with Digital Technology
   in the credits.
   */
   
   const board = JXG.JSXGraph.initBoard(BOARDID, {
       boundingbox: [-8, 8, 8, -8],
       minimizeReflow: 'svg',
       axis: false,
       zoom: {
           enabled: false
       },
       pan: {
           enabled: false
       }
   });
   
   var view = board.create(
       'view3d',
               [[-5, -3], [8, 8],
               [[-3, 3], [-3, 3], [-3, 3]]],
       {
           projection: 'central',
           trackball: { enabled: true },
           depthOrder: {
               enabled: true
           },
           xPlaneRear: { visible: false },
           yPlaneRear: { visible: false },
           zPlaneRear: { fillOpacity: 0.2, visible: true }
       }
   );
   
   // Basic icosahedron
   let rho = 1.6180339887;
   let vertexList = [
               [0, -1, -rho], [0, +1, -rho], [0, -1, rho], [0, +1, rho],
               [1, rho, 0], [-1, rho, 0], [1, -rho, 0], [-1, -rho, 0],
               [-rho, 0, 1], [-rho, 0, -1], [rho, 0, 1], [rho, 0, -1]
           ];
   let faceArray = [
               [4, 1, 11],
               [11, 1, 0],
               [6, 11, 0],
               [0, 1, 9],
               [11, 10, 4],
               [9, 1, 5],
               [8, 9, 5],
               [5, 3, 8],
               [6, 10, 11],
               [2, 3, 10],
               [2, 10, 6],
               [8, 3, 2],
               [3, 4, 10],
               [7, 8, 2],
               [9, 8, 7],
               [0, 9, 7],
               [4, 3, 5],
               [5, 1, 4],
               [0, 7, 6],
               [7, 2, 6]
           ];
   
   // Midpoint between two vertices
   let midPoint = (p1, p2) => [(p2[0] + p1[0]) * 0.5, (p2[1] + p1[1]) * 0.5, (p2[2] + p1[2]) * 0.5];
   
   // Normalize a vector (set it to length 1)
   let v3Unit = (v) => {
       let len = JXG.Math.hypot(v[0], v[1], v[2]);
       return [v[0] / len, v[1] / len, v[2] / len];
   };
   
   let newFaceArray = [];
   
   // Iterate the construction
   let iterations = 3;
   for (let j = 0; j < iterations; j++) {
       newFaceArray = [];
       for (let i = 0; i < faceArray.length; i++) {
           let f = faceArray[i];
   
           // Add three new points at the midpoint of each vertex
           let m0 = midPoint(vertexList[f[1]], vertexList[f[2]]);
           let m1 = midPoint(vertexList[f[0]], vertexList[f[2]]);
           let m2 = midPoint(vertexList[f[0]], vertexList[f[1]]);
   
           let radius = 2;
   
           let p0 = vertexList.push(v3Unit(m0).map((n) => n * radius)) -
               1; // New vertex point on surface of sphere through centroid and origin
           let p1 = vertexList.push(v3Unit(m1).map((n) => n * radius)) - 1;
           let p2 = vertexList.push(v3Unit(m2).map((n) => n * radius)) - 1;
   
           // now four faces - the three corner-to-midpoints and then all three midpoints
           newFaceArray.push([f[0], p2, p1]);
           newFaceArray.push([f[1], p0, p2]);
           newFaceArray.push([f[2], p1, p0]);
           newFaceArray.push([p0, p1, p2]);
       }
       faceArray = newFaceArray; // In case we go around again
   }
   
   var ico = view.create('polyhedron3d', [vertexList, faceArray], {
       fillColorArray: [],
       fillOpacity: 1,
       strokeWidth: 0.1,
       layer: 12,
       shader: {
           enabled: true,
           type: 'angle',
           hue: 0,
           saturation: 90,
           minlightness: 60,
           maxLightness: 80
       }
   });
</jsxgraph>

3D subdivided icosahedron

Iterating the icosahedron construction quickly approximates a sphere. The small dips are by purpose, i.e. the wrong choice of the radius, to demonstrate the shading effect.
// Define the id of your board in BOARDID

const board = JXG.JSXGraph.initBoard(BOARDID, {
    boundingbox: [-8, 8, 8, -8],
    minimizeReflow: 'svg',
    axis: false,
    zoom: {
        enabled: false
    },
    pan: {
        enabled: false
    }
});

var view = board.create(
    'view3d',
            [[-5, -3], [8, 8],
            [[-3, 3], [-3, 3], [-3, 3]]],
    {
        projection: 'central',
        trackball: { enabled: true },
        depthOrder: {
            enabled: true
        },
        xPlaneRear: { visible: false },
        yPlaneRear: { visible: false },
        zPlaneRear: { fillOpacity: 0.2, visible: true }
    }
);

// Basic icosahedron
let rho = 1.6180339887;
let vertexList = [
            [0, -1, -rho], [0, +1, -rho], [0, -1, rho], [0, +1, rho],
            [1, rho, 0], [-1, rho, 0], [1, -rho, 0], [-1, -rho, 0],
            [-rho, 0, 1], [-rho, 0, -1], [rho, 0, 1], [rho, 0, -1]
        ];
let faceArray = [
            [4, 1, 11],
            [11, 1, 0],
            [6, 11, 0],
            [0, 1, 9],
            [11, 10, 4],
            [9, 1, 5],
            [8, 9, 5],
            [5, 3, 8],
            [6, 10, 11],
            [2, 3, 10],
            [2, 10, 6],
            [8, 3, 2],
            [3, 4, 10],
            [7, 8, 2],
            [9, 8, 7],
            [0, 9, 7],
            [4, 3, 5],
            [5, 1, 4],
            [0, 7, 6],
            [7, 2, 6]
        ];

// Midpoint between two vertices
let midPoint = (p1, p2) => [(p2[0] + p1[0]) * 0.5, (p2[1] + p1[1]) * 0.5, (p2[2] + p1[2]) * 0.5];

// Normalize a vector (set it to length 1)
let v3Unit = (v) => {
    let len = JXG.Math.hypot(v[0], v[1], v[2]);
    return [v[0] / len, v[1] / len, v[2] / len];
};

let newFaceArray = [];

// Iterate the construction
let iterations = 3;
for (let j = 0; j < iterations; j++) {
    newFaceArray = [];
    for (let i = 0; i < faceArray.length; i++) {
        let f = faceArray[i];

        // Add three new points at the midpoint of each vertex
        let m0 = midPoint(vertexList[f[1]], vertexList[f[2]]);
        let m1 = midPoint(vertexList[f[0]], vertexList[f[2]]);
        let m2 = midPoint(vertexList[f[0]], vertexList[f[1]]);

        let radius = 2;

        let p0 = vertexList.push(v3Unit(m0).map((n) => n * radius)) -
            1; // New vertex point on surface of sphere through centroid and origin
        let p1 = vertexList.push(v3Unit(m1).map((n) => n * radius)) - 1;
        let p2 = vertexList.push(v3Unit(m2).map((n) => n * radius)) - 1;

        // now four faces - the three corner-to-midpoints and then all three midpoints
        newFaceArray.push([f[0], p2, p1]);
        newFaceArray.push([f[1], p0, p2]);
        newFaceArray.push([f[2], p1, p0]);
        newFaceArray.push([p0, p1, p2]);
    }
    faceArray = newFaceArray; // In case we go around again
}

var ico = view.create('polyhedron3d', [vertexList, faceArray], {
    fillColorArray: [],
    fillOpacity: 1,
    strokeWidth: 0.1,
    layer: 12,
    shader: {
        enabled: true,
        type: 'angle',
        hue: 0,
        saturation: 90,
        minlightness: 60,
        maxLightness: 80
    }
});

license

This example is licensed under a Creative Commons Attribution ShareAlike 4.0 International License.
Please note you have to mention The Center of Mobile Learning with Digital Technology in the credits.