Eu escrevi os dois métodos abaixo para selecionar automaticamente N cores distintas. Ele funciona definindo uma função linear por partes no cubo RGB. O benefício disso é que você também pode obter uma escala progressiva, se é isso o que deseja, mas quando N fica grande, as cores podem começar a parecer semelhantes. Também posso imaginar subdividir uniformemente o cubo RGB em uma treliça e depois desenhar pontos. Alguém conhece outros métodos? Estou descartando a definição de uma lista e, em seguida, apenas passando por ela. Eu também deveria dizer que geralmente não me importo se eles se chocam ou não parecem bons, eles só precisam ser visualmente distintos.
public static List<Color> pick(int num) {
List<Color> colors = new ArrayList<Color>();
if (num < 2)
return colors;
float dx = 1.0f / (float) (num - 1);
for (int i = 0; i < num; i++) {
colors.add(get(i * dx));
}
return colors;
}
public static Color get(float x) {
float r = 0.0f;
float g = 0.0f;
float b = 1.0f;
if (x >= 0.0f && x < 0.2f) {
x = x / 0.2f;
r = 0.0f;
g = x;
b = 1.0f;
} else if (x >= 0.2f && x < 0.4f) {
x = (x - 0.2f) / 0.2f;
r = 0.0f;
g = 1.0f;
b = 1.0f - x;
} else if (x >= 0.4f && x < 0.6f) {
x = (x - 0.4f) / 0.2f;
r = x;
g = 1.0f;
b = 0.0f;
} else if (x >= 0.6f && x < 0.8f) {
x = (x - 0.6f) / 0.2f;
r = 1.0f;
g = 1.0f - x;
b = 0.0f;
} else if (x >= 0.8f && x <= 1.0f) {
x = (x - 0.8f) / 0.2f;
r = 1.0f;
g = 0.0f;
b = x;
}
return new Color(r, g, b);
}
java
colors
color-scheme
color-picker
trabalho
fonte
fonte
Respostas:
Você pode usar o modelo de cores HSL para criar suas cores.
Se tudo o que você deseja são tons diferentes (provável) e pequenas variações na luminosidade ou saturação, é possível distribuir os tons da seguinte forma:
fonte
Essa pergunta aparece em várias discussões do SO:
Soluções diferentes são propostas, mas nenhuma é a ideal. Felizmente, a ciência vem em socorro
Arbitrário N
Os dois últimos serão gratuitos através da maioria das bibliotecas / proxies da universidade.
N é finito e relativamente pequeno
Nesse caso, pode-se optar por uma solução de lista. Um artigo muito interessante sobre o assunto está disponível gratuitamente:
Existem várias listas de cores a serem consideradas:
Também encontrei essa paleta por um aluno do MIT. Por fim, os links a seguir podem ser úteis na conversão entre diferentes sistemas / coordenadas de cores (algumas cores nos artigos não são especificadas em RGB, por exemplo):
Para a lista de Kelly e Boynton, eu já fiz a conversão para RGB (com exceção de branco e preto, o que deve ser óbvio). Algum código C #:
E aqui estão os valores RGB nas representações hexadecimal e de 8 bits por canal:
Para todos os desenvolvedores de Java, aqui estão as cores do JavaFX:
a seguir estão as cores kelly não classificadas de acordo com a ordem acima.
as cores a seguir são classificadas de acordo com os tons (observe que alguns amarelos não são muito contrastantes)
fonte
Como a resposta de Uri Cohen, mas é um gerador. Começará usando cores distantes. Determinístico.
Amostra, deixe as cores primeiro:
fonte
Aqui está uma ideia. Imagine um cilindro HSV
Defina os limites superior e inferior que deseja para o brilho e a saturação. Isso define um anel de seção transversal quadrada dentro do espaço.
Agora, espalhe N pontos aleatoriamente dentro deste espaço.
Em seguida, aplique um algoritmo de repulsão iterativo neles, para um número fixo de iterações ou até que os pontos se estabilizem.
Agora você deve ter N pontos representando N cores tão diferentes quanto possível dentro do espaço de cores em que você está interessado.
Hugo
fonte
Para o bem das gerações vindouras, adiciono aqui a resposta aceita em Python.
fonte
Todo mundo parece ter perdido a existência do muito útil espaço de cores YUV, que foi projetado para representar diferenças de cores percebidas no sistema visual humano. As distâncias no YUV representam diferenças na percepção humana. Eu precisava dessa funcionalidade para o MagicCube4D, que implementa os cubos de Rubik em quatro dimensões e um número ilimitado de outros quebra-cabeças sinuosos em 4D com números arbitrários de faces.
Minha solução começa selecionando pontos aleatórios em YUV e depois iterativamente dividindo os dois pontos mais próximos e convertendo apenas em RGB ao retornar o resultado. O método é O (n ^ 3), mas isso não importa para números pequenos ou para números que podem ser armazenados em cache. Certamente pode ser mais eficiente, mas os resultados parecem excelentes.
A função permite a especificação opcional de limites de brilho para não produzir cores nas quais nenhum componente é mais brilhante ou mais escuro do que as quantidades especificadas. Ou seja, você pode não querer valores próximos de preto ou branco. Isso é útil quando as cores resultantes serão usadas como cores base, que serão posteriormente sombreadas por meio de iluminação, camadas, transparência etc. e ainda deverão parecer diferentes das cores base.
fonte
O modelo de cores HSL pode ser adequado para "classificar" cores, mas se você estiver procurando cores visualmente distintas, precisará definitivamente do modelo de cores Lab .
Depois que você souber disso, encontrar o subconjunto ideal de N cores de uma ampla variedade de cores ainda é um problema difícil (NP), meio semelhante ao problema do vendedor ambulante e todas as soluções que usam algoritmos k-mean ou algo realmente não Socorro.
Dito isto, se N não for muito grande e se você começar com um conjunto limitado de cores, encontrará facilmente um subconjunto muito bom de cores distintas de acordo com a distância do laboratório com uma função aleatória simples.
Eu codifiquei essa ferramenta para meu próprio uso (você pode encontrá-la aqui: https://mokole.com/palette.html ), eis o que eu tenho para N = 7:
É tudo javascript, portanto, fique à vontade para dar uma olhada na fonte da página e adaptá-la às suas próprias necessidades.
fonte
L
de 0 a 128 ea
eb
a partir de -128 a 128. ¶ I comL
= 0,a
= -128,b
= -128, que é de um azul brilhante. Então eu aumenteia
três vezes. Big A grande mudança (+128)a
= 50 resulta em um azul apenas um pouco mais escuro. ❷ (+85)a
= 85 resultados ainda em azul. ❸ No entanto, a mudança relativamente pequena (+43)a
= 128 muda completamente a cor para fúcsia.Aqui está uma solução para gerenciar seu problema "distinto", que é totalmente exagerado:
Crie uma esfera unitária e solte pontos nela com cargas repelentes. Execute um sistema de partículas até que eles não se movam mais (ou o delta seja "pequeno o suficiente"). Nesse ponto, cada um dos pontos está o mais longe possível um do outro. Converta (x, y, z) em rgb.
Menciono isso porque, para certas classes de problemas, esse tipo de solução pode funcionar melhor que a força bruta.
Originalmente, vi essa abordagem aqui para pavimentar uma esfera.
Novamente, as soluções mais óbvias de percorrer o espaço HSL ou RGB provavelmente funcionarão bem.
fonte
Eu tentaria corrigir a saturação e a luminosidade ao máximo e focar apenas no tom. A meu ver, H pode ir de 0 a 255 e depois se mover. Agora, se você quisesse duas cores contrastantes, escolheria os lados opostos desse anel, ou seja, 0 e 128. Se desejasse 4 cores, separaria 1/4 do comprimento do círculo 256, ou seja, 0, 64,128,192. E, é claro, como outros sugeriram quando você precisa de N cores, basta separá-las por 256 / N.
O que eu acrescentaria a essa idéia é usar uma representação invertida de um número binário para formar essa sequência. Veja isso:
... dessa forma, se você precisar de N cores diferentes, poderá pegar os primeiros N números, invertê-los e obter o máximo de pontos distantes possível (pois N é poder de dois), preservando ao mesmo tempo que cada prefixo do sequência difere muito.
Esse era um objetivo importante no meu caso de uso, pois eu tinha um gráfico em que as cores eram classificadas por área coberta por essa cor. Eu queria que as maiores áreas do gráfico tivessem um grande contraste, e eu estava bem com algumas pequenas áreas com cores semelhantes às do top 10, pois era óbvio para o leitor qual é qual delas, apenas observando a área.
fonte
getfracs
. Mas sua abordagem é rápido e "simples" em linguagens de baixo nível: pouco revertendo em C .Se N for grande o suficiente, você obterá cores com aparência semelhante. Existem tantos no mundo.
Por que não distribuí-los uniformemente pelo espectro, assim:
Se você deseja misturar a sequência para que cores semelhantes não fiquem próximas, talvez seja possível embaralhar a lista resultante.
Estou pensando isso?
fonte
Isso é trivial no MATLAB (existe um comando hsv):
fonte
Eu escrevi um pacote para R chamado qualpalr, projetado especificamente para esse fim. Eu recomendo que você analise a vinheta para descobrir como ela funciona, mas tentarei resumir os pontos principais.
O qualpalr pega uma especificação de cores no espaço de cores HSL (que foi descrito anteriormente nesta linha), projeta-o no espaço de cores DIN99d (que é perceptualmente uniforme) e descobre o
n
que maximiza a distância mínima entre qualquer um deles.fonte
Eu acho que esse algoritmo recursivo simples complementa a resposta aceita, a fim de gerar valores distintos de matiz. Eu fiz isso para hsv, mas também pode ser usado para outros espaços de cores.
Ele gera matizes em ciclos, o mais separado possível um do outro em cada ciclo.
Não consegui encontrar esse tipo de algoritmo aqui. Espero que ajude, é o meu primeiro post aqui.
fonte
Essa função OpenCV usa o modelo de cores HSV para gerar
n
cores uniformemente distribuídas em torno de 0 <= H <= 360º com S = 1,0 máximo e V = 1,0. A função gera as cores BGR embgr_mat
:fonte