From d42871de7ec8eac119b92fd7510a1ddc6594edb2 Mon Sep 17 00:00:00 2001
From: brinn <brinn>
Date: Tue, 9 Aug 2011 08:12:21 +0000
Subject: [PATCH] extend: color mixture calculation to non-pure colors add:
 unit tests

SVN: 22418
---
 .../systemsx/cisd/common/color/HSBColor.java  |   7 +
 .../systemsx/cisd/common/color/MixColors.java |  32 ++++-
 .../cisd/common/color/PureHSBColor.java       |  10 +-
 .../cisd/common/color/MixColorsTest.java      | 133 ++++++++++++++++++
 .../common/color/WavelengthColorTest.java     |  48 +++++++
 5 files changed, 226 insertions(+), 4 deletions(-)
 create mode 100644 common/sourceTest/java/ch/systemsx/cisd/common/color/MixColorsTest.java
 create mode 100644 common/sourceTest/java/ch/systemsx/cisd/common/color/WavelengthColorTest.java

diff --git a/common/source/java/ch/systemsx/cisd/common/color/HSBColor.java b/common/source/java/ch/systemsx/cisd/common/color/HSBColor.java
index 8b01f938efc..64a88f4ed9a 100644
--- a/common/source/java/ch/systemsx/cisd/common/color/HSBColor.java
+++ b/common/source/java/ch/systemsx/cisd/common/color/HSBColor.java
@@ -150,4 +150,11 @@ public class HSBColor
     {
         return Color.getHSBColor(hue, saturation, brightness);
     }
+
+    @Override
+    public String toString()
+    {
+        return "HSBColor [hue=" + hue + ", saturation=" + saturation + ", brightness=" + brightness
+                + "]";
+    }
 }
diff --git a/common/source/java/ch/systemsx/cisd/common/color/MixColors.java b/common/source/java/ch/systemsx/cisd/common/color/MixColors.java
index aaa80f83911..1e9cf54b761 100644
--- a/common/source/java/ch/systemsx/cisd/common/color/MixColors.java
+++ b/common/source/java/ch/systemsx/cisd/common/color/MixColors.java
@@ -16,6 +16,7 @@
 
 package ch.systemsx.cisd.common.color;
 
+
 /**
  * A class for calculating a mixed color from a set of pure colors of different relative
  * intensities.
@@ -27,7 +28,7 @@ package ch.systemsx.cisd.common.color;
 public class MixColors
 {
 
-    private static float[] calcWeights(PureHSBColor[] colors, float[] intensities)
+    private static float[] calcWeights(HSBColor[] colors, float[] intensities)
     {
         final float[] effectiveIntensities = new float[intensities.length];
         float sum = 0.0f;
@@ -50,7 +51,7 @@ public class MixColors
      * @param colors The colors to mix.
      * @param intensities The intensities of each color. Has to be the same length as
      *            <var>colors</var>.
-     * @return The mixed color.
+     * @return The mixed (pure) color.
      */
     public static PureHSBColor calcMixedColor(PureHSBColor[] colors, float[] intensities)
     {
@@ -69,4 +70,31 @@ public class MixColors
         return new PureHSBColor(hue, brightness);
     }
 
+    /**
+     * Calculates a mixed color from given <var>colors</var>.
+     * 
+     * @param colors The colors to mix.
+     * @param intensities The intensities of each color. Has to be the same length as
+     *            <var>colors</var>.
+     * @return The mixed color.
+     */
+    public static HSBColor calcMixedColor(HSBColor[] colors, float[] intensities)
+    {
+        assert colors.length == intensities.length;
+
+        final float[] weights = calcWeights(colors, intensities);
+        
+        float hue = 0.0f;
+        float saturation = 0.0f;
+        float brightness = 0.0f;
+        for (int i = 0; i < weights.length; ++i)
+        {
+            hue += weights[i] * colors[i].getHue();
+            saturation += weights[i] * colors[i].getSaturation();
+            brightness = Math.max(brightness, intensities[i] * colors[i].getBrightness());
+        }
+
+        return new HSBColor(hue, saturation, brightness);
+    }
+
 }
diff --git a/common/source/java/ch/systemsx/cisd/common/color/PureHSBColor.java b/common/source/java/ch/systemsx/cisd/common/color/PureHSBColor.java
index 2ebc326d04e..854ca575f58 100644
--- a/common/source/java/ch/systemsx/cisd/common/color/PureHSBColor.java
+++ b/common/source/java/ch/systemsx/cisd/common/color/PureHSBColor.java
@@ -21,14 +21,14 @@ import java.awt.Color;
 /**
  * A pure color object in the HSB (Hue, Saturation, Brightness) color space.
  * <p>
- * A pure color is defined by having saturation = 1.0. 
+ * A pure color is defined by having saturation = 1.0.
  * 
  * @author Bernd Rinn
  */
 public class PureHSBColor extends HSBColor
 {
     /**
-     * Constructs a PureHSBColor from the given {@link java.awt.Color}. 
+     * Constructs a PureHSBColor from the given {@link java.awt.Color}.
      * 
      * @throw {@link IllegalArgumentException} if <var>color</var> is not pure.
      */
@@ -53,4 +53,10 @@ public class PureHSBColor extends HSBColor
         return true;
     }
 
+    @Override
+    public String toString()
+    {
+        return "PureHSBColor [hue=" + getHueDegree() + ", brightness=" + getBrightness() + "]";
+    }
+
 }
diff --git a/common/sourceTest/java/ch/systemsx/cisd/common/color/MixColorsTest.java b/common/sourceTest/java/ch/systemsx/cisd/common/color/MixColorsTest.java
new file mode 100644
index 00000000000..e7b2c946944
--- /dev/null
+++ b/common/sourceTest/java/ch/systemsx/cisd/common/color/MixColorsTest.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2011 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.common.color;
+
+import static org.testng.AssertJUnit.*;
+
+import org.testng.annotations.Test;
+
+/**
+ * Test cases fir {@link MixColors}.
+ * 
+ * @author Bernd Rinn
+ */
+public class MixColorsTest
+{
+    @Test
+    public void testMixTwoPureColorsFullIntensity()
+    {
+        PureHSBColor color = MixColors.calcMixedColor(new PureHSBColor[]
+            { new PureHSBColor(0.0f, 1.0f), new PureHSBColor(0.5f, 1.0f) }, new float[]
+            { 1f, 1f });
+        assertEquals(90.0f, color.getHueDegree());
+        assertEquals(1.0f, color.getBrightness());
+    }
+
+    @Test
+    public void testMixTwoPureColorsFullAndHalfIntensity()
+    {
+        PureHSBColor color = MixColors.calcMixedColor(new PureHSBColor[]
+            { new PureHSBColor(0.0f, 1.0f), new PureHSBColor(0.5f, 1.0f) }, new float[]
+            { 1f, 0.5f });
+        assertEquals(60.0f, color.getHueDegree());
+        assertEquals(1.0f, color.getBrightness());
+    }
+
+    @Test
+    public void testMixTwoPureColorsFullAndHalfBrightness()
+    {
+        PureHSBColor color = MixColors.calcMixedColor(new PureHSBColor[]
+            { new PureHSBColor(0.0f, 1.0f), new PureHSBColor(0.5f, 0.5f) }, new float[]
+            { 1f, 1f });
+        assertEquals(60.0f, color.getHueDegree());
+        assertEquals(1.0f, color.getBrightness());
+    }
+
+    @Test
+    public void testMixTwoPureColorsZeroAndFullIntensity()
+    {
+        PureHSBColor color = MixColors.calcMixedColor(new PureHSBColor[]
+            { new PureHSBColor(0.0f, 1.0f), new PureHSBColor(2f / 3f, 1.0f) }, new float[]
+            { 0f, 1f });
+        assertEquals(240.0f, color.getHueDegree());
+        assertEquals(1.0f, color.getBrightness());
+    }
+
+    @Test
+    public void testMixThreePureColorsFullQuarterQuarterIntensity()
+    {
+        PureHSBColor color =
+                MixColors.calcMixedColor(new PureHSBColor[]
+                    { new PureHSBColor(0.0f, 1.0f), new PureHSBColor(1f / 6f, 1.0f),
+                            new PureHSBColor(2f / 3f, 1.0f) }, new float[]
+                    { 1f, 0.25f, 0.25f });
+        assertEquals(50.0f, color.getHueDegree(), 1e-5f);
+        assertEquals(1.0f, color.getBrightness());
+    }
+
+    @Test
+    public void testMixThreePureColorsFullQuarterHalfIntensityHalfBrightness()
+    {
+        PureHSBColor color =
+                MixColors.calcMixedColor(new PureHSBColor[]
+                    { new PureHSBColor(0.0f, 1.0f), new PureHSBColor(1f / 6f, 0.5f),
+                            new PureHSBColor(2f / 3f, 1.0f) }, new float[]
+                    { 1f, 0.5f, 0.25f });
+        assertEquals(50.0f, color.getHueDegree(), 1e-5f);
+        assertEquals(1.0f, color.getBrightness());
+    }
+
+    @Test
+    public void testMixFourPureColorsFullQuarterHalfIntensityHalfBrightness()
+    {
+        PureHSBColor color =
+                MixColors.calcMixedColor(new PureHSBColor[]
+                    { new PureHSBColor(1f / 3f, 1.0f), new PureHSBColor(0f, 0.5f),
+                            new PureHSBColor(2f / 3f, 0.5f), new PureHSBColor(15f / 18f, 0.25f) },
+                        new float[]
+                            { 0.9f, 0.1f, 0.1f, 0.1f });
+        assertEquals(124.39f, color.getHueDegree(), 5e-4f);
+        assertEquals(0.9f, color.getBrightness());
+    }
+
+    @Test
+    public void testMixTwoColorsFullIntensityDifferentSaturation()
+    {
+        HSBColor color = MixColors.calcMixedColor(new HSBColor[]
+            { new HSBColor(0.0f, 1.0f, 1.0f), new HSBColor(0.5f, 0.5f, 1.0f) }, new float[]
+            { 1f, 1f });
+        assertEquals(90.0f, color.getHueDegree());
+        assertEquals(0.75f, color.getSaturation());
+        assertEquals(1.0f, color.getBrightness());
+    }
+
+    @Test
+    public void testMixFourColorsFullQuarterHalfIntensityHalfBrightness()
+    {
+        HSBColor color =
+                MixColors.calcMixedColor(new HSBColor[]
+                    { new HSBColor(1f / 3f, 1.0f), new HSBColor(0f, 0.5f, 0.5f),
+                            new HSBColor(2f / 3f, 0.5f, 0.5f),
+                            new HSBColor(15f / 18f, 0.25f, 0.25f) }, new float[]
+                    { 1f, 0.1f, 0.1f, 0.1f });
+        System.out.println(color);
+        assertEquals(124f, color.getHueDegree());
+        assertEquals(0.9389f, color.getSaturation(), 1e-4f);
+        assertEquals(1f, color.getBrightness());
+    }
+
+}
diff --git a/common/sourceTest/java/ch/systemsx/cisd/common/color/WavelengthColorTest.java b/common/sourceTest/java/ch/systemsx/cisd/common/color/WavelengthColorTest.java
new file mode 100644
index 00000000000..158fbcc5a07
--- /dev/null
+++ b/common/sourceTest/java/ch/systemsx/cisd/common/color/WavelengthColorTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2011 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.common.color;
+
+import static org.testng.AssertJUnit.*;
+
+import org.testng.annotations.Test;
+
+/**
+ * Test cases for the {@link WavelengthColor} class.
+ *
+ * @author Bernd Rinn
+ */
+public class WavelengthColorTest
+{
+
+    @Test
+    public void testCommonDyes()
+    {
+        PureHSBColor dapi = WavelengthColor.getHSBColorForWavelength(461);
+        assertEquals(214.8f, dapi.getHueDegree(), 0.05f);
+        assertEquals(1.0f, dapi.getBrightness());
+        PureHSBColor gfp = WavelengthColor.getHSBColorForWavelength(509);
+        assertEquals(123.1f, gfp.getHueDegree(), 0.05f);
+        assertEquals(1.0f, gfp.getBrightness());
+        PureHSBColor fitc = WavelengthColor.getHSBColorForWavelength(521);
+        assertEquals(110.6f, fitc.getHueDegree(), 0.05f);
+        assertEquals(1.0f, fitc.getBrightness());
+        PureHSBColor cy5 = WavelengthColor.getHSBColorForWavelength(660);
+        assertEquals(0.0f, cy5.getHueDegree());
+        assertEquals(1.0f, cy5.getBrightness());
+    }
+    
+}
-- 
GitLab