Algorithmus zum Ändern einer Farbe, um sie weniger ähnlich als den Hintergrund zu machen


23

Ich erstelle eine Demo von 20 Bällen, die sich gegenseitig aufprallen und einen einfarbigen Hintergrund haben. Die Farbe für jede Kugel wird zufällig randint(0, 255)für jede Tupelkomponente R, G, B ausgewählt.

Das Problem ist, dass einige Bälle am Ende eine Farbe haben, die dem Hintergrund sehr ähnlich ist, wodurch sie schwer zu erkennen sind. Ich möchte das vermeiden, indem ich entweder eine andere Farbe rolle, wenn die gewählte zu ähnlich ist (innerhalb eines bestimmten Schwellenwerts), oder indem ich sie von der Hintergrundfarbe entferne .

Wie berechnet man einen Ähnlichkeitsindex , der als Schwellenwert verwendet wird? Oder wie man eine Farbe transformiert, um sie beispielsweise weniger bläulich zu machen ?

Offensichtlicher Haftungsausschluss: Ich weiß nichts über Farbtheorie, daher weiß ich nicht, ob die obigen Konzepte überhaupt existieren!

Ich programmiere in Python, aber ich suche nach Konzepten und Strategien, also ist Pseudocode in Ordnung (oder nur die Theorie).

BEARBEITEN:

Um einige Punkte zu verdeutlichen:

  • Jeder Ball hat seine eigene zufällige Farbe. Ich möchte, dass sie so zufällig wie möglich bleiben und so viel wie möglich vom Farbraum ablesen (sei es RGB oder HSV, pygameakzeptiert beide Formate für die Farbdefinition).

  • Ich möchte nur vermeiden, dass jede Farbe dem Hintergrund zu nahe kommt. Problem ist nicht nur Farbton: Ich bin vollkommen in Ordnung mit einem hellblauen Ball vor einem dunkelblauen Hintergrund (oder einem "vollblauen" vor einem "weißlichen" Blau usw.)

  • Im Moment ist es mir egal, ob ein Ball eine ähnliche (oder sogar identische) Farbe wie ein anderer Ball hat. Das zu vermeiden ist ein Bonus, aber ein kleines Problem.

  • Die Hintergrundfarbe ist eine konstante einzelne RGB-Farbe. Im Moment benutze ich "Basic" Blau (0, 0, 255), aber damit bin ich nicht einverstanden. Betrachten Sie den Hintergrund daher als eine beliebige Farbe (mit einem beliebigen Farbton, einer beliebigen Helligkeit, einer beliebigen Sättigung usw.).

EDIT2:

TL, DR-Version: Geben Sie einfach die Möglichkeit, X zufällige Farben zu erstellen, sodass keine vor dem Hintergrund einer beliebigen (aber einfachen und konstanten) Farbe "zu stark einblendet"



1
Warum nicht einfach einen Umriss um jede Kugel legen?
Asche999

1
Dann könnte es ein Problem geben, eine
Umrissfarbe

1
@ AlexM .: Kaum zu glauben, dass es keine einfache Lösung gibt, um "zufällige Farben zu erzeugen, die keine willkürlichen Farben enthalten"
MestreLion

1
@MestreLion verwendet nur Schwarz als Umriss und generiert Farben mit einem RGB-Mindestwert von 128. So einfach ist das.
Asche999

Antworten:


33

Sie können die Tatsache nutzen, dass Farben einen (dreidimensionalen) Farbraum bilden und einen Abstand in diesem Farbraum berechnen. In diesem Farbraum müssen Sie dann eine Metrik definieren, um den Abstand zwischen zwei Farben zu ermitteln.

ZB ist der Abstand in einem euklidischen Raum zwischen zwei Punkten x = (x1, x2, x3) und y = (y1, y2, y3) gegeben durch d (x, y) = sqrt ((y1-x1) * (y1- x1) + (y2-x2) * (y2-x2) + (y3-x3) * (y3-x3)).

Jetzt können Sie den Abstand zwischen einer Kugelfarbe und Ihrer Hintergrundfarbe berechnen und, wenn er zu klein ist, eine neue zufällige Farbe erstellen und erneut testen.

Sie werden feststellen, dass weder RGB noch HSV gute Farbräume für diese Aufgabe sind. Der Wikipedia-Artikel über Farbunterschiede verwendet die L a b -Farbraum und gibt mehrere mögliche Metriken an.

Es gibt auch eine Diskussion zum Stackoverflow zum Thema.


Das ist ein sehr schöner Ansatz, das könnte ich machen :) Danke! Überlegen Sie auch, wie Sie eine angemessene Mindestentfernungsschwelle finden können. Wenn RGB nicht ausreicht, wie konvertiere ich nach L a b? Ich bin nicht bestrebt, genaue Wahrnehmungskennzahlen zu ermitteln, daher reichen alle "gut genug" -Standards aus.
MestreLion

1
Lieben Sie diese Antwort, gut durchdacht, gute Erklärung, wie man die Aufgabe erledigt, während Sie die benötigten Gleichungen und Referenzen bereitstellen. Gute erste Antwort.
Tom 'Blue' Piddock

1
Wenn Sie eine "gute" Annäherung an die menschliche Wahrnehmung suchen, möchten Sie möglicherweise in den YUV- Farbraum blicken , der eine direkte Konvertierung von RGB aufweist.
07.08.2014

5
Sparen Sie ein bisschen Zeit und nehmen Sie nicht die Quadratwurzel (teuer). Machen Sie einfach Ihren minimalen Farbabstandswert, den Sie mit dem Quadrat vergleichen.
Chris Cudmore

1
@MestreLion Der L a b * -Farbraum wurde erfunden, um wahrnehmungsgleich zu sein, was bedeutet, dass der wahrgenommene Abstand zwischen zwei Farben dem tatsächlichen Abstand im Farbraum entspricht. Da RGB-Farben geräteabhängig sind, können Sie nicht direkt zwischen Lab und RGB konvertieren. Wenn Sie jedoch einen bestimmten absoluten RGB-Farbraum verwenden, können Sie diese konvertieren. Siehe diesen Artikel: en.wikipedia.org/wiki/SRGB_color_space und diesen Artikel: en.wikipedia.org/wiki/Lab_color_space
jwir3

8

Die Website der Vereinten Nationen ( http://www.un.org/webaccessibility/1_visual/13_colourcontrast.shtml ) enthält einen Standard zur Gewährleistung eines korrekten Texts auf Websites, wobei zu berücksichtigen ist, dass einige Benutzer farbenblind sind. Dies könnte für Sie besonders wichtig sein, da einige Ihrer Benutzer möglicherweise auch farbenblind sind (es wäre schwierig, eine rote Kugel von einem grünen Hintergrund zu unterscheiden, wenn sie dieselbe Leuchtdichte haben).

Die UN-Seite verweist auf den Juicy Studios Luminosity Color Contrast Ratio Analyzer unter ( http://juicystudio.com/services/luminositycontrastratio.php#specify ), in dem angegeben ist, dass der Hintergrundtext ein Kontrastverhältnis von 4,5: 1 haben muss, außer ich glaube, deinem Fall ähnlich zu sein:

  • Großer Text: Großer Text und Bilder mit großem Text haben ein Kontrastverhältnis von mindestens 3: 1

Was ist nun ein Kontrastverhältnis? Wenn wir weiter Hyperlinks folgen (das macht Spaß!), Gelangen wir zu einer W3-Seite, die das Kontrastverhältnis wie folgt definiert:

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

Wobei L1 und L2 die relativen Luminenzen der Farben sind. L1 ist die mehr luminant Farbe, L2 die weniger luminant Farbe. Wir folgen erneut dem Link zu derselben W3-Seite, auf der Folgendes angegeben ist:

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

HINWEIS : Das Caret-Symbol ^ oben bezieht sich auf die Potenzierung (x²)

Und wir haben ein ziemlich gutes Framework für einen Kontrastalgorithmus (das ist farbenblind!)

  • Bestimmen Sie die R-, G- und B-Werte für jede Farbe
  • Bestimmen Sie die Leuchtdichte für jede Farbe
  • Wenn das Kontrastverhältnis der leuchtstärkeren Farbe zur niedrigsten leuchtstärkeren Farbe weniger als 3 beträgt, wiederholen Sie den Vorgang!

2
Vielleicht möchten Sie bemerken, dass ^ Exponentiation sein soll. Für uns verrückte C-artige Benutzer bedeutet dies xor (ich dachte wirklich, Sie wollten eine Minute lang eine bitweise Operation mit Gleitkommawerten ausführen).
Pharap

Das ist ein erstaunlicher Ansatz, ich mag es! :)
MestreLion

Und keine Sorge ^, ich würde in diesem Zusammenhang niemals über ein bitweises XOR nachdenken. (oder in irgendeinem anderen. C'mon C-Satz, ^ist das De-facto-Symbol für die Exponentiation in Pseudocodes (obwohl nur sehr wenige Sprachen es tatsächlich verwenden ... in Python ist es **)
MestreLion

1
Nur Tippfehler beheben. Plus, wenn eine Person Probleme mit dem ^ hat, besteht die Möglichkeit, dass jemand anderes dies auch in Zukunft könnte. Tut nicht weh, um genau zu sein.
John

1
@ John Keine Sorge,. Ich bin mir nicht sicher, woher die Verwirrung stammt (dh welche Sprache wurde zuerst für welchen Zweck verwendet?). Ich weiß nur, dass ^ aufgrund meiner Erfahrung mit VB manchmal für die Potenzierung verwendet wird (ich kenne keine anderen Sprachen, die es als Potenzierung verwenden, aber es gibt wahrscheinlich einige). Nur als Heads-Up ist es das Caret- Symbol, nicht das Karottensymbol . Vielleicht möchten Sie es ändern, bevor jemand einen schrecklichen Scherz über das Programmieren mit Gemüse macht (insbesondere mit Quadratwurzeln).
Pharap

2

Wenn Sie RGB-Werte verwenden, indem Sie 0-255für jede Komponente einen Zufallswert generieren, werden möglicherweise nicht nur Farben erzeugt, die dem Hintergrund ähnlich sind, sondern Sie erhalten möglicherweise auch sehr ähnliche Farben für die Kugeln.

Ich würde wahrscheinlich einen weniger zufälligen Ansatz wählen und stattdessen Farben kreieren, die garantiert unterschiedlich sind. Sie können eine Farbe für jeweils ~ 32 Grad im Farbtonbereich erstellen und die Helligkeit oder Sättigung ändern (HSV-Farbmodell anstelle von RGB verwenden).

So etwas in der Art:

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

Dadurch entstehen 20 Farben, die gut verteilt sind. Dies setzt voraus, dass Sie eine Ganzzahl-Mathematik verwendeni = 0 und i = 1erstellt den gleichen Farbtonwert.

Natürlich ist die Skalierung nicht so gut. Wenn Sie 100 Farbwerte erstellen müssen, reicht der Farbtonabstand möglicherweise nicht aus und Sie erhalten wieder ähnliche Farben. In diesem Fall können Sie auch dieV (Helligkeits-) Wert .

Ich weiß nicht, wie Ihre Hintergrundfarbe ist, aber HSV erleichtert auch das Vergleichen von Farben (vergleichen Sie einfach die 3 Komponenten und vergessen Sie nicht, dass HUE kreisförmig ist (0 == 360)).

AKTUALISIEREN:

Da ich Ihre Frage nicht wirklich beantwortet habe, sondern einen anderen Ansatz bereitgestellt habe, könnte ein Algorithmus für einen beliebigen Hintergrund und vollständig zufällige farbige Kugeln wie folgt aussehen (dies ist ein Brute-Force-Ansatz, sollte aber für Ihren Anwendungsfall gut funktionieren):

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

Wie wird bei Ihrem Algorithmus die Hintergrundfarbe berücksichtigt?
MestreLion

Momentan wird die Hintergrundfarbe nicht berücksichtigt. Sie können sie optimieren, indem Sie die generierten Farben vergleichen (wie im letzten Abschnitt beschrieben) und dann eine andere Farbe erstellen V(da dies durch den aktuellen Algorithmus nicht geändert wird).
Bummzack

@MestreLion Hinzugefügt ein Update mit einem alternativen Algorithmus
Bummzack

Großartig, das scheint eine nette Strategie zu sein. Brute Force ist in Ordnung, Farben werden nur einmal bei der Initialisierung erzeugt, nicht innerhalb der Spielschleife. Scheint, Sie verwenden denselben Ansatz wie René, mit einer einfachen euklidischen Distanz im HSV, richtig? Gibt es Hinweise auf eine geeignete Schwelle für den HSV? Haben H, S und V das gleiche Gewicht wie in RGB?
MestreLion

@MestreLion Ja, mein zweiter Algorithmus ist so ziemlich das, was René in seiner Antwort erklärt hat. Leider gibt es keinen definitiven Wert für eine gute Schwelle, da Farbänderungen nicht einheitlich wahrgenommen werden. Wir erkennen Änderungen in Grün viel schneller als in Blau. Für Grüntöne könnte eine kleinere Schwelle funktionieren, für andere Farben jedoch nicht ausreichen ist möglicherweise am besten geeignet, wenn Sie mit dem HSV-Farbraum keine wünschenswerten Ergebnisse erzielen.
Bummzack

1

Da Sie din erwähnt haben, dass Sie einen stationären Hintergrund haben, kann die Farbe der Kugeln immer noch zufällig sein, aber sie müssen in bestimmten Bereichen fallen, die den Hintergrund noch ergänzen.

Grundlagen. Bevor wir das tun, müssen Sie die Grundlagen kennen. Betrachten Sie die folgenden Farben:

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)

Farbmischung RGB [(0..255), (0..255), (0..255)] erzeugt neue Farben wie oben.

Berechnen für negative Farben Das Berechnen für negative Farben entspricht dem Umwandeln von Rot in Cyan, Grün in Lila und Blau in Gelb.

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)

Komplementärfarbe

Informationen zum Computing von Komplementärfarben finden Sie unter http://serennu.com/colour/rgbtohsl.php

Über HSL

HSL drückt Farben in Bezug auf Farbton, Sättigung und Helligkeit aus und gibt für jedes dieser drei Farbattribute eine Zahl an.

Der Farbton ist die Position der Farbe auf dem Farbkreis, ausgedrückt in Grad von 0 ° bis 359 °, was die 360 ​​° des Kreises darstellt. 0 ° ist rot, 180 ° ist die gegenüberliegende Farbe von Rot, Cyan und so weiter.

Die Sättigung ist die Intensität der Farbe, wie langweilig oder hell sie ist. Je niedriger die Sättigung, desto trüber (grauer) wirkt die Farbe. Dies wird als Prozentsatz ausgedrückt, wobei 100% die vollständige Sättigung, der hellste Wert und 0% keine Sättigung, grau sind.

Helligkeit ist, wie hell die Farbe ist. Etwas anders als die Sättigung. Je mehr Weiß in der Farbe enthalten ist, desto höher ist der Helligkeitswert. Je mehr Schwarz ist, desto geringer ist die Helligkeit. So wird aus 100% Helligkeit die Farbe Weiß, aus 0% Helligkeit die Farbe Schwarz, und die "reine" Farbe wäre 50% Helligkeit.

Es ist einfacher, den Unterschied zwischen Sättigung und Helligkeit zu erkennen, als ihn zu erklären. Wenn Sie dies klären möchten, versuchen Sie, die Helligkeits - und Sättigungsvarianten auf der Seite des Farbrechners anzuzeigen, und wählen Sie eine ziemlich helle Farbe als Startfarbe.

Die HSL-Notation sieht also so aus und gibt die Werte für Farbton, Sättigung und Helligkeit in dieser Reihenfolge an: t

Rot: 0 ° 100% 50% Hellrosa: 0 ° 100% 90% Cyan: 180 ° 100% 50% Hier sind die Schritte:

  1. Konvertieren Sie Ihre Farbe in HSL.

  2. Ändern Sie den Farbtonwert in den Wert des gegenüberliegenden Farbtons (wenn Ihr Farbton z. B. 50 ° beträgt, befindet sich der gegenüberliegende Wert auf dem Rad bei 230 ° - 180 ° weiter herum).

  3. Lassen Sie die Werte für Sättigung und Helligkeit unverändert.

  4. Konvertieren Sie diesen neuen HSL-Wert zurück in Ihre ursprüngliche Farbnotation (RGB oder was auch immer).

Websites wie EasyRGB.com können generische Konvertierungen von RGB in HSL oder umgekehrt für Sie durchführen.

Programmierbeispiel in PHP gemäß Referenz

Konvertierung von RGB nach HSL

Der Wert über Blue # 0000FF rgb (0,0,255) kann als Red Hexadecimal 00 + Green Hexadecimal 00 + Blue Hexadecimal FF dargestellt werden

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

Es kann auch als rote Dezimalzahl 0 + grüne Dezimalzahl 0 + blaue Dezimalzahl 255 dargestellt werden

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

Stecken Sie nun diese Werte in die Routine rgb2hsl. Unten ist meine PHP-Version des generischen Codes von EasyRGB.com für diese Konvertierung aufgeführt:

Die Eingabe ist $ var_r, $ var_g und $ var_b von oben. Die Ausgabe ist HSL-äquivalent zu $ ​​h, $ s und $ l - diese werden wiederum wie die Eingabewerte als Brüche von 1 ausgedrückt

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

Jetzt haben wir die Farbe als HSL-Wert in den Variablen $ h, $ s und $ l. Diese drei Ausgabevariablen werden zu diesem Zeitpunkt wieder als Bruchteile von 1 und nicht als Grad und Prozent gehalten. So würde beispielsweise Cyan (180 ° 100% 50%) als $ h = 0,5, $ s = 1 und $ l = 0,5 ausgegeben.

Finden Sie als nächstes den Wert des gegenüberliegenden Farbtons, dh den Wert, der 180 ° oder 0,5 ° entfernt ist (ich bin sicher, die Mathematiker haben eine elegantere Art, dies zu punktieren, aber):

Berechnen Sie den entgegengesetzten Farbton, $ h2

            $h2 = $h + 0.5;

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

Der HSL-Wert der Komplementärfarbe ist jetzt in $ h2, $ s, $ l. Also sind wir bereit, dies wieder in RGB umzuwandeln (wieder meine PHP-Version der EasyRGB.com-Formel). Beachten Sie, dass die Eingabe- und Ausgabeformate diesmal unterschiedlich sind. Siehe meine Kommentare oben im Code:

Die Eingabe ist der HSL-Wert der Komplementärfarbe, der in $ h2, $ s, $ l als Bruchteile von 1 gespeichert ist. Die Ausgabe ist RGB im normalen Format 255, 255, gehalten in $ r, $ g, $ b. Der Farbton wird mit der gezeigten Funktion hue_2_rgb konvertiert am Ende dieses Codes

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

Und nach dieser Routine haben wir endlich $ r, $ g und $ b im Format 255 255 255 (RGB), das wir in sechs hexadezimale Ziffern konvertieren können:

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

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

$ rgbhex ist unsere Antwort - die Komplementärfarbe in hex.

Da Ihr Farbhintergrund blau oder 0,0,255 ist, ist die HSL

Farbton (H): 240 Grad / Sättigung (S): 100% / Helligkeit (L): 4,9%

Das Gegenteil von 240 ist 60 in einem Kreis, dann ergibt die Rückkonvertierung in RGB einen Wert von # 181800


Vielen Dank! In dem Link geht es jedoch darum, eine "Komplementärfarbe" (was auch immer das ist) für sich selbst zu erzeugen . Ich weiß immer noch nicht, wie ich das verwenden soll, um mein Problem zu lösen: Stellen Sie sicher, dass jede zufällige Farbe nicht der Hintergrundfarbe ähnlich ist. Die Hintergrundfarbe ist konstant, eine Farbe und es gibt mehrere Bälle.
MestreLion

Danke, Krom, dass du das jetzt tust. @MestreLion, da der Hintergrund konstant ist, können Sie einen Bereich für Ihre Bälle festlegen, der den Hintergrund noch ergänzt.
Ace Caserya

Derzeit erkläre ich meine Antwort.
Ace Caserya

Getan. Ich kann nicht viel an den Erklärungen der Seiten ändern, weil es gut genug erklärt wird. Credits an die Jungs bei EasyRGB.com
Ace Caserya


1

Ich möchte die Idee von @ ashes999, eine Gliederung zu erstellen, erweitern.

Mein Code wird so pythonartig wie möglich sein (ich habe in meinem Leben noch nie eine Python-Zeile geschrieben, aber ein oder zwei Mal über ein Buch geschaut).

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

Es mag nicht besonders hübsch aussehen und es ist nicht wirklich ideal für Produktionscode, aber es sollte als schnelle Lösung ausreichen. Ich habe den Code nicht getestet, da mir nicht genau ein Programm zur Verfügung steht, mit dem ich ihn testen kann.


Bearbeiten:

Als ich den tatsächlich verwendeten Code sehe, hat sich die Situation auf den Kopf gestellt, und stattdessen biete ich diese Lösung an.

Ersetzen Sie die Zeilen 276-284 durch Folgendes:

# 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())

In dieser neuen vereinfachten Version spuckt eine Factory-Methode die Kugeln aus und eine spezialisierte Methode erzeugt die Farben. Der Farbgenerator testet die zufällig erzeugte Farbe, um festzustellen, ob sie in einem bestimmten Bereich der Nähe zur Hintergrundfarbe liegt. Eine Farbe kommt der HG-Farbe zu nahe, wenn sich alle drei Farbkanäle auf leewaybeiden Seiten des HG befinden. Wenn also der Spielraum 0 ist, werden nur Farben abgelehnt, die genau mit BG übereinstimmen. Ich habe 5 als Standard gewählt, wodurch die HG-Farbe und die 5 Farben auf beiden Seiten abgelehnt werden. Da die Hintergrundfarbe weiß ist, bin ich mir nicht sicher, ob sie Schwarz ablehnt, da die Ziffern umlaufen. Das kann mit der Verwendung von Min- und Max-Funktionen vermieden werden, aber ich habe sie der Kürze halber weggelassen.


Ich bin offen für jede Strategie :)
Was

Ich benutze pygameals Bibliothek. Kein Lerp, nur einfache RGB-HSV-CYMK-Konvertierungen: pygame.org/docs/ref/color.html
MestreLion

@MestreLion Oh Gott, jetzt muss ich Pygame und Python installieren, um es zu testen. Ich habe mich mit diesem XP in den Fuß geschossen. Lerping ist einfach, die lerpFunktion in meiner Antwort ist alles, was es zu tun gibt. (Lerp bedeutet "lineare Interpolation").
Pharap

@MestreLion Ich habe ein bisschen rumgespielt und festgestellt, dass meine Version von Python es nicht mag, wenn print ohne Klammern aufgerufen wird. Das wurde behoben, aber jetzt habe ich Fehler, weil Pygame nicht in der Lage ist, die richtigen Bibliotheken zu finden. Ich werde meinen Code umschreiben, damit er zu dem passt, was Sie haben, aber ich kann ihn nicht testen, bis ich Pygame repariert habe. Ich würde empfehlen, diese Datei an die Frage anzuhängen, falls Sie dies noch nicht getan haben (falls sich jemand gut genug fühlt, um Python für Sie zu schreiben).
Pharap

Sie printsind anders, weil Sie Python 3 verwenden und ich bin immer noch in Python 2. Und ich bin nicht sicher, ob pygamePy3 noch portiert wurde. Fazit: Mach dir keine Sorgen :) Bei der Frage geht es um Farben, du brauchst keine
echten

1

Für ein RGB-Format scheint dies gut genug zu funktionieren und ist trivial:

Diversity_score = (abs (r1 - r2) + abs (g1 - g2) + abs (b1 - b2)) / 765,0

Dies gibt Ihnen eine Punktzahl zwischen 0,0 und 1,0. Je niedriger, desto schwieriger ist es, zwei Farben zu unterscheiden.

Es sollte offensichtlich sein, aber der Vollständigkeit halber: Die Werte r, g, b müssen zuerst in eine Gleitkommazahl umgewandelt werden, und es wird angenommen, dass ihr Maximalwert 255 ist.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.