2009-04-08 17 views
31

Generuję niektóre wykresy, które wymagają ciągów szesnastkowych dla kolorów.Jak utworzyć losowy ciąg szesnastkowy reprezentujący kolor?

przykład:

<dataseries name="ford" color="FF00FF" /> 

tworzę one dynamicznie tak ja, aby wygenerować kod sześciokątną losowego każdy dataseries.

Jaki jest najlepszy sposób na zrobienie tego?

+0

Po prostu zauważyłem, że mój przykład się nie powiódł. Zgaduję, że to dlatego, że był to ciąg znaków xml ... No cóż, to nie miało znaczenia, ponieważ odpowiedź zadziałała świetnie. – rahkim

+1

@rahkim - zaktualizowano pytanie, aby to poprawić i dodano bardziej znaczący tytuł –

Odpowiedz

94

Najprostszym sposobem jest użycie String.Format i użycie formatu szesnastkowego dla argumentu.

var random = new Random(); 
var color = String.Format("#{0:X6}", random.Next(0x1000000)); // = "#A197B9" 
+2

+1 To jest tak niesamowicie proste, jasne i szybkie. –

+0

Wiem, po raz pierwszy wpatrywałam się w myśl o użyciu tablicy i elementach zbioru, a potem pamiętam, że String.Format może wykonywać szesnastkowo. – Samuel

+2

Popraw mnie, jeśli się mylę, ale z tym kodem, nigdy nie wygenerujesz wartości 0xFFFFFF, ponieważ liczba całkowita, którą przechodzisz do metody Next, jest nieobejmującą górną granicą. Tak więc, aby otrzymać wartość 0xFFFFFF, potrzebujesz random.Next (0x1000000). –

4
Random rand = new Random(); // specify a seed 
int r = rand.Next(0x1000000); 
Console.WriteLine("#{0:X6}", r); 
+1

To nie obsługuje niskich wartości. 0x00FFFF zmienia się w #FFFF, który nie jest taki sam jak w # 00FFFF. – Samuel

15

IMO, czysto losowe kolory mogą nie być korzystne, jak trzeba kolory, które są rozróżnialne w ludzkich oczach.

A co z ustawianiem pewnej liczby kolorów i losowaniem ich?

Być może można znaleźć lepsze odpowiedzi w niektórych bibliotekach opartych na otwartym kodzie źródłowym.

+0

To byłaby preferowana metoda, ale być może OP ma inne powody dla zupełnie przypadkowych kolorów. – Samuel

+0

Myślałem o tym, ponieważ niektóre kolory mogą się ze sobą łączyć. Nie byłem pewien, ile mam ustawić, ponieważ mogę mieć bardzo dużą liczbę serii. – rahkim

+0

Może pomóc hybryda ustawień wstępnych i losowych. Precyzyjnie zaprogramuj około 10 ładnie wyglądających kolorów. Wybierz losowo, jeśli jest więcej. Generalnie niewytrenowane oczy zaczynają się mylić na zbyt kolorowym wykresie, więc jakie dokładnie używane kolory nie są naprawdę ważne – Canton

12

Odpowiedź Samuela jest najlepszym sposobem, aby to zrobić, po prostu upewnij się, że jeśli generujesz kolory wewnątrz pętli, to za każdym razem nie tworzysz nowego obiektu, ponieważ generator new Random() zasysa generator za pomocą zegara systemowego. Twoja pętla będzie działać szybciej, niż zegar może zaznaczyć, więc będziesz generować kilka takich samych kolorów w kółko, ponieważ random jest wysiewany o tej samej wartości.

To powinno wyglądać mniej więcej tak:

int numColors = 10; 
var colors = new List<string>(); 
var random = new Random(); // Make sure this is out of the loop! 
for (int i = 0; i < numColors; i++) 
{ 
    colors.Add(String.Format("#{0:X6}", random.Next(0x1000000))); 
} 

zamiast:

int numColors = 10; 
var colors = new List<string>(); 
for (int i = 0; i < numColors; i++) 
{ 
    var random = new Random(); // Don't put this here! 
    colors.Add(String.Format("#{0:X6}", random.Next(0x1000000))); 
} 
+0

Miłe czytanie myśli! –

+1

To wyjaśnia, dlaczego rahkim uzyskuje losowe kolory podczas używania punktu przerwania. lol – Samuel

+0

To nawet nie przyszło mi przez myśl. Czy dodajesz kolory do listy z jakiegoś powodu?Tylko dobra praktyka, czy jest coś, czego im brakuje? – rahkim

11

dobrym sposobem na generowanie ładny zestaw kolorów jest zdefiniowanie ich za pomocą stałej nasycenie i jasność i różnicować odcień.

  1. Ustaw nasycenie i jasność na coś, co lubisz, powiedzmy 50% nasycenia i 90% jasności.
  2. Teraz podziel 360 stopni odcienia przez liczbę różnych kolorów, które chcesz.
  3. wybrać kolory z HSV wykorzystujące ten interwał Hue i stałą S i V.

To daje ładny zestaw kolorów, które wyglądają tak, jakby pochodziły z tego samego „set” - wszystko pastelowe, albo wszystkie intensywne, albo wszystkie białawe, cokolwiek. Kodowanie jest bardzo łatwe, jeśli masz Color.FromHSV().

Prawdopodobnie przestaje działać, gdy pojawi się zbyt wiele kolorów, będą one nie do odróżnienia. Ale i tak prawdopodobnie dostaniesz ten problem.

W pseudo kod:

Sat = 0.5 * 255 //assuming we want range 0-255... 
Brightness = 0.9 * 255 
NumberOfColours = 7 
HueSeparation = 360/7 
Colors = [] 
for (i = 0 ; i< NumberOfColours; i++) 
    Colors.Add(Color.FromHSV(HueSeparation * i, Sat, Brightness) 

lub

n = 7 
Colors = [Color.FromHSV(x*360/n, 128, 230) for x in range(n)] 

(lubię listowych ...)

+0

Schludny pomysł. Żałuję, że nie mogę umieścić tego w kodzie. ;-) – rahkim

3

Zauważyłem, że ty (Rahkim) skomentowałeś post Grega, że ​​chciałbyś, abyś wpadł na jego pomysł (utrzymując nasycenie i wartość na stałym poziomie, zmieniając odcień ... dobry pomysł) w kod. Możesz! Lub raczej ktoś już ma dla ciebie!

Znalazłem ten wpis na blogu na Converting HSV to RGB colour using C# i jestem pewien, że jest tam więcej. Prawdopodobnie skończysz z ładniejszym zestawem kolorów w ten sposób, niż wybierając je zupełnie losowo.

Dodatkowo, oczywiście, metoda ta pozwala łatwo uzyskać ładny zestaw kolorów ... od odcienia idzie od 0-359, można zrobić coś jak ustawić Hue coś takiego:

Hue = (PreviousHue + 50) % 360; 

(Wybrałem 50, ponieważ nie jest równomiernie 360, więc jeśli przekroczysz 360, nie zaczniesz od razu powtarzać odcieni. Musisz mieć pewność, że otrzymasz idealną separację w zależności od tego, ile różne kolory, których się spodziewasz.)

W ten sposób nie musisz się martwić o przypadek, w którym kod losowo wybiera dwa kolory, które są bardzo zbliżone do jednego ją, gdy wciąż jest dużo niewykorzystanej przestrzeni "barwy".

+0

Podoba mi się to. Daje mi to pewną elastyczność. – rahkim

Powiązane problemy