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,
pygame
akzeptiert 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"
Antworten:
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.
quelle
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:
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:
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:
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!)
quelle
^
, 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**
)Wenn Sie RGB-Werte verwenden, indem Sie
0-255
fü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:
Dadurch entstehen 20 Farben, die gut verteilt sind. Dies setzt voraus, dass Sie eine Ganzzahl-Mathematik verwenden
i = 0
undi = 1
erstellt 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 die
V
(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):
quelle
V
(da dies durch den aktuellen Algorithmus nicht geändert wird).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:
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.
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:
Konvertieren Sie Ihre Farbe in HSL.
Ä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).
Lassen Sie die Werte für Sättigung und Helligkeit unverändert.
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
Es kann auch als rote Dezimalzahl 0 + grüne Dezimalzahl 0 + blaue Dezimalzahl 255 dargestellt werden
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
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
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
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:
$ 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
quelle
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).
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:
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
leeway
beiden 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.quelle
pygame
als Bibliothek. Kein Lerp, nur einfache RGB-HSV-CYMK-Konvertierungen: pygame.org/docs/ref/color.htmllerp
Funktion in meiner Antwort ist alles, was es zu tun gibt. (Lerp bedeutet "lineare Interpolation").print
sind anders, weil Sie Python 3 verwenden und ich bin immer noch in Python 2. Und ich bin nicht sicher, obpygame
Py3 noch portiert wurde. Fazit: Mach dir keine Sorgen :) Bei der Frage geht es um Farben, du brauchst keineFü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.
quelle