replaced the broken calculation of distinct colors in the colormap with a HSV color schema based method

This commit is contained in:
fmittag committed 2012-06-22 11:57:44 +02:00
1 parent 856aa593be
commit 3d6ea70ed6
4 files changed
+223 -42

No files matched your search

@@ -1,10 +1,13 @@
package com.sap.sailing.domain.common;
import java.io.Serializable;
import com.sap.sailing.domain.common.impl.Util;
public interface Color extends Serializable {
Util.Triple<Integer, Integer, Integer> getAsRGB();
Util.Triple<Float, Float, Float> getAsHSV();
String getAsHtml();
}
@@ -0,0 +1,125 @@
package com.sap.sailing.domain.common.impl;
import com.sap.sailing.domain.common.Color;
import com.sap.sailing.domain.common.impl.Util.Triple;
/**
* A color defined in the HSV color schema (hue, saturation, brightness) Hue is a degree between 0.0 and 360.0
* Saturation is between 0.0 and 1.0 Brightness is between 0.0 and 1.0
*
* @author Frank
*/
public class HSVColor implements Color {
private static final long serialVersionUID = 7602013229606352246L;
float hue;
float saturation;
float brightness;
HSVColor() {
} // for GWT serializability
public HSVColor(float hue, float saturation, float brightness) {
this.hue = ensureValidRange(hue, 360.0f);
this.saturation = ensureValidRange(saturation, 1.0f);
this.brightness = ensureValidRange(brightness, 1.0f);
}
private float ensureValidRange(float value, float maxValue) {
float result = value;
if (value < 0.0f) {
result = 0.0f;
} else if (value > maxValue) {
result = maxValue;
}
return result;
}
@Override
public Triple<Integer, Integer, Integer> getAsRGB() {
float r, b, g;
if (saturation == 0) {
r = g = b = brightness;
} else {
float h = hue / 60.0f; // sector 0 to 5
int i = (int) Math.floor(h);
float f = h - i; // factorial part of h
float p = brightness * (1 - saturation);
float q = brightness * (1 - saturation * f);
float t = brightness * (1 - saturation * (1 - f));
switch (i) {
case 0:
r = brightness;
g = t;
b = p;
break;
case 1:
r = q;
g = brightness;
b = p;
break;
case 2:
r = p;
g = brightness;
b = t;
break;
case 3:
r = p;
g = q;
b = brightness;
break;
case 4:
r = t;
g = p;
b = brightness;
break;
default: // case 5:
r = brightness;
g = p;
b = q;
}
}
Triple<Integer, Integer, Integer> RGBColor = new Triple<Integer, Integer, Integer>(Math.round(r * 255),
Math.round(g * 255), Math.round(b * 255));
return RGBColor;
}
@Override
public String getAsHtml() {
Triple<Integer, Integer, Integer> asRGB = getAsRGB();
return "#" + toBrowserHexValue(asRGB.getA()) + toBrowserHexValue(asRGB.getB())
+ toBrowserHexValue(asRGB.getC());
}
private static String toBrowserHexValue(int number) {
StringBuilder builder = new StringBuilder(Integer.toHexString(number & 0xff));
while (builder.length() < 2) {
builder.append("0");
}
return builder.toString().toUpperCase();
}
@Override
public Triple<Float, Float, Float> getAsHSV() {
return new Triple<Float, Float, Float>(hue, saturation, brightness);
}
@Override
public String toString() {
return "HSVColor [hue=" + hue + ", saturation=" + saturation + ", brightness=" + brightness + "]";
}
public float getHue() {
return hue;
}
public float getSaturation() {
return saturation;
}
public float getBrightness() {
return brightness;
}
}
@@ -3,16 +3,20 @@ package com.sap.sailing.domain.common.impl;
import com.sap.sailing.domain.common.Color;
import com.sap.sailing.domain.common.impl.Util.Triple;
/**
* A color defined in the RGB color schema
* @author Frank
*/
public class RGBColor implements Color {
private static final long serialVersionUID = -4091876840771631308L;
private int red;
private int green;
private int blue;
RGBColor() {} // for GWT serializability
RGBColor() {
} // for GWT serializability
public RGBColor(int red, int green, int blue) {
super();
this.red = ensureValidRange(red);
this.green = ensureValidRange(green);
this.blue = ensureValidRange(blue);
@@ -33,11 +37,52 @@ public class RGBColor implements Color {
return new Triple<Integer, Integer, Integer>(red, green, blue);
}
public Triple<Float, Float, Float> getAsHSV() {
float hue, saturation, brightness;
int cmax = (red > green) ? red : green;
if (blue > cmax) {
cmax = blue;
}
int cmin = (red < green) ? red : green;
if (blue < cmin) {
cmin = blue;
}
brightness = ((float) cmax) / 255.0f;
if (cmax != 0) {
saturation = ((float) (cmax - cmin)) / ((float) cmax);
} else {
saturation = 0;
}
if (saturation == 0) {
hue = 0;
}
else {
float redc = ((float) (cmax - red)) / ((float) (cmax - cmin));
float greenc = ((float) (cmax - green)) / ((float) (cmax - cmin));
float bluec = ((float) (cmax - blue)) / ((float) (cmax - cmin));
if (red == cmax) {
hue = bluec - greenc;
} else if (green == cmax) {
hue = 2.0f + redc - bluec;
} else {
hue = 4.0f + greenc - redc;
}
hue = hue / 6.0f;
if (hue < 0) {
hue = hue + 1.0f;
}
}
Triple<Float, Float, Float> HSVColor = new Triple<Float, Float, Float>(hue, saturation, brightness);
return HSVColor;
}
@Override
public String getAsHtml() {
return "#" + toBrowserHexValue(red) + toBrowserHexValue(green) + toBrowserHexValue(blue);
}
private static String toBrowserHexValue(int number) {
StringBuilder builder = new StringBuilder(Integer.toHexString(number & 0xff));
while (builder.length() < 2) {
@@ -73,10 +118,21 @@ public class RGBColor implements Color {
return false;
return true;
}
@Override
public String toString() {
return getAsHtml();
}
public int getRed() {
return red;
}
public int getGreen() {
return green;
}
public int getBlue() {
return blue;
}
}
@@ -2,20 +2,34 @@ package com.sap.sailing.gwt.ui.client;
import java.util.HashMap;
import com.sap.sailing.domain.common.impl.HSVColor;
/**
* Manages color assignments to objects.
*
* @author Axel Uhl (d043530)
*
* @param <T> the type of the objects to which a color is assigned
*
* @param <T>
* the type of the objects to which a color is assigned
*/
public class ColorMap<T> {
private final HashMap<T, String> idColor;
private int colorCounter;
private HSVColor[] baseColors;
public ColorMap() {
baseColors = new HSVColor[8];
baseColors[0] = new HSVColor(0.0f, 1.0f, 1.0f); // Red
baseColors[1] = new HSVColor(30.0f, 1.0f, 1.0f); // Orange
baseColors[2] = new HSVColor(60.f, 1.0f, 1.0f); // Yellow
baseColors[3] = new HSVColor(120.0f, 1.0f, 1.0f); // Green
baseColors[4] = new HSVColor(180.0f, 1.0f, 1.0f); // Cyan
baseColors[5] = new HSVColor(240.0f, 1.0f, 1.0f); // Blue
baseColors[6] = new HSVColor(240.0f, 1.0f, 1.0f); // Pink
baseColors[7] = new HSVColor(300.0f, 1.0f, 1.0f); // Magenta
idColor = new HashMap<T, String>();
}
@@ -26,15 +40,15 @@ public class ColorMap<T> {
* An ID unique for a competitor.
* @return A color in hex/html-format (e.g. #ff0000)
*/
public String getColorByID(T object){
public String getColorByID(T object) {
String color = idColor.get(object);
if (color == null || color.isEmpty()){
color = createHexColor(colorCounter++);
idColor.put(object, color);
if (color == null || color.isEmpty()) {
color = createHexColor(colorCounter++);
idColor.put(object, color);
}
return color;
}
/**
* Only use this if you don't want the color to be cached.
*
@@ -42,32 +56,15 @@ public class ColorMap<T> {
* The index of e.g. a competitor. Make sure, that each competitor has a unique index.
* @return A color computed using the {@code index}.
*/
private String createHexColor(int index){
String rs, gs, bs;
int r = 0, g = 0, b = 0;
double factor = 1 - ((index/6)/6.0);
if (index%6 < 2 || index%6 > 4){
r = (int) (255*factor);
}
rs = Integer.toHexString(r);
while(rs.length() < 2){
rs = "0" + rs;
}
if (index%6 > 0 && index%6 < 4){
g = (int) (220*factor);
}
gs = Integer.toHexString(g);
while(gs.length() < 2){
gs = "0" + gs;
}
if (index%6 > 2){
b = (int) (255*factor);
}
bs = Integer.toHexString(b);
while(bs.length() < 2){
bs = "0" + bs;
}
return "#" + rs + gs + bs;
private String createHexColor(int index) {
int baseColorCount = baseColors.length;
int baseColorsIndex = index % baseColorCount;
float brightnessDecrease = Math.round(index / baseColorCount) * 0.75f;
float saturationDecrease = Math.round(index / baseColorCount) * 0.05f;
HSVColor hsvColor = baseColors[baseColorsIndex];
HSVColor newColor = new HSVColor(hsvColor.getHue(), hsvColor.getSaturation() - saturationDecrease,
hsvColor.getBrightness() - brightnessDecrease);
return newColor.getAsHtml();
}
}