Skip to content

Commit

Permalink
Move color averaging to package common
Browse files Browse the repository at this point in the history
Also implement correct hue averaging in polar space
  • Loading branch information
pdf committed Nov 19, 2015
1 parent f4c3fbd commit ff995ff
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 15 deletions.
39 changes: 39 additions & 0 deletions common/color.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package common

import "math"

// Color is used to represent the color and color temperature of a light.
// The color is represented as a 48-bit HSB (Hue, Saturation, Brightness) value.
// The color temperature is represented in K (Kelvin) and is used to adjust the
Expand All @@ -11,3 +13,40 @@ type Color struct {
Brightness uint16 // range 0 to 65535
Kelvin uint16 // range 2500° (warm) to 9000° (cool)
}

// AverageColor returns the average of the provided colors
func AverageColor(colors ...Color) (color Color) {
var (
x, y float64
hue, sat, bri, kel int
)

// Sum sind/cosd for hues
for _, c := range colors {
// Convert hue to degrees
h := float64(c.Hue) / float64(math.MaxUint16) * 360.0

x += math.Cos(h / 180.0 * math.Pi)
y += math.Sin(h / 180.0 * math.Pi)
sat += int(c.Saturation)
bri += int(c.Brightness)
kel += int(c.Kelvin)
}

// Average sind/cosd
x /= float64(len(colors))
y /= float64(len(colors))

// Take atan2 of averaged hue and convert to uint16 scale
hue = int((math.Atan2(y, x) * 180.0 / math.Pi) / 360.0 * float64(math.MaxUint16))
sat /= len(colors)
bri /= len(colors)
kel /= len(colors)

color.Hue = uint16(hue)
color.Saturation = uint16(sat)
color.Brightness = uint16(bri)
color.Kelvin = uint16(kel)

return color
}
21 changes: 6 additions & 15 deletions protocol/v2/device/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,19 +202,16 @@ func (g *Group) CachedColor() common.Color {
return c
}

func (g *Group) getColor(cached bool) (common.Color, error) {
var (
hueSum, satSum, brightSum, kelvSum uint64
color common.Color
)

func (g *Group) getColor(cached bool) (color common.Color, err error) {
lights := g.Lights()

if len(lights) == 0 {
return color, nil
}

for _, light := range lights {
colors := make([]common.Color, len(lights))

for i, light := range lights {
var (
c common.Color
err error
Expand All @@ -227,16 +224,10 @@ func (g *Group) getColor(cached bool) (common.Color, error) {
return color, err
}
}
hueSum += uint64(c.Hue)
satSum += uint64(c.Saturation)
brightSum += uint64(c.Brightness)
kelvSum += uint64(c.Kelvin)
colors[i] = c
}

color.Hue = uint16(hueSum / uint64(len(lights)))
color.Saturation = uint16(satSum / uint64(len(lights)))
color.Brightness = uint16(brightSum / uint64(len(lights)))
color.Kelvin = uint16(kelvSum / uint64(len(lights)))
color = common.AverageColor(colors...)

return color, nil
}
Expand Down

0 comments on commit ff995ff

Please sign in to comment.