Here are some patterns and a 3D map generator I made last year that look pretty good on a tree.

A few are new; many are existing patterns adapted for this map. All are slowed down. We wanted more subtle fades that don’t distract you when doing other things in the same room.

### Code

In order to not clutter the pattern library, here’s a:

- .zip file of the individual patterns as .epes
- Full .pbb backup archive - use this with a Pixelblaze standard. Restoring this will overwrite all your patterns.

### Map

The map is mostly a stack of rings. This worked well even though it was more like a spiral cone in practice. I could specify the number of LEDs in each revolution and the starting rotation of each ring, which was easier than trying to string it with an accurate spiral. I include a mapping helper pattern above to make it easier to set the LEDs-per-revolution and angular alignment arrays.

## Map generator code

```
function (pixelCount) {
var map = []
// Flat ring generator
function ring(pixels, r, h, start) {
for (j = 0; j < pixels; j++) {
c = j / pixels * Math.PI * 2;
point = [r * Math.cos(c - start), r * Math.sin(c - start), h]
map.push(point)
}
}
// Wizard's spiral cone generator
function cone(cpixels) {
loops = 3
r = 4
phase = 0
pixelSpacing = 1.3
resolution = .00005 //controls the resolution of the integral
a = Math.PI * 2 * loops
function conicalHelix(t, r, a) {
z = layerPixels.length +130*t/cpixels
x = (1-t) * r * Math.cos(t * a - phase * Math.PI * 2)
y = (1-t) * r * Math.sin(t * a - phase * Math.PI * 2)
return [x,y,z]
}
function conicalHelixArcLength(t1, t2, r, a) {
h1 = conicalHelix(t1, r, a)
h2 = conicalHelix(t2, r, a)
dh = [h1[0] - h2[0], h1[1] - h2[1], h1[2] - h2[2]]
return Math.sqrt(dh[0]*dh[0] + dh[1]*dh[1] + dh[2]*dh[2])
}
for (t = 0, i = 0; i < cpixels; i++) {
//integrate arc lengths until we cover the distance to our next pixel
l = 0;
while (l < pixelSpacing) {
l += conicalHelixArcLength(t, t+resolution, r, a)
t += resolution
}
map.push(conicalHelix(t, r, a))
}
}
// Number of pixels in each ring layer, bottom to top
var layerPixels = [134, 122, 114,
96, 84, 79, 68,
73, 49, 40, 41, 37,
33];
// Angular starting offset for each layer
// Unit is revolutions (multiply by 2 PI to get radians)
var layerAngles = [ -0.02, 0.02, 0.13,
-.08, -.07, 0.03,
0.05, -.08, -.05, 0.04, .1, -.66,
0.6];
// For each layer
for (i = 0; i < layerPixels.length; i++) {
ring(layerPixels[i], // pixels
layerPixels.length - i + 3, // radius - gets smaller each layer, but min radius of 3
i, // height
layerAngles[i] * Math.PI * 2); // angular offset
}
cone(30) // top is a simple spiral
return map
}
```

Even though it’s an approximation, I found it was less work than correcting the 2% wildly-errant LED positions that the nascent auto-mapping tools produce.

### LEDs

Two years ago I strung my tree with 1000 WS2811 (12V) bullets (now $280, with green wire). I’ve used strands of 20mm SK9822 modules in other projects, but they don’t have the classic bulb look like the bullets do.

If doing this now I would try out these ~~12V~~* 5V GS820* 6* bullets - the 8206 is supposedly the IC version of the GS8208. The the GS8208 is the 5050 LED+chip with a great 12-bit gamma curve that some of us have really come to like.

I think some people are happy with the fairy-light style LEDs as well.

*Edit: Thanks, @hex337 - you’re right, the GS8206 bullets seem to all be 5V