سؤال

هذا شيء لقد الزائفة حلها عدة مرات ولم تماما وجدت الحل.

المشكلة هي أن يأتي مع وسيلة لتوليد N الألوان التي يمكن تمييزها ممكن حيث N هي معلمة.

هل كانت مفيدة؟

المحلول

فكرتي الأولى على هذا هو "كيفية توليد ن المتجهات في الفضاء التي تزيد المسافة عن بعضها البعض."

يمكنك أن ترى أن RGB (أو أي مقياس يمكنك استخدام هذا يشكل أساس في مساحة اللون) هي مجرد ناقلات.نلقي نظرة على نقطة عشوائية الانتقاء.مرة واحدة لديك مجموعة من النواقل التي هي تعظيم حدة ، يمكنك حفظها في جدول تجزئة أو شيء في وقت لاحق ، مجرد أداء عشوائي تناوب عليها للحصول على جميع الألوان التي تريدها أن الحد الأقصى بعيدا عن بعضها البعض!

التفكير في هذه المشكلة أكثر من ذلك ، سيكون من الأفضل أن خريطة الألوان في الخطية بطريقة ربما (0,0,0) → (255,255,255) lexicographically ثم توزيعها بالتساوي.

أنا حقا لا أعرف كيف سيكون هذا العمل ، ولكن يجب أن منذ, دعونا نقول:

n = 10

ونحن نعرف أن لدينا 16777216 لونا (256^3).

يمكننا استخدام الأبازيم خوارزمية 515 العثور على lexicographically فهرسة اللون.\frac {\binom {256^3} {3}} {n} * i.ربما سيكون لديك لتحرير خوارزمية لتجنب تجاوز وربما إضافة بعض طفيفة تحسينات في السرعة.

نصائح أخرى

سيكون من الأفضل للعثور على الألوان بعيد الحد الأقصى في "إدراكيا موحدة" colorspace مثلاCIELAB (باستخدام المسافة الإقليدية بين L* a* b* الإحداثيات الخاصة بك المسافة المترية) ثم تحويل إلى colorspace من اختيارك.الإدراك الحسي التوحيد يتحقق من خلال التغيير والتبديل في colorspace لتقريب اللاخطية في النظام البصري.

بعض الموارد ذات الصلة:

ColorBrewer - مجموعات من الألوان تهدف إلى الحد الأقصى مميزة للاستخدام على الخرائط.

الهروب RGBland:اختيار الألوان في الرسومات الإحصائية - تقني تقرير عام يصف مجموعة من خوارزميات توليد جيدة (أيالحد الأقصى مميزة) اللون في مجموعات hcl الفضاء اللوني.

هنا بعض التعليمات البرمجية لتخصيص الألوان RGB بالتساوي في جميع أنحاء الأعرج عجلة الألوان من معان محددة.

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

أليس كذلك أيضا وهو عامل أجل إعداد الألوان ؟

مثل إذا كنت تستخدم Dillie-Os فكرة تحتاج إلى مزيج الألوان قدر الإمكان.0 64 128 256 هو من واحد إلى التالي.ولكن 0 256 64 128 في عجلة من شأنه أن يكون أكثر "بصرف النظر"

فهل يعقل هذا ؟

لقد قرأت في مكان ما العين البشرية لا تستطيع التمييز بين أقل من 4 القيم على حدة.لذلك هذا هو شيء أن نأخذ في الاعتبار.الخوارزمية التالية لا تعوض عن هذا.

أنا متأكد من أن هذا هو بالضبط ما تريد, ولكن هذا هو واحد طريقة تولد عشوائيا غير تكرار قيم الألوان:

(حذار متناسقة الزائفة رمز قدما)

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

طريقة واحدة يمكنك تحسين هذا من أجل رؤية أفضل مقارنة المسافة بين كل لون و كل الألوان في مجموعة:

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

ولكن هذا النهج سوف يتباطأ بشكل كبير خوارزمية الخاص بك.

سيكون هناك طريقة أخرى الخردة العشوائية ومنهجية تذهب من خلال كل 4 القيم و إضافة اللون إلى مجموعة في المثال أعلاه.

أعرف أن هذا البريد القديم ولكن وجدت أنه في حين تبحث عن PHP حل الموضوع وأخيرا جاء مع الحل بسيط:

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

حتى مجرد الاتصال random_color() وظيفة حيث $i يحدد اللون ، $n عدد ممكن من الألوان ، $جلس تشبع $br السطوع.

لتحقيق "معظم مميز" نحن بحاجة إلى استخدام الإدراك الحسي لون الفضاء مثل مختبر (أو أي الأخرى إدراكيا الخطية لون الفضاء) وليس RGB.أيضا, يمكننا أن ثبت هذا الفضاء لتقليل حجم من الفضاء.

توليد كامل 3D الفضاء مع كل ما يمكن من الكم إدخالات تشغيل K-يعني الخوارزمية مع k=N.مما أدى مراكز/ "تعني" يجب أن يكون حوالي معظم distinguishabl من بعضها البعض.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top