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