package patterns import ( "math" ) type RGBcolor = [3]byte func floatColorToIntColor(val float64) byte { return byte(val*256 - 0.5) } func plasmaRGBFromVal(val byte) (byte, byte, byte) { var r byte var g byte var b byte if val < 85 { r = val * 3 g = 255 - r b = 0 } else if val < 170 { b = (val - 85) * 3 r = 255 - b g = 0 } else { g = (val - 170) * 3 b = 255 - g r = 0 } return r, g, b } func LinearPlasma(l int) []byte { line := make([]byte, l*3) for i := 0; i < l*3; i += 3 { val := byte(i % 256) r, g, b := plasmaRGBFromVal(val) line[i] = r line[i+1] = g line[i+2] = b } return line } func linearFromVal(val byte) (byte, byte, byte) { var r byte = val var g byte = 0 var b byte = 0 return r, g, b } func positiveModF(val float64) float64 { _, val = math.Modf(val) if val < 0 { return val + 1.0 } return val } func colorPlasmaFromFloatVal(val float64) (byte, byte, byte) { var r byte var g byte var b byte val = positiveModF(val) * 3.0 if val < 1.0 { r = floatColorToIntColor(val) g = floatColorToIntColor(1.0 - val) b = 0 } else if val < 2.0 { b = floatColorToIntColor(val - 1.0) r = floatColorToIntColor(1.0 - (val - 1.0)) g = 0.0 } else { g = floatColorToIntColor(val - 2.0) b = floatColorToIntColor(1.0 - (val - 2.0)) r = 0.0 } return r, g, b } var palletteOffset float64 = 0.0 func PlasmaPanel(w int, h int, speed uint16) [][]RGBcolor { grid := make([][]RGBcolor, w) for i := 0; i < w; i++ { grid[i] = make([]RGBcolor, h) } // pbrook didn't say what DT is for... so it resolves to 0.05 palletteOffset -= 0.05 / 1.0 if palletteOffset < 0 { palletteOffset += 1.0 } offset := 0.5 // center offset scaleW := math.Pi * 2.0 / float64(w) scaleH := math.Pi * 2.0 / float64(h) for y := 0; y < h; y++ { for x := 0; x < w; x++ { u := math.Cos((float64(x) + offset) * scaleW) v := math.Cos((float64(y) + offset) * scaleH) j := math.Cos(offset * scaleW) // 2D - No Z e := (u + v + j + 3.0) / 6.0 r, g, b := colorPlasmaFromFloatVal(palletteOffset + e) var rgb [3]byte rgb[0] = r rgb[1] = g rgb[2] = b grid[x][y] = rgb } } return grid } func singleColorPlasmaFromFloatVal(val float64, baseColor RGBcolor) (byte, byte, byte) { var r byte var g byte var b byte val = positiveModF(val) r = byte(math.Trunc(float64(baseColor[0]) * val)) g = byte(math.Trunc(float64(baseColor[1]) * val)) b = byte(math.Trunc(float64(baseColor[2]) * val)) return r, g, b } func PlasmaPanelSingleColor(w int, h int, speed uint16, baseColor RGBcolor) [][]RGBcolor { grid := make([][]RGBcolor, w) for i := 0; i < w; i++ { grid[i] = make([]RGBcolor, h) } palletteOffset -= 0.05 / 1.0 if palletteOffset < 0 { palletteOffset += 1.0 } offset := 0.5 // center offset scaleW := math.Pi * 2.0 / float64(w) scaleH := math.Pi * 2.0 / float64(h) for y := 0; y < h; y++ { for x := 0; x < w; x++ { u := math.Cos((float64(x) + offset) * scaleW) v := math.Cos((float64(y) + offset) * scaleH) j := math.Cos(offset * scaleW) // 2D - No Z e := (u + v + j + 3.0) / 6.0 r, g, b := singleColorPlasmaFromFloatVal(palletteOffset+e, baseColor) var rgb [3]byte rgb[0] = r rgb[1] = g rgb[2] = b grid[x][y] = rgb } } return grid }