Try using only the hue in video mode, with max saturation and value
[kaka/cakelight.git] / src / kaka / cakelight / Color.java
1 package kaka.cakelight;
2
3 public class Color {
4     private static int[] gammaCorrection = new int[256];
5
6     public static void calculateGammaCorrection(double gamma) {
7         for (int i = 0, max = 255; i <= max; i++) {
8             gammaCorrection[i] = (int)(Math.pow((double)i / max, gamma) * max);
9         }
10     }
11
12     private int r, g, b;
13
14     public static Color rgb(double r, double g, double b) {
15         return rgb((int)(255 * r), (int)(255 * g), (int)(255 * b));
16     }
17
18     public static Color rgb(int r, int g, int b) {
19         Color c = new Color();
20         c.r = r;
21         c.g = g;
22         c.b = b;
23         return c;
24     }
25
26     /**
27      * @param hue 0.0 - 1.0
28      * @param saturation 0.0 - 1.0
29      * @param value 0.0 - 1.0
30      */
31     public static Color hsv(double hue, double saturation, double value) {
32         double normalizedHue = hue - Math.floor(hue);
33         int h = (int)(normalizedHue * 6);
34         double f = normalizedHue * 6 - h;
35         double p = value * (1 - saturation);
36         double q = value * (1 - f * saturation);
37         double t = value * (1 - (1 - f) * saturation);
38
39         switch (h) {
40             case 0: return rgb(value, t, p);
41             case 1: return rgb(q, value, p);
42             case 2: return rgb(p, value, t);
43             case 3: return rgb(p, q, value);
44             case 4: return rgb(t, p, value);
45             case 5: return rgb(value, p, q);
46             default: throw new RuntimeException("Something went wrong when converting from HSV to RGB. Input was " + hue + ", " + saturation + ", " + value);
47         }
48     }
49
50     public double[] toHSV() {
51         return toHSV(r / 255.0, g / 255.0, b / 255.0);
52     }
53
54     /**
55      * @return an array with hsv values ranging from 0.0 to 1.0
56      */
57     public static double[] toHSV(double r, double g, double b) {
58         double h, s, v;
59         double min = Math.min(Math.min(r, g), b);
60         double max = Math.max(Math.max(r, g), b);
61
62         if (max == 0) {
63             return new double[] {0, 0, 0};
64         }
65
66         // Value
67         v = max;
68
69         // Saturation
70         double delta = max - min;
71         s = delta / max;
72
73         // Hue
74         if (r == max) {
75             h = (g - b) / delta; // between yellow & magenta
76         } else if (g == max) {
77             h = 2 + (b - r) / delta; // between cyan & yellow
78         } else {
79             h = 4 + (r - g) / delta; // between magenta & cyan
80         }
81
82         h /= 6.0;
83         if (h < 0)
84             h += 1;
85
86         return new double[] {h, s, v};
87     }
88
89     public int r() {
90         return gammaCorrection[r];
91     }
92
93     public int g() {
94         return gammaCorrection[g];
95     }
96
97     public int b() {
98         return gammaCorrection[b];
99     }
100
101     public Color interpolate(Color other, double value) {
102         double invertedValue = 1 - value;
103         return Color.rgb(
104                 (int)(r * invertedValue + other.r * value),
105                 (int)(g * invertedValue + other.g * value),
106                 (int)(b * invertedValue + other.b * value)
107         );
108     }
109 }