Padrão RGB na classe Color - Como validar se duas cores são SEMELHANTES?

prezados,

existe uma maneira de distinguir via código se um Color possui um RGB semelhante ao outro?
um verde claro e um verde escuro…
meu gráfico terá várias cores e preciso evitar cores parecidas.
alguém já passou por isso?

Existe um método na classe color chamado toHsb. Ele passa a cor para o padrão Hue, Saturation e Brightness.

Nesse padrão, o Hue representa o tom da cor. Você pode testar por intervalos de Hue para determinar se uma cor é parecida com outra ou não.
Saturation indica o quão intensa é a cor, enquanto o brightness indica o quão brilhosa.

Será muito difícil testar isso diretamente em RGB, pois esse espaço de cor apresenta distorções difíceis nesse sentido. As vezes, uma pequena variação num dos canais provoca uma grande variação no tipo de cor.

Agora, uma outra forma de resolver seu problema seria criar uma tabela de cores. Você pode inserir diversos tons básicos diferentes e, se eles acabarem, usar o método darker() ou brighter() da classe Color para gerar tons mais claros/escuros.

obrigado pela dica, Vini. tentarei da primeira forma que vc indicou.

fiz das duas formas aqui e nenhuma me atendeu completamente.
chego a conclusão de que é impossível :smiley:
simplesmente porque numa escala de 50 ou mais cores, como é o meu caso, é impossível não sair tonalidades semelhantes… na real não são cores iguais, mas as tonalidades acabam se parecendo. o algoritmo que fiz evita apenas que uma cor semelhante saia em seguida. também fiz uma base com as cores primárias, quando elas acabam eu chamo os métodos que alteram o saturation da uma nova cor gerada randomicamente.

Até porque, é difícil também dizer com precisão o que são “duas cores diferentes”.

vc já precisou fazer isso? é impossível mesmo ou eu que sou ruim?
:confused:

Não há uma pessoa que consiga diferenciar 50 cores diferentes a menos que ela seja um especialista em cores (uma vez eu estava comentando que os sapatos de uma moça tinham uma cor esquisita e esse cara, só de ver os sapatos, me disse que era Pantone 359 (confira qual era a cor dos sapatos em http://www.logodesignteam.com/logo-design-pantone-color-chart.html ).

Se quiser, pegue justamente a lista das cores Pantone, e vá eliminando algumas delas, até que sobre apenas 50.

Normalmente você começa a pintar as coisas que têm cores semelhantes com hachurados, pontilhados ou outros padrões.

Já precisei fazer o contrário, que é igualmente difícil. Determinar se duas cores são parecidas.

Aí temos o problema que valores RGB completamente diferentes podem gerar cores parecidas. E que cores parecidas de verdade podem ser descartadas.

E é realmente muito difícil. O buraco é bem mais embaixo do que parece. Até pq pessoas diferentes tem percepções diferentes sobre cor (nunca discutiu com uma mulher sobre o fato da sua calça preta não ser azul petróleo?). Por isso, sugeri criar um arrayzinho com cores, que é a solução do Excel.

cara eu consegui bloquear qualquer vermelho de aparecer.
pegando a escala do hsb eu sei que > 0.9F ou < 0.039F é vermelho.
mas fiz isso observando a mudança de tom no vermelho… existe um padrão? pq existindo eu posso validar se a cor que vai aparecer está dentro da faixa de alguma outra e aí eu barro. seria uma forma de se fazer isso. problema é descobrir o padrão.

O Hsv é dado em graus e segue as faixas da cor da luz visível:
http://upload.wikimedia.org/wikipedia/commons/a/a0/Hsl-hsv_models.svg

Quando o problema não pode ser resolvido por lógica booleana(existem mais de 2 parâmetros) você usa uma outra lógica chamada “fuzzy”. A lógica fuzzy foi concebida para trabalhar com dúvidas, ou seja variáveis humanas(perto, longe, quente, morno, frio…);

A lógica fuzzy é teoria de conjuntos. Nesse seu problema você poderia ter 3 variáveis como Vermelho, Verde e Azul, e calcular a função fuzzy que dirá o grau de parentesco(em porcentagem) da cor repassada com as variáveis.

A rede neural kohonen ou SOM também faz associações e comumente é usada em problemas de reconhecimento de padrões. Esse problema se chama “clustering”

abaixo um exemplo de catalogagem de cores (color clustering) usando uma SOM


http://xa.yimg.com/kq/groups/14962965/239729311/name/Color+ClusteringBased+on+NN.pdf

bom pessoal, esse foi o quão longe consegui chegar:


public class CorUtilR {
	public static Set<Color> colors = new HashSet<Color>();
	public static Random random = new Random();
	public static boolean lighten = true;
	public static List<Color> baseDeCoresList = new ArrayList<Color>();
	
	private static void popularBase(){
		baseDeCoresList.add(Color.cyan.darker());
		baseDeCoresList.add(Color.YELLOW);
		baseDeCoresList.add(Color.BLUE);
		baseDeCoresList.add(Color.yellow.darker());
		baseDeCoresList.add(Color.CYAN);
		baseDeCoresList.add(Color.MAGENTA);
		baseDeCoresList.add(Color.GREEN);
		baseDeCoresList.add(Color.ORANGE);
		baseDeCoresList.add(Color.PINK);
		baseDeCoresList.add(new Color(70, 130, 180)); //SteelBlue
		baseDeCoresList.add(new Color(188, 143, 143)); //RosyBrown
		baseDeCoresList.add(new Color(0, 100, 0)); //DarkGreen
		baseDeCoresList.add(new Color(255, 165, 0)); //Orange
		baseDeCoresList.add(new Color(240, 128, 128)); //LightCoral
		baseDeCoresList.add(new Color(32, 178, 170)); //LightSeaGreen
		baseDeCoresList.add(new Color(160, 32, 240)); //Purple
		baseDeCoresList.add(new Color(0, 104, 139)); //DeepSkyBlue4
		baseDeCoresList.add(new Color(127, 255, 0)); //Chartreuse1
		baseDeCoresList.add(new Color(139, 28, 98)); //Maroon4
		baseDeCoresList.add(new Color(139, 69, 19)); //Chocolate4
		baseDeCoresList.add(new Color(100, 149, 237).darker()); //CornflowerBlue
	}
			
	public static Color getNewColorRandom() {
		Color color = creatingBaseColors();
		if(color != null)
			return color;
		color = lightOrDarkColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
		
		while (!colors.add(color)) {
			color = lightOrDarkColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
		}
		return color;
	}

	private static Color creatingBaseColors() {
		if(baseDeCoresList.isEmpty())
			popularBase();
		for(Color cor : baseDeCoresList){
			if(colors.add(cor)){
				return cor;
			}
		}
		return null;
	}

	
	
	
	private static Color lightOrDarkColor(Color color) {
		return (lighten) ? lightenColor(color.getRed(),
				color.getGreen(), color.getBlue()) : darkColor(
						color.getRed(), color.getGreen(), color.getBlue());
	}

	public static Color lightenColor(int red, int green, int blue) {
		float[] hsb = Color.RGBtoHSB(red, green, blue, null);
		float hue = blockRedColor(hsb);
		float saturation = 0.3F;
		float brightness =  hsb[2] < 0.4F ? 0.4F: hsb[2];
		lighten = false;
		return Color.getHSBColor(hue, saturation, brightness);
	}

	public static Color darkColor(int red, int green, int blue) {
		float[] hsb = Color.RGBtoHSB(red, green, blue, null);
		float hue = blockRedColor(hsb);
		float saturation = 1.0F;
		float brightness =  hsb[2] < 0.4F ? 0.4F: hsb[2];
		lighten = true;
		return Color.getHSBColor(hue, saturation, brightness);
	}

	private static float blockRedColor(float[] hsb) {
		return hsb[0] > 0.9F || hsb[0] < 0.039F ? 0.65F : hsb[0];
	}
}

eu tenho a base de cores e quando ela acaba eu passo a gerar cores randômicas que nunca serão muito escuras ou muito claras, também evito o vermelho.
Vini,
o que achou?

juliocbq,
vlw a dica, vou estudar sobre o assunto depois.