Jak automatycznie wygenerować N "odrębnych" kolorów?
Napisałem dwie metody poniżej, aby automatycznie wybrać N różnych kolorów. Działa poprzez zdefiniowanie funkcji liniowej na kostce RGB. Zaletą tego jest to, że można również uzyskać progresywną skalę, jeśli to jest to, co chcesz, ale gdy N dostaje duże kolory mogą zacząć wyglądać podobnie. Mogę też sobie wyobrazić równomierne dzielenie kostki RGB na kratkę, a następnie rysowanie punktów. Czy ktoś zna jakieś inne metody? Wykluczam zdefiniowanie listy, a potem ją przejeżdżam. Ja też powinienem. powiedzmy, że ogólnie nie obchodzi mnie, czy się zderzają, czy nie wyglądają ładnie, po prostu muszą być wizualnie wyraźne.
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);
}
12 answers
Możesz użyć modelu kolorów HSL do tworzenia kolorów.
Jeśli wszystko, co chcesz, to różne odcienie (prawdopodobnie) i niewielkie różnice w jasności lub nasyceniu, możesz rozłożyć odcienie w następujący sposób:]}
// assumes hue [0, 360), saturation [0, 100), lightness [0, 100)
for(i = 0; i < 360; i += 360 / num_colors) {
HSLColor c;
c.hue = i;
c.saturation = 90 + randf() * 10;
c.lightness = 50 + randf() * 10;
addColor(c);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-22 22:01:44
To pytanie pojawia się w kilku dyskusjach więc:
- Algorytm Generowania Unikalnych Kolorów
- Wygeneruj unikalne kolory
- generowanie wyraźnie różnych kolorów RGB na wykresach
- Jak wygenerować N różnych kolorów dla dowolnej liczby naturalnej n?
Proponuje się różne rozwiązania, ale żaden nie jest optymalny. Na szczęście, nauka przychodzi na ratunek
Dowolne N
- kolorowe wyświetlacze do zdjęć kategorycznych (do pobrania za darmo)
- W 2007 roku, po raz pierwszy w historii, pojawiła się nowa wersja gry, która została wydana na konsolę Xbox 360 i Xbox 360.]}
- algorytm doboru zestawów kolorów O Wysokim kontraście (autorzy oferują darmową implementację C++)
- zestawy kolorów O Wysokim kontraście (pierwszy algorytm problemu)
Ostatnie 2 będą za darmo przez większość biblioteki uniwersyteckie / proxy.
N jest skończone i stosunkowo małe
W tym przypadku, można przejść do rozwiązania listy. Bardzo ciekawy artykuł w temacie jest dostępny bezpłatnie:
Istnieje kilka list kolorów do rozważenia:
- Lista 11 kolorów Boyntona, które prawie nigdy nie są mylone (dostępna w pierwszym artykule poprzedniej sekcji)
- Kelly ' s 22 kolory maksymalnego kontrastu (dostępne w powyższym papierze)
- http://chem8.org/uch/space-55036-do-blog-id-5333.html
- https://metacpan.org/pod/Color::Library::Dictionary::NBS_ISCC
- kolor Teoria: jak przekonwertować Munsell HVC NA RGB/HSB / HSL
Dla listy Kelly ' ego i Boyntona, dokonałem już konwersji na RGB (z wyjątkiem bieli i czerni, co powinno być oczywiste). Jakiś kod C#:
public static ReadOnlyCollection<Color> KellysMaxContrastSet
{
get { return _kellysMaxContrastSet.AsReadOnly(); }
}
private static readonly List<Color> _kellysMaxContrastSet = new List<Color>
{
UIntToColor(0xFFFFB300), //Vivid Yellow
UIntToColor(0xFF803E75), //Strong Purple
UIntToColor(0xFFFF6800), //Vivid Orange
UIntToColor(0xFFA6BDD7), //Very Light Blue
UIntToColor(0xFFC10020), //Vivid Red
UIntToColor(0xFFCEA262), //Grayish Yellow
UIntToColor(0xFF817066), //Medium Gray
//The following will not be good for people with defective color vision
UIntToColor(0xFF007D34), //Vivid Green
UIntToColor(0xFFF6768E), //Strong Purplish Pink
UIntToColor(0xFF00538A), //Strong Blue
UIntToColor(0xFFFF7A5C), //Strong Yellowish Pink
UIntToColor(0xFF53377A), //Strong Violet
UIntToColor(0xFFFF8E00), //Vivid Orange Yellow
UIntToColor(0xFFB32851), //Strong Purplish Red
UIntToColor(0xFFF4C800), //Vivid Greenish Yellow
UIntToColor(0xFF7F180D), //Strong Reddish Brown
UIntToColor(0xFF93AA00), //Vivid Yellowish Green
UIntToColor(0xFF593315), //Deep Yellowish Brown
UIntToColor(0xFFF13A13), //Vivid Reddish Orange
UIntToColor(0xFF232C16), //Dark Olive Green
};
public static ReadOnlyCollection<Color> BoyntonOptimized
{
get { return _boyntonOptimized.AsReadOnly(); }
}
private static readonly List<Color> _boyntonOptimized = new List<Color>
{
Color.FromArgb(0, 0, 255), //Blue
Color.FromArgb(255, 0, 0), //Red
Color.FromArgb(0, 255, 0), //Green
Color.FromArgb(255, 255, 0), //Yellow
Color.FromArgb(255, 0, 255), //Magenta
Color.FromArgb(255, 128, 128), //Pink
Color.FromArgb(128, 128, 128), //Gray
Color.FromArgb(128, 0, 0), //Brown
Color.FromArgb(255, 128, 0), //Orange
};
static public Color UIntToColor(uint color)
{
var a = (byte)(color >> 24);
var r = (byte)(color >> 16);
var g = (byte)(color >> 8);
var b = (byte)(color >> 0);
return Color.FromArgb(a, r, g, b);
}
A oto wartości RGB w reprezentacjach hex I 8-bit-per-channel:
kelly_colors_hex = [
0xFFB300, # Vivid Yellow
0x803E75, # Strong Purple
0xFF6800, # Vivid Orange
0xA6BDD7, # Very Light Blue
0xC10020, # Vivid Red
0xCEA262, # Grayish Yellow
0x817066, # Medium Gray
# The following don't work well for people with defective color vision
0x007D34, # Vivid Green
0xF6768E, # Strong Purplish Pink
0x00538A, # Strong Blue
0xFF7A5C, # Strong Yellowish Pink
0x53377A, # Strong Violet
0xFF8E00, # Vivid Orange Yellow
0xB32851, # Strong Purplish Red
0xF4C800, # Vivid Greenish Yellow
0x7F180D, # Strong Reddish Brown
0x93AA00, # Vivid Yellowish Green
0x593315, # Deep Yellowish Brown
0xF13A13, # Vivid Reddish Orange
0x232C16, # Dark Olive Green
]
kelly_colors = dict(vivid_yellow=(255, 179, 0),
strong_purple=(128, 62, 117),
vivid_orange=(255, 104, 0),
very_light_blue=(166, 189, 215),
vivid_red=(193, 0, 32),
grayish_yellow=(206, 162, 98),
medium_gray=(129, 112, 102),
# these aren't good for people with defective color vision:
vivid_green=(0, 125, 52),
strong_purplish_pink=(246, 118, 142),
strong_blue=(0, 83, 138),
strong_yellowish_pink=(255, 122, 92),
strong_violet=(83, 55, 122),
vivid_orange_yellow=(255, 142, 0),
strong_purplish_red=(179, 40, 81),
vivid_greenish_yellow=(244, 200, 0),
strong_reddish_brown=(127, 24, 13),
vivid_yellowish_green=(147, 170, 0),
deep_yellowish_brown=(89, 51, 21),
vivid_reddish_orange=(241, 58, 19),
dark_olive_green=(35, 44, 22))
Dla wszystkich programistów Java, oto Kolory JavaFX:
// Don't forget to import javafx.scene.paint.Color;
private static final Color[] KELLY_COLORS = {
Color.web("0xFFB300"), // Vivid Yellow
Color.web("0x803E75"), // Strong Purple
Color.web("0xFF6800"), // Vivid Orange
Color.web("0xA6BDD7"), // Very Light Blue
Color.web("0xC10020"), // Vivid Red
Color.web("0xCEA262"), // Grayish Yellow
Color.web("0x817066"), // Medium Gray
Color.web("0x007D34"), // Vivid Green
Color.web("0xF6768E"), // Strong Purplish Pink
Color.web("0x00538A"), // Strong Blue
Color.web("0xFF7A5C"), // Strong Yellowish Pink
Color.web("0x53377A"), // Strong Violet
Color.web("0xFF8E00"), // Vivid Orange Yellow
Color.web("0xB32851"), // Strong Purplish Red
Color.web("0xF4C800"), // Vivid Greenish Yellow
Color.web("0x7F180D"), // Strong Reddish Brown
Color.web("0x93AA00"), // Vivid Yellowish Green
Color.web("0x593315"), // Deep Yellowish Brown
Color.web("0xF13A13"), // Vivid Reddish Orange
Color.web("0x232C16"), // Dark Olive Green
};
Poniżej znajdują się niesortowane kolory kelly zgodnie z kolejnością powyżej.
Poniżej przedstawiono posortowane kolory kelly ' ego według odcieni (zauważ, że niektóre żółcienie nie są zbyt kontrastowe)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:44
Mam pomysł. Wyobraź sobie cylinder HSV
Określ górną i dolną granicę jasności i nasycenia. Definiuje to kwadratowy pierścień przekroju w przestrzeni.
Teraz rozrzuć N punktów losowo w tej przestrzeni.
Następnie zastosuj na nich iteracyjny algorytm odpychania, albo dla ustalonej liczby iteracji, albo do czasu ustabilizowania się punktów.
Teraz powinieneś mieć N punktów reprezentujących N kolorów, które są o różne, jak to możliwe, w przestrzeni kolorów, które Cię interesują.
Hugo
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-08 14:09:51
Jak odpowiedź Uri Cohena, ale zamiast tego jest generatorem. Zacznie używać kolorów daleko od siebie. Deterministyczne.
Próbka, lewy kolor pierwszy:
#!/usr/bin/env python3.3
import colorsys
import itertools
from fractions import Fraction
def zenos_dichotomy():
"""
http://en.wikipedia.org/wiki/1/2_%2B_1/4_%2B_1/8_%2B_1/16_%2B_%C2%B7_%C2%B7_%C2%B7
"""
for k in itertools.count():
yield Fraction(1,2**k)
def getfracs():
"""
[Fraction(0, 1), Fraction(1, 2), Fraction(1, 4), Fraction(3, 4), Fraction(1, 8), Fraction(3, 8), Fraction(5, 8), Fraction(7, 8), Fraction(1, 16), Fraction(3, 16), ...]
[0.0, 0.5, 0.25, 0.75, 0.125, 0.375, 0.625, 0.875, 0.0625, 0.1875, ...]
"""
yield 0
for k in zenos_dichotomy():
i = k.denominator # [1,2,4,8,16,...]
for j in range(1,i,2):
yield Fraction(j,i)
bias = lambda x: (math.sqrt(x/3)/Fraction(2,3)+Fraction(1,3))/Fraction(6,5) # can be used for the v in hsv to map linear values 0..1 to something that looks equidistant
def genhsv(h):
for s in [Fraction(6,10)]: # optionally use range
for v in [Fraction(8,10),Fraction(5,10)]: # could use range too
yield (h, s, v) # use bias for v here if you use range
genrgb = lambda x: colorsys.hsv_to_rgb(*x)
flatten = itertools.chain.from_iterable
gethsvs = lambda: flatten(map(genhsv,getfracs()))
getrgbs = lambda: map(genrgb, gethsvs())
def genhtml(x):
uint8tuple = map(lambda y: int(y*255), x)
return "rgb({},{},{})".format(*uint8tuple)
gethtmlcolors = lambda: map(genhtml, getrgbs())
if __name__ == "__main__":
print(list(itertools.islice(gethtmlcolors(), 100)))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-11 09:59:20
Ze względu na przyszłe pokolenia dodaję tutaj akceptowaną odpowiedź w Pythonie.
import numpy as np
import colorsys
def _get_colors(num_colors):
colors=[]
for i in np.arange(0., 360., 360. / num_colors):
hue = i/360.
lightness = (50 + np.random.rand() * 10)/100.
saturation = (90 + np.random.rand() * 10)/100.
colors.append(colorsys.hls_to_rgb(hue, lightness, saturation))
return colors
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-14 11:33:00
Wydaje się, że wszyscy przegapili istnienie bardzo użytecznej przestrzeni kolorów YUV, która została zaprojektowana, aby reprezentować postrzegane różnice kolorów w ludzkim systemie wizualnym. Odległości w YUV reprezentują różnice w postrzeganiu człowieka. Potrzebowałem tej funkcjonalności dla MagicCube4D, który implementuje 4-wymiarowe kostki Rubika i nieograniczoną liczbę innych łamigłówek 4D o dowolnej liczbie twarzy.
Moje rozwiązanie zaczyna się od wybrania losowych punktów w YUV, a następnie iteracyjnie rozbijanie dwóch najbliższych punktów i tylko konwersja do RGB przy zwracaniu wyniku. Metoda jest O (N^3), ale to nie ma znaczenia dla małych liczb lub tych, które mogą być buforowane. Z pewnością można go zwiększyć, ale wyniki wydają się być doskonałe.
Funkcja pozwala na opcjonalne określenie progów jasności, aby nie tworzyć kolorów, w których żaden składnik nie jest jaśniejszy lub ciemniejszy od podanych ilości. IE możesz nie chcieć wartości bliskich czerni lub bieli. To jest przydatne, gdy uzyskane kolory będą używane jako kolory podstawowe, które są później zacienione za pomocą oświetlenia, warstw, przezroczystości itp. i musi nadal wyglądać inaczej niż ich podstawowe kolory.
import java.awt.Color;
import java.util.Random;
/**
* Contains a method to generate N visually distinct colors and helper methods.
*
* @author Melinda Green
*/
public class ColorUtils {
private ColorUtils() {} // To disallow instantiation.
private final static float
U_OFF = .436f,
V_OFF = .615f;
private static final long RAND_SEED = 0;
private static Random rand = new Random(RAND_SEED);
/*
* Returns an array of ncolors RGB triplets such that each is as unique from the rest as possible
* and each color has at least one component greater than minComponent and one less than maxComponent.
* Use min == 1 and max == 0 to include the full RGB color range.
*
* Warning: O N^2 algorithm blows up fast for more than 100 colors.
*/
public static Color[] generateVisuallyDistinctColors(int ncolors, float minComponent, float maxComponent) {
rand.setSeed(RAND_SEED); // So that we get consistent results for each combination of inputs
float[][] yuv = new float[ncolors][3];
// initialize array with random colors
for(int got = 0; got < ncolors;) {
System.arraycopy(randYUVinRGBRange(minComponent, maxComponent), 0, yuv[got++], 0, 3);
}
// continually break up the worst-fit color pair until we get tired of searching
for(int c = 0; c < ncolors * 1000; c++) {
float worst = 8888;
int worstID = 0;
for(int i = 1; i < yuv.length; i++) {
for(int j = 0; j < i; j++) {
float dist = sqrdist(yuv[i], yuv[j]);
if(dist < worst) {
worst = dist;
worstID = i;
}
}
}
float[] best = randYUVBetterThan(worst, minComponent, maxComponent, yuv);
if(best == null)
break;
else
yuv[worstID] = best;
}
Color[] rgbs = new Color[yuv.length];
for(int i = 0; i < yuv.length; i++) {
float[] rgb = new float[3];
yuv2rgb(yuv[i][0], yuv[i][1], yuv[i][2], rgb);
rgbs[i] = new Color(rgb[0], rgb[1], rgb[2]);
//System.out.println(rgb[i][0] + "\t" + rgb[i][1] + "\t" + rgb[i][2]);
}
return rgbs;
}
public static void hsv2rgb(float h, float s, float v, float[] rgb) {
// H is given on [0->6] or -1. S and V are given on [0->1].
// RGB are each returned on [0->1].
float m, n, f;
int i;
float[] hsv = new float[3];
hsv[0] = h;
hsv[1] = s;
hsv[2] = v;
System.out.println("H: " + h + " S: " + s + " V:" + v);
if(hsv[0] == -1) {
rgb[0] = rgb[1] = rgb[2] = hsv[2];
return;
}
i = (int) (Math.floor(hsv[0]));
f = hsv[0] - i;
if(i % 2 == 0)
f = 1 - f; // if i is even
m = hsv[2] * (1 - hsv[1]);
n = hsv[2] * (1 - hsv[1] * f);
switch(i) {
case 6:
case 0:
rgb[0] = hsv[2];
rgb[1] = n;
rgb[2] = m;
break;
case 1:
rgb[0] = n;
rgb[1] = hsv[2];
rgb[2] = m;
break;
case 2:
rgb[0] = m;
rgb[1] = hsv[2];
rgb[2] = n;
break;
case 3:
rgb[0] = m;
rgb[1] = n;
rgb[2] = hsv[2];
break;
case 4:
rgb[0] = n;
rgb[1] = m;
rgb[2] = hsv[2];
break;
case 5:
rgb[0] = hsv[2];
rgb[1] = m;
rgb[2] = n;
break;
}
}
// From http://en.wikipedia.org/wiki/YUV#Mathematical_derivations_and_formulas
public static void yuv2rgb(float y, float u, float v, float[] rgb) {
rgb[0] = 1 * y + 0 * u + 1.13983f * v;
rgb[1] = 1 * y + -.39465f * u + -.58060f * v;
rgb[2] = 1 * y + 2.03211f * u + 0 * v;
}
public static void rgb2yuv(float r, float g, float b, float[] yuv) {
yuv[0] = .299f * r + .587f * g + .114f * b;
yuv[1] = -.14713f * r + -.28886f * g + .436f * b;
yuv[2] = .615f * r + -.51499f * g + -.10001f * b;
}
private static float[] randYUVinRGBRange(float minComponent, float maxComponent) {
while(true) {
float y = rand.nextFloat(); // * YFRAC + 1-YFRAC);
float u = rand.nextFloat() * 2 * U_OFF - U_OFF;
float v = rand.nextFloat() * 2 * V_OFF - V_OFF;
float[] rgb = new float[3];
yuv2rgb(y, u, v, rgb);
float r = rgb[0], g = rgb[1], b = rgb[2];
if(0 <= r && r <= 1 &&
0 <= g && g <= 1 &&
0 <= b && b <= 1 &&
(r > minComponent || g > minComponent || b > minComponent) && // don't want all dark components
(r < maxComponent || g < maxComponent || b < maxComponent)) // don't want all light components
return new float[]{y, u, v};
}
}
private static float sqrdist(float[] a, float[] b) {
float sum = 0;
for(int i = 0; i < a.length; i++) {
float diff = a[i] - b[i];
sum += diff * diff;
}
return sum;
}
private static double worstFit(Color[] colors) {
float worst = 8888;
float[] a = new float[3], b = new float[3];
for(int i = 1; i < colors.length; i++) {
colors[i].getColorComponents(a);
for(int j = 0; j < i; j++) {
colors[j].getColorComponents(b);
float dist = sqrdist(a, b);
if(dist < worst) {
worst = dist;
}
}
}
return Math.sqrt(worst);
}
private static float[] randYUVBetterThan(float bestDistSqrd, float minComponent, float maxComponent, float[][] in) {
for(int attempt = 1; attempt < 100 * in.length; attempt++) {
float[] candidate = randYUVinRGBRange(minComponent, maxComponent);
boolean good = true;
for(int i = 0; i < in.length; i++)
if(sqrdist(candidate, in[i]) < bestDistSqrd)
good = false;
if(good)
return candidate;
}
return null; // after a bunch of passes, couldn't find a candidate that beat the best.
}
/**
* Simple example program.
*/
public static void main(String[] args) {
final int ncolors = 10;
Color[] colors = generateVisuallyDistinctColors(ncolors, .8f, .3f);
for(int i = 0; i < colors.length; i++) {
System.out.println(colors[i].toString());
}
System.out.println("Worst fit color = " + worstFit(colors));
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-03 00:13:59
Oto rozwiązanie do zarządzania Twoim" odrębnym " problemem, który jest całkowicie przesadny:
Stwórz kulę jednostki i zrzuć na nią punkty odpychające ładunki. Uruchom system cząstek, dopóki nie przestaną się poruszać (lub delta jest "wystarczająco mała"). W tym momencie każdy z punktów jest tak daleko od siebie, jak to możliwe. Konwertuj (x, y, z) NA rgb.
Wspominam o tym, ponieważ dla pewnych klas problemów tego typu rozwiązanie może działać lepiej niż brute force.
I pierwotnie widział to podejście tutaj do tesselowania kuli.
Ponownie, najbardziej oczywiste rozwiązania przesuwania przestrzeni HSL lub przestrzeni RGB będą prawdopodobnie działać dobrze.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-22 21:51:25
Starałbym się naprawić nasycenie i luminację na maksimum i skupić się tylko na odcieniu. Jak widzę, H może przejść od 0 do 255, a następnie owija się. Teraz gdybyś chciał dwa kontrastujące kolory, wziąłbyś przeciwne strony tego pierścienia, tj. 0 i 128. Gdybyś chciał 4 kolory, wziąłbyś jakieś oddzielone 1/4 z 256 długości okręgu, czyli 0, 64,128,192. I oczywiście, jak sugerowali inni, gdy potrzebujesz N kolorów, możesz je po prostu rozdzielić przez 256 / n.]}
Co bym dodał do idea ta polega na użyciu odwrotnej reprezentacji liczby binarnej do utworzenia tego ciągu. Zobacz też:
0 = 00000000 after reversal is 00000000 = 0
1 = 00000001 after reversal is 10000000 = 128
2 = 00000010 after reversal is 01000000 = 64
3 = 00000011 after reversal is 11000000 = 192
... w ten sposób, jeśli potrzebujesz N różnych kolorów, możesz po prostu wziąć pierwsze n liczb, odwrócić je i uzyskać jak najwięcej odległych punktów (N jest potęgą dwóch), zachowując jednocześnie, że każdy prefiks sekwencji różni się bardzo.
Był to ważny cel w moim przypadku użycia, ponieważ miałem wykres, w którym kolory zostały posortowane według obszaru objętego tym kolor. Chciałem, aby największe obszary wykresu miały duży kontrast, i byłem w porządku z niektórymi małymi obszarami, aby mieć kolory podobne do tych z top 10, ponieważ było oczywiste dla czytelnika, który z nich jest który, obserwując tylko obszar.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-06 06:57:39
Jeśli N jest wystarczająco duże, dostaniesz podobne kolory. Jest ich tylko tyle na świecie.
Dlaczego nie po prostu równomiernie rozprowadzić ich po widmie, w ten sposób:
IEnumerable<Color> CreateUniqueColors(int nColors)
{
int subdivision = (int)Math.Floor(Math.Pow(nColors, 1/3d));
for(int r = 0; r < 255; r += subdivision)
for(int g = 0; g < 255; g += subdivision)
for(int b = 0; b < 255; b += subdivision)
yield return Color.FromArgb(r, g, b);
}
Jeśli chcesz pomieszać sekwencję tak, aby podobne kolory nie były obok siebie, Możesz przetasować wynikową listę.
Czy ja o tym nie myślę?Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-22 20:43:11
Jest to trywialne w Matlabie (istnieje Komenda hsv):
cmap = hsv(number_of_colors)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-11 01:54:23
Napisałem pakiet dla R o nazwie qualpalr , który został zaprojektowany specjalnie do tego celu. Polecam spojrzeć na winietę , aby dowiedzieć się, jak to działa, ale postaram się podsumować główne punkty.
Qualpalr pobiera specyfikację kolorów w przestrzeni kolorów HSL (która została opisana wcześniej w tym wątku), projektuje ją do przestrzeni kolorów DIN99d (która jest percepcyjnie jednorodna) i znajduje n
, które maksymalizują minimalną odległość między nimi każdy je znajdzie.
# Create a palette of 4 colors of hues from 0 to 360, saturations between
# 0.1 and 0.5, and lightness from 0.6 to 0.85
pal <- qualpal(n = 4, list(h = c(0, 360), s = c(0.1, 0.5), l = c(0.6, 0.85)))
# Look at the colors in hex format
pal$hex
#> [1] "#6F75CE" "#CC6B76" "#CAC16A" "#76D0D0"
# Create a palette using one of the predefined color subspaces
pal2 <- qualpal(n = 4, colorspace = "pretty")
# Distance matrix of the DIN99d color differences
pal2$de_DIN99d
#> #69A3CC #6ECC6E #CA6BC4
#> 6ECC6E 22
#> CA6BC4 21 30
#> CD976B 24 21 21
plot(pal2)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-02 17:32:13
Myślę, że ten prosty rekurencyjny algorytm uzupełnia zaakceptowaną odpowiedź, aby wygenerować różne wartości odcienia. Zrobiłem go dla hsv, ale może być również używany do innych przestrzeni kolorów.
Generuje barwy w cyklach, jak najbardziej oddzielonych od siebie w każdym cyklu.
/**
* 1st cycle: 0, 120, 240
* 2nd cycle (+60): 60, 180, 300
* 3th cycle (+30): 30, 150, 270, 90, 210, 330
* 4th cycle (+15): 15, 135, 255, 75, 195, 315, 45, 165, 285, 105, 225, 345
*/
public static float recursiveHue(int n) {
// if 3: alternates red, green, blue variations
float firstCycle = 3;
// First cycle
if (n < firstCycle) {
return n * 360f / firstCycle;
}
// Each cycle has as much values as all previous cycles summed (powers of 2)
else {
// floor of log base 2
int numCycles = (int)Math.floor(Math.log(n / firstCycle) / Math.log(2));
// divDown stores the larger power of 2 that is still lower than n
int divDown = (int)(firstCycle * Math.pow(2, numCycles));
// same hues than previous cycle, but summing an offset (half than previous cycle)
return recursiveHue(n % divDown) + 180f / divDown;
}
}
Nie udało mi się znaleźć takiego algorytmu. Mam nadzieję, że to pomoże, to mój pierwszy post tutaj.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-09 13:04:15