Tiny adjustment to spot or wide color picker: Toroid/wrap around

It’s a little fix for my room where the lights wrap around the ceiling, but the spot stops abruptly at the beginning or end of the pixel array.

It’s got a fancy name at least, toroidal distance measurement!

export function render(index) {
  distance = abs(location - index/pixelCount)
  if (distance > 0.5){
    distance = 1.0 - distance
  }
  var v = value * pow(1 - distance, sharpness)
  hsv(hue, saturation, v)
}

1 Like

I had to look up what you meant.

In plain English:

When dealing with circles (or closed loops, or donuts or…), this avoids the start or end of the led strand from being an edge/end and calculates the distance as if it wasn’t…

It finds the shortest distance between two points, when there is more than one direction you could go.

Better:

Very helpful. Thanks!

1 Like

Thats very close to what triangle() does.

2 Likes

Oooh, that’s a well hidden fact.

So let’s see… time() cycles from 0 to 1 and repeats. A sawtooth: /////

triangle() takes that cycle and converts it from a sawtooth into a triangular wave: /\/\/\/\

oh cool! This is my first time coding for pixelblaze, I’ll play around with triangle() - not that this pattern needs to be performant, but are there speed differences that mean I should use internal functions vs doing it myself?

1 Like

Almost always! It’s one reason we commonly request new functions. :wink:

1 Like

alas, I couldn’t figure out a way to use triangle() to make this wrap around behavior. I think it’s possible, somehow stretching the triangle, but I couldn’t think of it last night, so it’ll stay with the if statement for now.

1 Like

Yeah, I racked my brain to convert your code to it. I believe (and hopefully @wizard will correct me if I’m wrong) triangle() will (in essence) convert 0-0.5 values to 0-1 (effectively multiply by 2), and convert .5-1 values to 1-0 (= 2 - value x2)

Your code says “if distance is greater than .5, distance is equal to 1 - distance” so you’re have to divide triangle(distance) by two to get your desired result.

Replacement code:

distance = triangle(abs(location - index/pixelCount))/2

Should be slightly faster, but also far less casually understandable.

1 Like

thanks! thus begins the descent into madness.

@danner your version is great! I didn’t mean that as a criticism, I think its awesome that you figured out how to get the effect you were looking for!

I wanted to share that triangle does that same kind of thing – ramps up, then back down (just scaled to 0-1) – in case it comes in handy for you later. I use that kind of thing so often it became one of the original Pixelblaze animation tools / APIs.

You can see a similar thing in “fast pulse,” which will wrap, the core if that pattern (for 1D) is this:

v = triangle(2 * wave(t1) + index / pixelCount)

The base structure of the triangle is triangle(index/pixelCount) which would start low, go high toward the middle, and back down.

It animates that back and forth by adding this offset: 2 * wave(t1), which is like changing the spotlight’s position with a slider but animates based on the t1 timer. The * 2 causes to to spin twice over before returning, and triangle() wraps values to the 0-1 range so you can keep adding in components.

1 Like