Concentric Rings/Circle Mapping

Do you think that was a 2-color print (black border between cells, and a translucent window above the LEDs)? Wild to watch!

I added the z-axis to this, turning it into a sphere! Tweak the layers var to make the sphere bigger/smaller. The amount of pixels required will be printed to the console, so you know what to set in the settings menus to get all of the pixels to light up with any 3D patterns.

/**
 * Author: Pixelplanetarorcus
 * 
 * Modified Scruffynerf's code at:
 * https://forum.electromage.com/t/concentric-rings-circle-mapping/649/11
 * 
 * The modifications makes it 3D. Spheres and prisms are now easier to simulate! 
**/

function (pixelCount) {
    var map = [];
    var rings = [1, 6] //Pattern is like, [x, y=y*2, y=y*2 ...]. Ie; [1,2,4,8,4,2,1], [1,3,6,12,6,3,1], ...
    var layers = 11 //How many layers! [1,2,4,8,4,2,1] is 7 layers for example. CHANGE THIS FOR MEGA FUN!
    var spaceBetweenRings = 0.9 // Affects total height of entire thing
    var ringTightness = 0.9 //Affects radius of rings
    var inwardwired = 0 // if outward, set to 0. it's far easier to calculate this mapping going outward. But if lights are wired inward, we'll reverse at the end
    console.clear() //For quickly getting current data without drowning in old data
    
    //layers = layers + 2 //I forgot why exactly I did this... Commented out in case the bug this killed comes back later.
    for(layer = 2; layer < layers - 3; layer++){ //Starting at 2 because the first two places in the layers array is defined.
            if(layer == (layers - 3)/2)
              rings.push(rings[layer-1] * 2) // if previous layer is x, push x*2
            else if(layer < (layers - 3) / 2)
              rings.push(rings[layer-1] * 2) //Grows bigger and bigger
            else
              rings.push(rings[layer-1] / 2) // Grows smaller and smaller
    }
    rings.push(1) // Bottom
    console.log(rings) // Prints the array, for quick sanity check.
    //https://stackoverflow.com/questions/3762589/fastest-javascript-summation
    console.log("Total pixels: " + (rings.reduce(function(pv, cv){return pv+cv},0))*2) //Why do I need to muiplity this by 2 to get the actual pixels? I'm bad at math!

    for (ring = 0; ring < layers; ring++) {
        if (rings[ring] == 0) {
            // no ring, just for spacing
        } else {
            for (i = inwardwired; i < rings[ring] + inwardwired; i++) {
                c = i / rings[ring] * Math.PI * 2 //Ring radius affected by i

                if (ring == Math.floor(layers / 2)) // Middle ring
                    map.push([0 - Math.cos(c) * (ring * ringTightness), 0 - Math.sin(c) * (ring * ringTightness), (layers / 2) * spaceBetweenRings])
                else if (ring < Math.floor(layers / 2)) { //Top to middle rings
                    if (rings[ring] == 1){
                          map.push([0, 0, (rings.length + 2)* spaceBetweenRings]) // Bottom
                    }
                    else
                        map.push([0 - Math.cos(c) * (ring * ringTightness), 0 - Math.sin(c) * (ring * ringTightness), (ring * spaceBetweenRings)])
                }

                if (ring < Math.floor(layers / 2)) { // Middle to bottom rings
                    if (rings[ring] == 1)
                        map.push([0, 0, 0]) //Top
                    else {
                        c = (i - rings[ring]) / rings[ring] * Math.PI * 2 //Start shrinking radius
                        map.push([0 - Math.cos(c) * (ring * ringTightness), 0 - Math.sin(c) * (ring * ringTightness), (layers - ring) * spaceBetweenRings])
                    }
                }
            }
        }
    }
    
    if (inwardwired) {
        return map.reverse(); //flip the map, so pixel order runs inward
    } else {
        return map; // outward is correct
    }
}
2 Likes