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

**URL:** <https://forum.electromage.com/t/tiny-adjustment-to-spot-or-wide-color-picker-toroid-wrap-around/1681>\
**Category:** Patterns and Code\
**Created:** [October 26, 2021, 9:01pm UTC](https://forum.electromage.com/t/tiny-adjustment-to-spot-or-wide-color-picker-toroid-wrap-around/1681 "2021-10-26T21:01:47Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![danner](https://forum.electromage.com/user_avatar/forum.electromage.com/danner/32/1607_2.png) [@danner](https://forum.electromage.com/u/danner)\
**Post date:** [October 26, 2021, 9:01pm UTC](https://forum.electromage.com/t/tiny-adjustment-to-spot-or-wide-color-picker-toroid-wrap-around/1681/1 "2021-10-26T21:01:47Z")

</div>

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!

```auto
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)
}

```

---

<div class="post-metadata">

**Author:** ![Scruffynerf](https://forum.electromage.com/letter_avatar_proxy/v4/letter/s/34f0e0/32.png) [@Scruffynerf](https://forum.electromage.com/u/Scruffynerf)\
**Post date:** [October 26, 2021, 11:46pm UTC](https://forum.electromage.com/t/tiny-adjustment-to-spot-or-wide-color-picker-toroid-wrap-around/1681/2 "2021-10-26T23:46:17Z")

</div>

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:

> **[Calculating the Distance Between Points in “Wrap Around” (Toroidal) Space](https://blog.demofox.org/2017/10/01/calculating-the-distance-between-points-in-wrap-around-toroidal-space/)**
>
> Let’s say you are trying to find the distance between two points in 2D, but that these points are in a universe that “wraps around” like old video games – leaving the screen…

Very helpful. Thanks!

---

<div class="post-metadata">

**Author:** ![wizard](https://forum.electromage.com/user_avatar/forum.electromage.com/wizard/32/4_2.png) [@wizard](https://forum.electromage.com/u/wizard)\
**Post date:** [October 27, 2021, 12:31am UTC](https://forum.electromage.com/t/tiny-adjustment-to-spot-or-wide-color-picker-toroid-wrap-around/1681/3 "2021-10-27T00:31:08Z")

</div>

Thats very close to what `triangle()` does.

---

<div class="post-metadata">

**Author:** ![Scruffynerf](https://forum.electromage.com/letter_avatar_proxy/v4/letter/s/34f0e0/32.png) [@Scruffynerf](https://forum.electromage.com/u/Scruffynerf)\
**Post date:** [October 27, 2021, 12:39am UTC](https://forum.electromage.com/t/tiny-adjustment-to-spot-or-wide-color-picker-toroid-wrap-around/1681/4 "2021-10-27T00:39:47Z")

</div>

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: `/\/\/\/\`

---

<div class="post-metadata">

**Author:** ![danner](https://forum.electromage.com/user_avatar/forum.electromage.com/danner/32/1607_2.png) [@danner](https://forum.electromage.com/u/danner)\
**Post date:** [October 27, 2021, 12:39am UTC](https://forum.electromage.com/t/tiny-adjustment-to-spot-or-wide-color-picker-toroid-wrap-around/1681/5 "2021-10-27T00:39:51Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![jeff](https://forum.electromage.com/user_avatar/forum.electromage.com/jeff/32/3473_2.png) [@jeff](https://forum.electromage.com/u/jeff)\
**Post date:** [October 27, 2021, 5:14am UTC](https://forum.electromage.com/t/tiny-adjustment-to-spot-or-wide-color-picker-toroid-wrap-around/1681/6 "2021-10-27T05:14:29Z")

</div>

> [@danner](#):
>
> are there speed differences that mean I should use internal functions vs doing it myself?

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

---

<div class="post-metadata">

**Author:** ![danner](https://forum.electromage.com/user_avatar/forum.electromage.com/danner/32/1607_2.png) [@danner](https://forum.electromage.com/u/danner)\
**Post date:** [October 27, 2021, 12:52pm UTC](https://forum.electromage.com/t/tiny-adjustment-to-spot-or-wide-color-picker-toroid-wrap-around/1681/7 "2021-10-27T12:52:53Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Scruffynerf](https://forum.electromage.com/letter_avatar_proxy/v4/letter/s/34f0e0/32.png) [@Scruffynerf](https://forum.electromage.com/u/Scruffynerf)\
**Post date:** [October 27, 2021, 2:03pm UTC](https://forum.electromage.com/t/tiny-adjustment-to-spot-or-wide-color-picker-toroid-wrap-around/1681/8 "2021-10-27T14:03:18Z")

</div>

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:

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

```

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

---

<div class="post-metadata">

**Author:** ![danner](https://forum.electromage.com/user_avatar/forum.electromage.com/danner/32/1607_2.png) [@danner](https://forum.electromage.com/u/danner)\
**Post date:** [October 27, 2021, 2:22pm UTC](https://forum.electromage.com/t/tiny-adjustment-to-spot-or-wide-color-picker-toroid-wrap-around/1681/9 "2021-10-27T14:22:27Z")

</div>

thanks! thus begins the descent into madness.

---

<div class="post-metadata">

**Author:** ![wizard](https://forum.electromage.com/user_avatar/forum.electromage.com/wizard/32/4_2.png) [@wizard](https://forum.electromage.com/u/wizard)\
**Post date:** [October 27, 2021, 6:49pm UTC](https://forum.electromage.com/t/tiny-adjustment-to-spot-or-wide-color-picker-toroid-wrap-around/1681/10 "2021-10-27T18:49:21Z")

</div>

@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:

```auto
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.
