Rengi arka plandan daha az benzer yapmak için renk değiştiren algoritma


23

Düz bir renk ile dolu bir arka plan ile, birbirlerini zıplayan 20 top bir demo oluşturuyorum. Her top için renk, her randint(0, 255)R, G, B tuple bileşeni için rastgele seçilir .

Sorun, bazı topların arka plana çok benzeyen ve görmelerini zorlaştıran bir renkle sonuçlanmasıdır. Seçilen renk çok benzer ise (belirli bir eşik içinde) başka bir rengi yuvarlayarak veya arka plan renginden uzağa taşıyarak bunu önlemek isterim .

Eşik olarak kullanmak için benzerlik endeksi nasıl hesaplanır ? Ya da daha az mavi-ish demek için bir rengi nasıl dönüştürürsünüz ?

Açıkça sorumluluk reddi: Renk teorisi hakkında hiçbir şey bilmiyorum, bu yüzden yukarıdaki kavramların var olup olmadığını bilmiyorum!

Python kodluyorum, ancak kavram ve stratejiler arıyorum, bu yüzden sözde kod iyi (ya da sadece teori).

DÜZENLE:

Birkaç noktayı netleştirmek için:

  • Her topun kendi rastgele rengi vardır. Mümkün olduğunca rastgele kalmalarını ve renk uzayını mümkün olduğunca keşfetmelerini istiyorum (RGB veya HSV olsun, pygamerengi tanımlamak için her iki formatı da kabul eder)

  • Her bir rengin arka plana "çok yakın" olmasından kaçınmak istiyorum. Sorun sadece renk tonu değil: Koyu mavi bir arka plana karşı açık mavi bir topla (ya da "beyaz-mavi" maviya karşı "tam mavi") tamamen mükemmelim.

  • Şimdilik, bir topun başka bir topla aynı renkte (veya aynı bile) olması durumunda umurumda değil. Bunu önlemek bir bonus, ama bu küçük bir sorun.

  • Arka plan rengi sabit, tek bir RGB renktir. Şimdilik "temel" maviyi kullanıyorum (0, 0, 255), ancak buna razı değilim. Bu nedenle, arka planı isteğe bağlı bir renk olarak düşünün (keyfi renk tonu, parlaklık, doygunluk vb.).

EDIT2:

TL, DR sürümü: Sadece rastgele (ancak tek ve sabit) bir renk arka planına karşı "çok fazla kaybolmaz" diye X rastgele renk oluşturmanın bir yolunu verin



1
Neden sadece her topun çevresine bir taslak koymadınız?
ashes999

1
Öyleyse, anahat rengini hem arka plandan hem de top renginden farklı bir renkle yapmakta bir sorun olabilir;)
Kromster

1
@AlexM .: "keyfi bir
tondan

1
@MestreLion sadece taslak için siyah kullanır ve minimum RGB değeri 128 olan renkler oluşturur.
ashes999

Yanıtlar:


33

Renklerin (üç boyutlu) bir renk uzayı oluşturması ve bu renk uzayda bir mesafe hesaplaması gerçeğini kullanabilirsiniz. Daha sonra iki renk arasındaki mesafeyi bulmak için bu renk uzayında bir metrik tanımlamanız gerekir.

Öklid uzayda iki nokta arasındaki mesafe x = (x1, x2, x3) ve y = (y1, y2, y3) arasındaki mesafe d (x, y) = sqrt ((y1-x1) * (y1- ile verilmiştir. x1) + (y2-x2) * (y2-x2) + (y3-x3) * (y3-x3)).

Artık bir top rengiyle arka plan renginiz arasındaki mesafeyi hesaplayabilirsiniz ve çok küçükse, yeni bir rasgele renk oluşturun ve tekrar test edin.

Ne RGB ne de HSV'nin bu görev için iyi renk alanları olmadığını göreceksiniz. Renk farkı Ara madde kullanan L bir b renk alanı ve mümkün olan muhtelif ölçümlerini vermektedir.

Ayrıca konuyla ilgili stackoverflow üzerinde bir diskussion da var .


Bu çok hoş bir yaklaşım, bunu yapabilirim :) Teşekkürler! Ayrıca, yeterli bir "minimum mesafe" eşiğinin nasıl bulunacağına biraz daha dikkat etmek ister misiniz? RGB yeterli değilse, L a b nasıl dönüştürülür ? Doğru algı ölçütleri için çalışmıyorum, bu nedenle "yeterince iyi" varsayılanlar yapacaktır.
MestreLion

1
Bu cevabı sev, iyi düşünülmüş, gerekli denklemleri ve referansları sağlarken işin nasıl yapılacağının iyi bir açıklaması. İyi ilk cevap.
Tom 'Blue' Piddock

1
İnsan algısının "yeterince iyi" bir yaklaşımını arıyorsanız , RGB'den doğrudan bir dönüşüme sahip olan YUV renk uzayına bakmak isteyebilirsiniz .
trm

5
Biraz zaman kazanın ve karekök alma (pahalı). Sadece kareye kıyasla minimum renk mesafesi değerini yapın.
Chris Cudmore

1
@MestreLion Ö, bir renk alanı iki renk arasında algılanan mesafe renk uzaydaki gerçek mesafe ile aynıdır, yani algısal olarak homojen olduğu keşfedilmiştir *, b. RGB renkleri cihaza bağlı olduğundan, Lab ve RGB arasında doğrudan dönüştürme yapamazsınız. Ancak, belirli bir mutlak RGB renk alanı kullanıyorsanız, bunları dönüştürebilirsiniz. Bu makaleye bakın: en.wikipedia.org/wiki/SRGB_color_space ve bu makale: en.wikipedia.org/wiki/Lab_color_space
jwir3

8

Birleşmiş Milletler web erişilebilirlik standartları sayfası ( http://www.un.org/webaccessibility/1_visual/13_colourcontrast.shtml ), bazı kullanıcıların renk körü olduğunu göz önünde bulundurarak, web sitelerinde düzgün metin kontrastı sağlamak için bir standart olduğunu gösterir . Bu, sizin için özellikle önemli olabilir, çünkü bazı kullanıcılarınız da renk körü olabilir (aynı parlaklığa sahiplerse yeşil bir arka plandan kırmızı bir topu söylemek zor olacaktır).

Birleşmiş Milletler sayfası , arka plandaki metni belirtenler dışında 4.5: 1 olan kontrast oranına sahip olması gerektiğini belirten ( http://juicystudio.com/services/luminositycontrastratio.php#specify ) adresindeki Juicy Studios Parlaklık Renk Kontrast Oranı Analizörüne işaret ediyor davanıza benzer olduğuna inanıyorum:

  • Büyük Metin: Büyük ölçekli metin ve büyük ölçekli metinlerin görüntüleri en az 3: 1 kontrast oranına sahip

Şimdi kontrast oranı nedir? Köprülerden sonra (bu eğlenceli!) Kontrast oranını şu şekilde tanımlayan bir W3 sayfasına ulaşıyoruz:

Contrast Ratio = (L1 + 0.05)/(L2 + 0.05)

L1 ve L2'nin renklerin göreceli aydınlıkları olduğu yerlerde. L1 daha aydınlatıcı renk, L2 daha az aydınlatıcı renktir. Yine, W3 sayfasının bağlantısını belirten aynı bağlantıyı takip ediyoruz:

L = 0.2126 * R + 0.7152 * G + 0.0722 * B where R, G and B are defined as:

if RsRGB <= 0.03928 then R = RsRGB/12.92 else R = ((RsRGB+0.055)/1.055) ^ 2.4
if GsRGB <= 0.03928 then G = GsRGB/12.92 else G = ((GsRGB+0.055)/1.055) ^ 2.4
if BsRGB <= 0.03928 then B = BsRGB/12.92 else B = ((BsRGB+0.055)/1.055) ^ 2.4
and RsRGB, GsRGB, and BsRGB are defined as:

RsRGB = R8bit/255
GsRGB = G8bit/255
BsRGB = B8bit/255

NOT : Yukarıdaki şapka simgesi ^ üstelleştirmeyi (x²) belirtir.

Bir kontrast algoritması için oldukça iyi bir çerçeveye sahibiz (bu renk körü dostu!)

  • Her renk için R, G, B değerlerini belirle
  • Her renk için parlaklık belirleme
  • Daha aydınlık olan rengin Kontrast Oranı en az aydınlık rengine 3 ise, yeniden!

2
^ Üstel olması gerekiyordu unutmayın. Bizim için deli C benzeri kullanıcılar xor anlamına gelir (Ben gerçekten bir dakika boyunca kayan nokta değerleri üzerinde bitsel bir işlem yapmaya çalıştığınızı düşündüm).
Pharap

Bu inanılmaz bir yaklaşım, hoşuma gitti! :)
MestreLion,

Ve endişelenme ^, bu bağlamda asla bitsel bir XOR düşünmeyeceğim. . (veya herhangi aslında C'mon C phreaks içinde, ^çok az dilleri aslında kullanmak her ne kadar öyle python ... (sözde kodları üs için fiili simbol olan **)
MestreLion

1
Sadece yazım hatalarını düzeltiyorum. Ayrıca, bir kişi ^ ile ilgili sorun yaşarsa, gelecekte de başkalarının şansı olabilir. Belirli olmaktan zarar gelmez.
John,

1
Endişeye gerek yok. Kargaşanın nereden kaynaklandığından emin değilim (yani hangi dili önce kullandı ^). VB ile olan deneyimim nedeniyle bazen üstelleştirme için kullanıldığını biliyorum ^ (üstelleştirme olarak kullanan diğer dilleri bilmiyorum, ancak muhtemelen bazıları var). Yine de bir heads-up olarak, bu havuç sembolü değil, şapka sembolüdür. Birileri tanrıya sebzelerle programlama konusunda korkunç şaka yapmadan önce bunu değiştirmek isteyebilir (özellikle kare kökleri içeren).
Pharap

2

Rastgele üreterek RGB değerlerini kullanma 0-255sadece arka plana benzer renkler oluşturmak olmayabilir her bileşen için değer, ayrıca topları için çok benzer renkler ile sona erebilir.

Muhtemelen daha az rastgele bir yaklaşım seçer ve bunun yerine farklı olduğu garantili renkler oluştururdum. Ton aralığında her ~ 32 derece için bir renk oluşturabilir ve parlaklığı veya doygunluğu değiştirebilirsiniz (RGB yerine HSV renk modelini kullanın).

Yani böyle bir şey:

numColors = 20;
stepSize = 360 / (numColors / 2 + 1); // hue step size
for(i = 0; i < numColors; i++){
    color = HSV(i / 2 * stepSize, 0.5 + (i % 2) * 0.5, 1.0) 
}

güzel dağıtılmış 20 renk yaratacaktır. Bu tamsayı matematik kullanıyoruz, böylece varsayar i = 0ve i = 1aynı renk değerini oluşturur.

Tabii ki bu çok iyi ölçeklenemez. Eğer yaratılacak 100 renk değerine sahipseniz, renk aralığı yeterli olmayabilir ve yine benzer renklerle sonuçlanırsınız. Bu durumda V(parlaklık) değerini de değiştirebilirsiniz .

Arka plan renginizin nasıl olduğunu bilmiyorum, ancak HSV renkleri karşılaştırmayı da kolaylaştırıyor (yalnızca 3 bileşeni karşılaştırın ve HUE'nin dairesel olduğunu unutmayın (0 == 360)).

GÜNCELLEŞTİRME:

Sorunuza gerçekten cevap veremediğimden ama başka bir yaklaşım sunduğum için, keyfi bir arka plan ve tamamen rastgele renkli toplar için bir algoritma nasıl görünebilir (bu bir kaba kuvvet yaklaşımıdır ancak kullanım durumunuz için iyi çalışmalıdır):

// background color, currently equals RGB(0, 0, 255)
bg = HSV(240, 1.0, 1.0)

// number of colors to create is equal to the amount of balls
numColors = balls.length

// set threshold to compare colors. you can tweak this to your liking
threshold = 0.15

for(i = 0; i < numColors; i++){
    do {
        // assuming rnd returns a random float 0-1 inclusive
        color = HSV(rnd() * 360, rnd(), rnd())
        // calculate delta values, normalize hue to 0-1
        dH = (180 - abs(abs(bg.h - color.h) - 180)) / 360
        dS = bg.s - color.s
        dV = bg.v - color.v
        // "distance" between bg and color
        difference = sqrt(dH * dH + dS * dS + dV * dV)
    } while(difference < threshold)

    ball[i].color = color
}

Algoritmanız hakkında, arka plan rengini nasıl dikkate alıyor?
MestreLion

Şu anda arka plan rengini hesaba katmıyor ... oluşturulan renkleri karşılaştırarak (son paragrafta anlatıldığı gibi) ince ayar yapabilir ve daha sonra farklı bir renk oluşturabilirsiniz V(mevcut algoritma bunu değiştirmez).
Bummzack

@MestreLion Alternatif bir algoritma içeren bir güncelleme
ekledim

Harika, bu iyi bir strateji gibi görünüyor. Kaba kuvvet tamam, renkler oyun sırasında değil, başlangıçta yalnızca bir kez üretilir. HSV'de düz öklid mesafesi olan René ile aynı yaklaşımı kullandığınız görülüyor mu? HSV için uygun bir eşik referansı var mı? H, S ve V, RGB'deki gibi aynı ağırlıkta mı?
MestreLion

@MestreLion Evet, ikinci algoritmam, René'nin cevabında anlattığı şey. Ne yazık ki, renk değişimleri eşit şekilde algılanmadığından iyi bir eşik için kesin bir değer yoktur. Yeşildeki değişiklikleri maviden çok daha hızlı olarak tanıyoruz ... bu nedenle yeşil tonlar için daha küçük bir eşik işe yarayabilir ancak diğer renkler için yeterli olmayacaktır. HSV renk boşluğu ile istenen sonuçları almazsanız en uygun olabilir.
Bummzack

1

Diyelim ki, sabit bir arka plana sahip olduğunuzdan, topların rengi hala rastgele olabilir ama yine de arka planı tamamlayan belli aralıklara düşmeleri gerekir.

Temelleri. Bunu yapmadan önce temellerini bilmek gerekir. Aşağıdaki renkleri göz önünde bulundurun:

Black   #000000 rgb(0,0,0)
Red     #FF0000 rgb(255,0,0)
Green   #00FF00 rgb(0,255,0)
Blue    #0000FF rgb(0,0,255)
Yellow  #FFFF00 rgb(255,255,0)
Cyan    #00FFFF rgb(0,255,255)
Pink    #FF00FF rgb(255,0,255)
Gray    #C0C0C0 rgb(192,192,192)
White   #FFFFFF rgb(255,255,255)

Renklerin Karışımı RGB [(0..255), (0..255), (0..255)] yukarıdaki gibi yeni renkler oluşturur.

Negatif Renklerin Hesaplanması Negatif renklerin hesaplanması tıpkı siyanede kırmızı, morda yeşil, sarıda mavi dönüşümü gibidir.

Red     #FF0000 rgb(255,0,0) ->     Cyan    #00FFFF rgb(0,255,255)
Green   #00FF00 rgb(0,255,0) ->     Purple   #FF00FF    rgb(255,0,255)
Blue    #0000FF rgb(0,0,255) ->     Yellow  #FFFF00 rgb(255,255,0)

Tamamlayıcı renk

Bilgisayardaki tamamlayıcı renkler referansına göre: http://serennu.com/colour/rgbtohsl.php

HSL hakkında

HSL, renkleri Ton, Doygunluk ve Açıklık cinsinden ifade eder ve rengin bu üç özelliği için bir sayı verir.

Renk tonu, rengin 360 ° 'yi temsil eden renk tekerleğindeki 0 ° ile 359 ° derece arasında ifade edilen pozisyonudur; 0 ° kırmızı, 180 ° kırmızı zıt renk camgöbeği vb.

Doygunluk, rengin yoğunluğu, ne kadar mat veya parlak olduğu. Doygunluk azaldıkça, dolgu rengi (daha gri) renk görünür. Bu yüzde olarak ifade edilir,% 100 doygunluk, en parlak ve% 0 doygunluk yok, gri.

Hafiflik, rengin ne kadar hafif olduğu. Doygunluktan biraz farklı. Renk ne kadar beyaz olursa Açıklık değeri o kadar yüksek, açıklık o kadar siyah olur. Böylece% 100 Hafiflik rengi beyaza çevirir,% 0 Hafiflik rengi siyaha çevirir ve "saf" renk% 50 Hafiflik olur.

Doygunluk ve Hafiflik arasındaki farkı görmek açıklamaktan daha kolaydır. Netleştirmek istiyorsanız, renk hesaplayıcı sayfasındaki Açıklık ve Doygunluk çeşitlemelerini görüntülemeyi deneyin, başlangıç ​​renginiz olarak oldukça parlak bir renk seçin.

HSL notasyonu şöyle görünür, Hue, Saturation ve Lightness değerlerini bu sıraya göre verir: t

Kırmızı: 0 ° 100% 50% Soluk pembe: 0 ° 100%% 90 Mavi: 180 ° 100% 50% İşte Adımlar:

  1. Renginizi HSL'ye dönüştürün.

  2. Ton değerini, karşısındaki Ton ile değiştirin (örneğin, Tonunuz 50 ° ise, bunun tersi tekerlek üzerinde 230 ° olacaktır - yaklaşık 180 ° daha ileride).

  3. Doygunluk ve Hafiflik değerlerini olduğu gibi bırakın.

  4. Bu yeni HSL değerini tekrar orijinal renk notasyonunuza (RGB veya her neyse) dönüştürün.

EasyRGB.com gibi siteler sizin için RGB'den HSL'ye veya bunun tersi yönde genel dönüşüm yapabilir.

PHP'ye referans olarak yapılan programlama örneği

RGB’den HSL’ye dönüşüm

Mavi # 0000FF rgb (0,0,255) üstündeki değer Kırmızı Onaltılık 00 + Yeşil Onaltılık 00 + Mavi Onaltılık FF olarak sunulabilir

$redhex  = substr($hexcode,0,2);
$greenhex = substr($hexcode,2,2);
$bluehex = substr($hexcode,4,2);

Ayrıca Kırmızı Ondalık 0 + Yeşil Ondalık 0 + Mavi Ondalık 255 olarak da sunulabilir.

$var_r = (hexdec($redhex)) / 255;
$var_g = (hexdec($greenhex)) / 255;
$var_b = (hexdec($bluehex)) / 255;

Şimdi bu değerleri rgb2hsl yordamına takın. Aşağıda, bu dönüşüm için EasyRGB.com’un genel kodunun PHP versiyonu:

Girdi $ var_r, $ var_g ve yukarıdan $ var_b. Çıktı HSL'nin $ h, $ s ve $ l ile eşdeğeridir - bunlar yine girdi değerleri gibi 1'in kesirleri olarak ifade edilir.

$var_min = min($var_r,$var_g,$var_b);ttt
$var_max = max($var_r,$var_g,$var_b);
$del_max = $var_max - $var_min;

$l = ($var_max + $var_min) / 2;

if ($del_max == 0)
{
        $h = 0;
        $s = 0;
}
else
{
        if ($l < 0.5)
        {
                $s = $del_max / ($var_max + $var_min);
        }
        else
        {
                $s = $del_max / (2 - $var_max - $var_min);
        };

        $del_r = ((($var_max - $var_r) / 6) + ($del_max / 2)) / $del_max;
        $del_g = ((($var_max - $var_g) / 6) + ($del_max / 2)) / $del_max;
        $del_b = ((($var_max - $var_b) / 6) + ($del_max / 2)) / $del_max;

        if ($var_r == $var_max)
        {
                $h = $del_b - $del_g;
        }
        elseif ($var_g == $var_max)
        {
                $h = (1 / 3) + $del_r - $del_b;
        }
        elseif ($var_b == $var_max)
        {
                $h = (2 / 3) + $del_g - $del_r;
        };

        if ($h < 0)
        {
                $h += 1;
        };

        if ($h > 1)
        {
                $h -= 1;
        };
};

Şimdi bir hsl değeri olarak renge sahibiz, $ h, $ s ve $ l değişkenlerinde. Bu üç çıktı değişkeni, derece ve yüzde olarak değil, yine bu aşamada 1'in kesirleri olarak tutulur. Örneğin, camgöbeği (180 °% 100% 50), $ h = 0.5, $ s = 1 ve $ l = 0.5 olarak ortaya çıkacaktır.

Daha sonra karşıt Ton'un değerini, yani 180 ° veya 0,5 uzakta olanı bulun (matematikçilerin bunu daha zarif bir şekilde ifade etmenin bir yolu olduğuna eminim ama):

Karşıt tonu hesapla, $ h2

            $h2 = $h + 0.5;

            if ($h2 > 1)
                    {
                            $h2 -= 1;
                    };

Tamamlayıcı rengin HSL değeri şimdi $ h2, $ s, $ l cinsindendir. Bu yüzden bunu tekrar RGB'ye dönüştürmeye hazırız (yine, EasyRGB.com formülünün PHP sürümüm). Giriş ve çıkış biçimlerinin bu sefer farklı olduğuna dikkat edin, yorumlarımın kodun üst kısmına bakın:

Giriş, tamamlayıcı rengin HSL değeridir, $ h2, $ s, $ l değerinde 1 l'lik kesirler olarak tutulur. Çıktı normal RGB 255 255 255 biçiminde, $ r, $ g değerinde tutulur, $ b Hue, gösterilen hue_2_rgb işlevi kullanılarak dönüştürülür bu kodun sonunda

    if ($s == 0)
    {
            $r = $l * 255;
            $g = $l * 255;
            $b = $l * 255;
    }
    else
    {
            if ($l < 0.5)
            {
                    $var_2 = $l * (1 + $s);
            }
            elset
            {
                    $var_2 = ($l + $s) - ($s * $l);
            };

            $var_1 = 2 * $l - $var_2;
            $r = 255 * hue_2_rgb($var_1,$var_2,$h2 + (1 / 3));
            $g = 255 * hue_2_rgb($var_1,$var_2,$h2);
            $b = 255 * hue_2_rgb($var_1,$var_2,$h2 - (1 / 3));
    };

   // Function to convert hue to RGB, called from above

    function hue_2_rgb($v1,$v2,$vh)
    {
            if ($vh < 0)
            {
                    $vh += 1;
            };

            if ($vh > 1)
            {
                    $vh -= 1;
            };

            if ((6 * $vh) < 1)
            {
                    return ($v1 + ($v2 - $v1) * 6 * $vh);
            };

            if ((2 * $vh) < 1)
            {
                    return ($v2);
            };

            if ((3 * $vh) < 2)
            {
                    return ($v1 + ($v2 - $v1) * ((2 / 3 - $vh) * 6));
            };

            return ($v1);
    };

Ve bu rutinden sonra, 255 255 255 (RGB) biçiminde nihayet $ r, $ g ve $ b değerine sahibiz;

    $rhex = sprintf("%02X",round($r));
    $ghex = sprintf("%02X",round($g));
    $bhex = sprintf("%02X",round($b));

    $rgbhex = $rhex.$ghex.$bhex;

$ rgbhex bizim cevabımız - hex'deki tamamlayıcı renk.

Renkli arka planınız mavi veya 0,0255 olduğundan HSL

Ton (H): 240 derece / Doygunluk (S):% 100 / Hafiflik (L):% 4,9

240'ın karşısı bir dairede 60'tır, daha sonra geri RGB'ye dönüştürür # 181800


Teşekkürler! Ancak bağlantı, kendisinden "tamamlayıcı bir renk" (her ne olursa olsun) üretmekten bahsediyor . Sorunu çözmek için nasıl kullanılacağı konusunda hala ipucu yok: Her rastgele rengin arka plan rengiyle aynı olmadığından emin olun. Arka plan rengi sabittir, tek renk ve çok sayıda top var.
MestreLion

Teşekkürler Krom bunu şimdi yapıyor. @MestreLion, arka plan sabit olduğundan, arka planınızı hala tamamlayan toplarınız için bir aralık belirleyebilirsiniz.
Ace Caserya

Şu anda cevabımı ifşa ediyor.
Ace Caserya

Bitti. Sitelerde açıklamalarda fazla değişiklik yapacak şeyleri yapmıyorum, çünkü yeterince açıklandı. EasyRGB.com'daki adamlara verilen krediler
Ace Caserya


1

@ Ashes999'un bir taslak oluşturma fikri üzerine genişletmek istiyorum.

Kodum başımın üstünden çıkarabildiğim kadar python gibi olacak (Hayatımda hiçbir zaman bir python satırı yazmadım, ama bir ya da iki kez bir kitap üzerine baktım).

def lerp(a,b,value): # assuming your library was not kind enough to give you this for free
    return a + ((b - a) * value);

def drawRandomBall(bgColour,radius,point):
    var ballColour = Colour(random(0,255),random(0,255),random(0,255);
    var outlineColour = Colour(lerp(bgColour.R,255 - ballColour.R,0.5),lerp(bgColour.G,255 - ballColour.G,0.5),lerp(bgColour.B,255 - ballColour.B,0.5));
    fillCircle(point,radius+1,outlineColour);
    fillCircle(point,radius,ballColour);

Özellikle hoş görünmeyebilir ve üretim kodu için gerçekten ideal değildir, ancak hızlı bir düzeltme için yeterli olmalıdır. Kodu tam olarak test etmedim, çünkü test etmek için susturabileceğim bir "ekran etrafında zıplayan toplar" programım olmadı.


Düzenle:

Kullanımdaki gerçek kodu görünce, durum tersine döndü, bu yüzden bunun yerine bu çözümü öneriyorum.

276-284 numaralı çizgileri aşağıdakilerle değiştirin:

# Colour generator
def generateColourNonBG(leeway):
    color = (randint(0,255), randint(0,255), randint(0,255))
    while color[0] >= BG_COLOR[0]-leeway and color[0] =< BG_COLOR[0] + leeway and
    color[1] >= BG_COLOR[1]-leeway and color[1] =< BG_COLOR[1] + leeway and
    color[2] >= BG_COLOR[2]-leeway and color[2] =< BG_COLOR[2] + leeway:
        color = (randint(0,255), randint(0,255), randint(0,255))

# Ball generator
def generateBall():
    Ball(generateColourNonBG(5),
                   radius=randint(10, radius),
                   position=[randint(100, screen.get_size()[0]-radius),
                             randint(100, screen.get_size()[0]-radius)],
                   velocity=[randint(50, 50+vel[0]), randint(50, 50+vel[1])],
                   )                       

# Create the balls
balls = pygame.sprite.Group()
for _ in xrange(BALLS):
    balls.add(generateBall())

Bu yeni sadeleştirilmiş versiyonda, bir fabrika metodu topları dağıtıyor ve özel bir metot renkleri üretiyor. Renk üreteci, arka plan rengine belirli bir yakınlık aralığında olup olmadığını görmek için rastgele oluşturulan rengi test eder. Renk kanallarının üçü leewayde BG'nin iki tarafındaysa, renk, BG rengine çok yakın olarak kabul edilir . Öyleyse leeway 0 ise, yalnızca BG ile tam olarak eşleşen renkler reddedilir. BG rengini ve her iki taraftaki 5 rengi reddeden varsayılanı 5 seçtim. BG rengi beyaz olduğu için, rakamlar sarılandığından siyahın reddedileceğinden emin değilim. Min ve max fonksiyonlarının kullanılmasıyla bu önlenebilir, ancak onları kısayk için dışarıda bıraktım.


Herhangi bir stratejiye açığım :), bir programın sesini kesmesine gelince , size şunu söyleyebilirim : github.com/MestreLion/rainballs ilgili satırlar 279-284
MestreLion 07.07

pygameKütüphane olarak kullanıyorum . Lerp yok, sadece temel RGB-HSV-CYMK dönüşümleri: pygame.org/docs/ref/color.html
MestreLion

@MestreLion Oh tanrım, şimdi test etmek için pygame ve python kullanmam gerekiyor. Bu tek XP ile kendimi ayağımdan vurdum. Lerping kolaydır, cevabımdaki lerpişlev, hepsi bu. (Lerp 'Doğrusal enterpolasyon' anlamına gelir).
Pharap

@MestreLion Bir parça kıpır kıpır, python sürümümün parantez olmadan yazdırılmasından hoşlanmadığı ortaya çıktı. Bunu düzelttim, fakat şimdi pygame'den doğru kütüphaneleri bulamadığım için hatalar var. Kodumu sahip olduklarınıza uyacak şekilde yeniden yazacağım, ancak pygame'i çözene kadar test edemiyorum. Henüz yapmadıysanız, bu dosyayı soruya eklemenizi tavsiye ederim (eğer biri sizin için biraz piton yazmak için yeterince iyi hissediyorsa).
Pharap

Siz printfarklısınız çünkü Python 3 kullanıyorsunuz ve ben hala Python pygame2'deyim. Ve henüz Py3'e taşındığından emin değilim . Bottomline:
Rahatsız

1

Bir RGB formatı için, bu yeterince iyi çalışıyor gibi görünüyor ve önemsiz:

çeşitlilik_score = (abs (r1 - r2) + abs (g1 - g2) + abs (b1 - b2)) / 765.0

Bu size 0.0 ile 1.0 arasında bir puan verecektir. Ne kadar düşük olursa, iki rengi ayırt etmek zorlaşır.

Açık olması gerekir, ancak eksiksiz olması için: r, g, b değerlerinin önce bir kayan nokta sayısına atılması gerekir ve maksimum değerlerinin 255 olduğu varsayılır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.