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