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
}
}
3 Likes