Concentric Rings/Circle Mapping

LOL, I was just writing a reply to check out Jason Coon… I see you are already aware of his stuff. His stuff looks hypnotic to me. I think I am putting a https://www.tindie.com/products/jasoncoon/fibonacci256-166mm-disc-with-256-ws2812b-rgb-led/ on my Christmas list :slight_smile:

Hi! Re: polar maps, I know you asked Wizard to explain, but I think I know what’s going on and can give it a try.

Wizard’s shown me a few times how you can use pixel maps as a generalized per-pixel attribute dictionary. For example, there was the recent thread where, if it was a 2D map, you could store extra information in ‘z’, such as a per-pixel brightness coefficient.

I think a polar map just means that you write a map such that the first per-pixel array element (normally x) stores r (distance), and y stores phi (angle). It won’t render correctly in the Mapping tab’s preview anymore, but you can consume it in a render2D as render2D(index, r, phi). Circles, spirals, and Spirograph-esque stuff would be a little faster than using the trig transforms.

Thanks for the big circular maps!

1 Like

Awesome, I sorta kinda was wondering if it was exactly like that, “abusing” pixel attributes that way. I’ll have to play with it. I keep finding areas barely hinted at in the existing examples.

I got in the 241 led circle array and Wow, it’s nice, especially for a meager $30 from Amazon.

1 Like

@Scruffynerf Please stop making me aware of new LED products at good prices. I compulsively purchase them with no project in mind.

5 Likes

I have no idea what you’re talking about. :wink:

1 Like

Jason’s latest: micro using tiny LEDs

https://www.reddit.com/gallery/jd0b5l

2 Likes

Did you read the part where he was using a microscope to place them?!

2 Likes

Just as a pointer to piles of neat info, related to the above

I found a pile of patterns I expect will be trivial to port to PB (if they don’t already exist)

1 Like

@jeff, whatever you do, don’t go look at
https://amazon.com/dp/B08KS4LXFD

3 wire, not 2 (non addressable single color) or 4 wire (non-addressable RGB), these are w2812 in a fairy wire (copper wire) setup, 66ft/200 led (so 30 led/m) also available perhaps cheaper from China (which I was going to do on 11.11 day sales, but decided to check Amazon… And yup, for next day delivery to me… Almost same price, instead of weeks of waiting? Sold.)

Ordered enough to build a massive 10x10x10 cube, and yet didn’t break the bank at all.

@Scruffynerf,
Those don’t look like addressable LEDs. I’d expect rainbows in the previews or mentions about repurposing in the reviews. I have seen RGB 3 wire fairy wire LEDs that are in some sort of charlieplexed configuration, which would be enough to drive the simple patterns shown in the photos. And the price is too good to be true.

There are serially addressable fairy wire LEDs out there, but I don’t think these are it.

Thanks for the heads up… I have something similar to share back. That link shows 200 for $20 shipped is $0.10 per pixel;

I can report decent results with this product from AliExpress. WS2812, $0.12 per pixel shipped, arrived in under three weeks from my order date.

They are, look at the video someone posted in the reviews and watch the chase sequence. Plus I did the research and found this elsewhere (AliExpress, similar to Jeff’s link above) with more details. BTF also makes similar for $13 for 50 LEDs no controller, and $20ish for either USB or battery box controller.

I’ll have these tomorrow and will confirm and even hook it up to PB. (I really need some more PBs, I was hoping for the v3s soon ish)

Yeah that video looks like addressables! I missed that before. I’m still skeptical, but I would be happy to hear confirmation when you get yours!

Confirmed. Cracked open the USB controller and it’s got 2 no name/ID 8 pin ICs (plus IR, etc) and the lines are labeled L+, L- and D. Many of the 15 effects are individually addressable across the string, like color each pixel red one at a time, till the strip is red, then change each pixel one at a time to green, then all to blue etc. Will hook up to a PB shortly. Right now, the one I opened is still in 2 round bundles of 100 as I plan how to layout it out on the 12 inch sphere (ok, it’s actually 2 round wire plant hangers, but damn for $20, look at the nifty 12 inch wire sphere…) The PB will be the most expensive part of this build. It even came with a USB wall wart (5v2a)

I’m going to move discussion of the above very cheap string to it’s own thread, due to some technical questions.

Heh, so glad I inspired Jeff to build his StarDisc.

My latest arrival on the pile of cool stuff (so many projects, and now I want to do them with videos…) is I snagged a “warehouse” (returned?) discounted (Amazon FTW) 576 pixel micro smd2020 ws2812 board, 18x32 pixels, PCB full of holes so it’s a mesh of LEDs (rigid)
Photo when I light it up.

I also got in some NLED Photon controllers for building a set of wand poi, and the HD107 sticks arrived for that (also photos when I light them up), along with the hd107 8x8 matrix. I got enough sticks of 8 to do multiple poi, and I also got enough PBs (I own 5 now, and 4 sensors) to turn two into poi as well (long down my list). Waiting for more poi bits though.

2 Likes

Found this tip on Reddit at Jason Coons latest ring project (1628 pixels)

Reddit user iscor said:

I recommend adding which “ring” the pixel belongs too as “z” coordinate in your Cartesian coordinate lookup table. I found using that value * 0.01 or so as the z value in noise adds a little extra to the standard 2D noise pattern

Another argument for non-concentric layout:

3d printed design, hopefully they’ll share the STL

1 Like

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