Funkcja tworzenia kół kolorów [zamknięta]

zamknięte . To pytanie musi być bardziej skoncentrowane . Obecnie nie przyjmuje odpowiedzi.

Chcesz poprawić to pytanie? Update the question so it edytując ten post.

Zamknięte 3 lata temu .

Popraw to pytanie

To jest coś, co pseudo-rozwiązałem wiele razy i nigdy nie znalazłem rozwiązania.

Problemem jest wymyślenie sposobu generowania N kolorów, które są jak rozróżnialne, gdy N jest parametrem.

Author: Rann Lifshitz, 2008-08-01

8 answers

Moja pierwsza myśl na ten temat jest " jak wygenerować N wektorów w przestrzeni, które maksymalizują odległość od siebie."

Widać, że RGB (lub każda inna skala, której używasz, która tworzy podstawę w przestrzeni kolorów) to tylko Wektory. Spójrz na losowe Wybieranie punktów . Gdy masz zestaw wektorów, które są zmaksymalizowane od siebie, możesz zapisać je w tabeli hash lub czymś innym na później i po prostu wykonać na nich losowe obroty, aby uzyskać wszystkie pożądane kolory, które są maksymalnie od siebie siebie nawzajem!

Myśląc bardziej o tym problemie, lepiej byłoby odwzorować kolory w sposób liniowy, ewentualnie (0,0,0) → (255,255,255) leksykograficznie, a następnie rozłożyć je równomiernie.

Naprawdę Nie wiem, jak dobrze to zadziała, ale powinno, powiedzmy:

n = 10

Wiemy, że mamy 16777216 kolorów (256^3).

Możemy użyć algorytmu klamry 515 , aby znaleźć leksykograficznie indeksowany kolor.\frac {\binom {256^3} {3}} {n} * i. Prawdopodobnie będziesz musiał edytować algorytm aby uniknąć przepełnienia i prawdopodobnie dodać kilka drobnych ulepszeń prędkości.

 27
Author: nlucaroni,
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
2018-05-30 13:55:59

Najlepiej byłoby znaleźć Kolory maksymalnie odległe w "percepcyjnie jednolitej" przestrzeni kolorów, np. CIELAB (używając euklidesowej odległości między współrzędnymi L*, a*, B* jako metryki odległości), a następnie przekształcić je w wybraną przestrzeń kolorów. Percepcyjna jednolitość jest osiągana przez dostosowanie przestrzeni kolorów w celu przybliżenia nieliniowości w ludzkim systemie wizualnym.

 20
Author: Liudvikas Bukys,
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-01-30 15:14:29

Niektóre powiązane zasoby:

ColorBrewer - zestawy kolorów przeznaczone do maksymalnego rozróżniania na mapach.

Rgbland: Selecting Colors for Statistical Graphics - raport techniczny opisujący zbiór algorytmów generowania dobrych (tj. maksymalnie rozróżnialnych) zestawów kolorów w przestrzeni barw hcl.

 11
Author: hadley,
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
2008-09-18 16:01:24

Oto kod do równomiernego przydzielania kolorów RGB wokół koła kolorów HSL o określonej jasności.

class cColorPicker
{
public:
    void Pick( vector<DWORD>&v_picked_cols, int count, int bright = 50 );
private:
    DWORD HSL2RGB( int h, int s, int v );
    unsigned char ToRGB1(float rm1, float rm2, float rh);
};
/**

  Evenly allocate RGB colors around HSL color wheel

  @param[out] v_picked_cols  a vector of colors in RGB format
  @param[in]  count   number of colors required
  @param[in]  bright  0 is all black, 100 is all white, defaults to 50

  based on Fig 3 of http://epub.wu-wien.ac.at/dyn/virlib/wp/eng/mediate/epub-wu-01_c87.pdf?ID=epub-wu-01_c87

*/

void cColorPicker::Pick( vector<DWORD>&v_picked_cols, int count, int bright )
{
    v_picked_cols.clear();
    for( int k_hue = 0; k_hue < 360; k_hue += 360/count )
        v_picked_cols.push_back( HSL2RGB( k_hue, 100, bright ) );
}
/**

  Convert HSL to RGB

  based on http://www.codeguru.com/code/legacy/gdi/colorapp_src.zip

*/

DWORD cColorPicker::HSL2RGB( int h, int s, int l )
{
    DWORD ret = 0;
    unsigned char r,g,b;

    float saturation = s / 100.0f;
    float luminance = l / 100.f;
    float hue = (float)h;

    if (saturation == 0.0) 
    {
      r = g = b = unsigned char(luminance * 255.0);
    }
    else
    {
      float rm1, rm2;

      if (luminance <= 0.5f) rm2 = luminance + luminance * saturation;  
      else                     rm2 = luminance + saturation - luminance * saturation;
      rm1 = 2.0f * luminance - rm2;   
      r   = ToRGB1(rm1, rm2, hue + 120.0f);   
      g = ToRGB1(rm1, rm2, hue);
      b  = ToRGB1(rm1, rm2, hue - 120.0f);
    }

    ret = ((DWORD)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)));

    return ret;
}


unsigned char cColorPicker::ToRGB1(float rm1, float rm2, float rh)
{
  if      (rh > 360.0f) rh -= 360.0f;
  else if (rh <   0.0f) rh += 360.0f;

  if      (rh <  60.0f) rm1 = rm1 + (rm2 - rm1) * rh / 60.0f;   
  else if (rh < 180.0f) rm1 = rm2;
  else if (rh < 240.0f) rm1 = rm1 + (rm2 - rm1) * (240.0f - rh) / 60.0f;      

  return static_cast<unsigned char>(rm1 * 255);
}

int _tmain(int argc, _TCHAR* argv[])
{
    vector<DWORD> myCols;
    cColorPicker colpick;
    colpick.Pick( myCols, 20 );
    for( int k = 0; k < (int)myCols.size(); k++ )
        printf("%d: %d %d %d\n", k+1,
        ( myCols[k] & 0xFF0000 ) >>16,
        ( myCols[k] & 0xFF00 ) >>8,
        ( myCols[k] & 0xFF ) );

    return 0;
}
 10
Author: ravenspoint,
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-04-30 11:29:24

Czy nie jest to również czynnik, który kolejność ustawić kolory?

Jak używasz dillie-Os idea musisz mieszać kolory jak najwięcej. 0 64 128 256 ale 0 256 64 128 w Kole byłoby bardziej "osobno"

Czy to ma sens?

 5
Author: svrist,
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
2008-08-02 18:16:07

Czytałem gdzieś, że ludzkie oko nie może odróżnić mniej niż 4 wartości od siebie. więc to jest coś, o czym należy pamiętać. Poniższy algorytm tego nie kompensuje.

Nie jestem pewien, czy to jest dokładnie to, czego chcesz, ale jest to jeden ze sposobów na losowo generowanie nie powtarzających się wartości kolorów:

(Uwaga, niespójny pseudo-kod przed nami)

//colors entered as 0-255 [R, G, B]
colors = []; //holds final colors to be used
rand = new Random();

//assumes n is less than 16,777,216
randomGen(int n){
   while (len(colors) < n){
      //generate a random number between 0,255 for each color
      newRed = rand.next(256);
      newGreen = rand.next(256);
      newBlue = rand.next(256);
      temp = [newRed, newGreen, newBlue];
      //only adds new colors to the array
      if temp not in colors {
         colors.append(temp);
      }
   }
}

Jednym ze sposobów optymalizacji tego dla lepszej widoczności byłoby porównanie odległości między każdym nowym kolorem i wszystkimi kolory w tablicy:

for item in color{
   itemSq = (item[0]^2 + item[1]^2 + item[2]^2])^(.5);
   tempSq = (temp[0]^2 + temp[1]^2 + temp[2]^2])^(.5);
   dist = itemSq - tempSq;
   dist = abs(dist);
}
//NUMBER can be your chosen distance apart.
if dist < NUMBER and temp not in colors {
   colors.append(temp);
}
Ale takie podejście znacznie spowolniłoby Twój algorytm.

Innym sposobem byłoby pozbycie się losowości i systematyczne przechodzenie przez wszystkie 4 wartości i dodanie koloru do tablicy w powyższym przykładzie.

 3
Author: helloandre,
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
2008-08-01 19:36:46
function random_color($i = null, $n = 10, $sat = .5, $br = .7) {
    $i = is_null($i) ? mt_rand(0,$n) : $i;
    $rgb = hsv2rgb(array($i*(360/$n), $sat, $br));
    for ($i=0 ; $i<=2 ; $i++) 
        $rgb[$i] = dechex(ceil($rgb[$i]));
    return implode('', $rgb);
}

function hsv2rgb($c) { 
    list($h,$s,$v)=$c; 
    if ($s==0) 
        return array($v,$v,$v); 
    else { 
        $h=($h%=360)/60; 
        $i=floor($h); 
        $f=$h-$i; 
        $q[0]=$q[1]=$v*(1-$s); 
        $q[2]=$v*(1-$s*(1-$f)); 
        $q[3]=$q[4]=$v; 
        $q[5]=$v*(1-$s*$f); 
        return(array($q[($i+4)%6]*255,$q[($i+2)%6]*255,$q[$i%6]*255)); //[1] 
    } 
}

Wystarczy więc wywołać funkcję random_color(), Gdzie $i określa kolor, $n liczbę możliwych kolorów, $sat nasycenie i $br jasność.

 3
Author: Mauro,
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
2020-07-05 12:19:01

Aby osiągnąć "najbardziej rozpoznawalne", musimy użyć percepcyjnej przestrzeni kolorów, takiej jak Lab (lub innej percepcyjnie liniowej przestrzeni kolorów) innej niż RGB. Możemy również kwantyfikować tę przestrzeń, aby zmniejszyć jej rozmiar.

Wygeneruj pełną przestrzeń 3D ze wszystkimi możliwymi skwantowanymi wpisami i uruchom algorytm k-means z K=N. Powstałe centra / "środki" powinny być w przybliżeniu najbardziej odróżnialne od siebie.

 3
Author: Adi Shavit,
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
2020-07-05 21:49:16