renk tekerlekleri oluşturmak için Fonksiyon

oy
63

Bu benim sözde çözüldü defalarca ve oldukça için bir çözüm bulmadım şeydir.

Sorun üretmek için bir yol ile gelip etmektir Nnerede mümkün olduğunca ayırt edilebilir renkleri, Nbir parametredir.

Oluştur 01/08/2008 saat 19:42
kaynak kullanıcı
Diğer dillerde...                            


8 cevaplar

oy
23

Bu konuda İlk düşüncem "birbirinden mesafeyi maksimize bir alanda N vektörleri oluşturmak için nasıl" dir.

RGB (veya renk uzayında bir esasını oluşturduğu kullanan diğer ölçek) sadece vektörleri olduğunu görebilirsiniz. Bir göz atın Rastgele Noktası toplama . Eğer ayrı maksimize edilir vektörlerin kümesi edindikten sonra, sonrası için karma tablo falan bunları kaydedebilir ve sadece birbirlerinden birbirinden azami olduklarını arzu tüm renkleri elde etmek için üzerlerine rastgele dönüşlerinin gerçekleştirebilirsiniz!

daha bu sorun hakkında düşünme, sözlük sırasında → muhtemelen (0,0,0), doğrusal bir şekilde (255,255,255) renkleri eşleştirmek ve sonra eşit olarak dağıtmak için daha iyi olurdu.

Gerçekten bu kadar iyi çalışacağını bilmiyorum, ama bu yana, diyelim olmalıdır:

n = 10

biz 16777216 renkler (^ 3 256) biliyorum.

Biz kullanabilirsiniz Toka Algoritması 515 leksikografik endeksli rengi bulmak için. \ Frac {\ binom {256 ^ 3} {3}} {n} * ı. Muhtemelen taşması önlemek ve muhtemelen bazı küçük hız artışı eklemek algoritma düzenlemek gerekecek.

Cevap 02/08/2008 saat 20:03
kaynak kullanıcı

oy
17

Bu ve daha sonra seçtiğiniz ColorSpace (dönüştürme L *, a *, b * senin mesafeye metrik olarak koordinatları arasındaki Öklid uzaklığı kullanarak) "algısal üniforma" ColorSpace içinde maksimum uzak renkler, örneğin CIELAB bulmak için en iyi olurdu. Algısal homojenliği insan görme sistemi lineersizlikleri yaklaştığı renk aralığını verdiği ile elde edilir.

Cevap 12/09/2008 saat 20:00
kaynak kullanıcı

oy
7

Bazı ilgili kaynaklar:

ColorBrewer - tasarlanmış renklerin takımları haritalarda kullanılmak üzere maksimum ayırt edilebilir nitelikte olması.

Kaçış RGBland: İstatistiksel Grafik için Renkleri seçme - hcl renk uzayında iyi (yani maksimum ayırt) renk jeneratör grupları için algoritmaların kümesi anlatan bir teknik rapor.

Cevap 18/09/2008 saat 17:01
kaynak kullanıcı

oy
6

İşte belirtilen parlaklığının bir HSL renk çarkında eşit RGB renklerini ayırmak için bazı kodudur.

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;
}
Cevap 27/09/2008 saat 17:39
kaynak kullanıcı

oy
3

Eğer renkleri kurmak sipariş bir faktör de değil midir?

Eğer Dillie-Os fikri kullanırsanız gibi mümkün olduğunca renkleri karıştırmak gerekir. 0 ila 64 128 256, birinden diğerine olan. ama bir tekerlek 0 256 64 128 daha "ayrı" olacağını

Bu mantıklı mı?

Cevap 02/08/2008 saat 19:16
kaynak kullanıcı

oy
1

Bu eski bir yazı biliyorum ama konuya bir PHP çözüm arayan ve son olarak basit bir çözüm ile geldi ise ben buldum:

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] 
    } 
}

Dolayısıyla, sadece $ i renk, $ n muhtemel renk sayısını belirler random_color () işlevini çağırmak, $ parlaklık br doygunluğu ve $ oturdu.

Cevap 19/10/2011 saat 02:58
kaynak kullanıcı

oy
1

Ben insan gözü ayrı 4'ten az değerleri arasında ayrım yapamaz yerde okudum. böylece bu akılda tutulması gereken bir şeydir. Aşağıdaki algoritma bu telafi etmez.

Bunun ne istediğini tam olarak emin değilim, ama bu rastgele tekrarlanmayan renk değerlerini oluşturmak için bir yoldur:

(Önde, tutarsız sözde kodu dikkat edin)

//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);
      }
   }
}

Daha iyi görüş için bu optimize olabilir bir yolu, her yeni renk ve dizideki tüm renklerin arasındaki mesafeyi karşılaştırmak olacaktır:

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);
}

Ama bu yaklaşım önemli ölçüde algoritma yavaşlatmak olacaktır.

Başka yolu da rasgelelik hurda ve sistematik her 4 değerlere geçmesi ve yukarıdaki örnekte bir diziye bir renk katmak olacaktır.

Cevap 01/08/2008 saat 20:36
kaynak kullanıcı

oy
0

Biz Lab gibi bir algısal renk alanını (veya başka algısal doğrusal renk alanını) olup RGB kullanmak gerekir "en ayırt" başarmak için. Ayrıca, biz uzay boyutunu azaltmak için bu alanı kuantize edebilirsiniz.

Tüm olası nicelenmiş girişlerle dolu 3D boşluk oluşturun ve birlikte K-Means algoritması çalıştırın k=N. Elde edilen merkezler / "anlamına gelir" yaklaşık olarak en distinguishabl birbirinden olmalıdır.

Cevap 07/02/2014 saat 18:43
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more