Try using only the hue in video mode, with max saturation and value
[kaka/cakelight.git] / src / kaka / cakelight / Color.java
index ba85866..fe010c7 100644 (file)
@@ -1,8 +1,20 @@
 package kaka.cakelight;
 
 public class Color {
+    private static int[] gammaCorrection = new int[256];
+
+    public static void calculateGammaCorrection(double gamma) {
+        for (int i = 0, max = 255; i <= max; i++) {
+            gammaCorrection[i] = (int)(Math.pow((double)i / max, gamma) * max);
+        }
+    }
+
     private int r, g, b;
 
+    public static Color rgb(double r, double g, double b) {
+        return rgb((int)(255 * r), (int)(255 * g), (int)(255 * b));
+    }
+
     public static Color rgb(int r, int g, int b) {
         Color c = new Color();
         c.r = r;
@@ -11,16 +23,79 @@ public class Color {
         return c;
     }
 
+    /**
+     * @param hue 0.0 - 1.0
+     * @param saturation 0.0 - 1.0
+     * @param value 0.0 - 1.0
+     */
+    public static Color hsv(double hue, double saturation, double value) {
+        double normalizedHue = hue - Math.floor(hue);
+        int h = (int)(normalizedHue * 6);
+        double f = normalizedHue * 6 - h;
+        double p = value * (1 - saturation);
+        double q = value * (1 - f * saturation);
+        double t = value * (1 - (1 - f) * saturation);
+
+        switch (h) {
+            case 0: return rgb(value, t, p);
+            case 1: return rgb(q, value, p);
+            case 2: return rgb(p, value, t);
+            case 3: return rgb(p, q, value);
+            case 4: return rgb(t, p, value);
+            case 5: return rgb(value, p, q);
+            default: throw new RuntimeException("Something went wrong when converting from HSV to RGB. Input was " + hue + ", " + saturation + ", " + value);
+        }
+    }
+
+    public double[] toHSV() {
+        return toHSV(r / 255.0, g / 255.0, b / 255.0);
+    }
+
+    /**
+     * @return an array with hsv values ranging from 0.0 to 1.0
+     */
+    public static double[] toHSV(double r, double g, double b) {
+        double h, s, v;
+        double min = Math.min(Math.min(r, g), b);
+        double max = Math.max(Math.max(r, g), b);
+
+        if (max == 0) {
+            return new double[] {0, 0, 0};
+        }
+
+        // Value
+        v = max;
+
+        // Saturation
+        double delta = max - min;
+        s = delta / max;
+
+        // Hue
+        if (r == max) {
+            h = (g - b) / delta; // between yellow & magenta
+        } else if (g == max) {
+            h = 2 + (b - r) / delta; // between cyan & yellow
+        } else {
+            h = 4 + (r - g) / delta; // between magenta & cyan
+        }
+
+        h /= 6.0;
+        if (h < 0)
+            h += 1;
+
+        return new double[] {h, s, v};
+    }
+
     public int r() {
-        return r;
+        return gammaCorrection[r];
     }
 
     public int g() {
-        return g;
+        return gammaCorrection[g];
     }
 
     public int b() {
-        return b;
+        return gammaCorrection[b];
     }
 
     public Color interpolate(Color other, double value) {