Thuật toán sửa đổi màu sắc để làm cho nó ít giống với nền


23

Tôi đang tạo một bản demo gồm 20 quả bóng nảy lên nhau, với một nền chứa đầy màu sắc. Màu sắc cho mỗi quả bóng được chọn ngẫu nhiên với randint(0, 255)mỗi thành phần tuple R, G, B.

Vấn đề là một số quả bóng kết thúc với một màu rất giống với nền, làm cho chúng khó nhìn. Tôi muốn tránh điều đó, bằng cách cuộn một màu khác nếu màu được chọn quá giống nhau (trong một ngưỡng nhất định) hoặc bằng cách di chuyển nó ra khỏi màu nền.

Làm thế nào để tính toán một chỉ số tương tự để sử dụng như một ngưỡng? Hoặc làm thế nào để biến đổi một màu sắc để làm cho nó, nói, ít màu xanh-ish ?

Từ chối trách nhiệm rõ ràng: Tôi không biết gì về lý thuyết màu sắc, vì vậy tôi không biết liệu các khái niệm trên có tồn tại hay không!

Tôi đang mã hóa bằng python, nhưng tôi đang tìm kiếm các khái niệm và chiến lược, vì vậy mã giả là tốt (hoặc chỉ là lý thuyết).

CHỈNH SỬA:

Để làm rõ một vài điểm:

  • Mỗi quả bóng có màu sắc ngẫu nhiên riêng. Tôi muốn chúng duy trì ngẫu nhiên nhất có thể và khám phá càng nhiều càng tốt về không gian màu (có thể là RGB hoặc HSV, pygamechấp nhận cả hai định dạng để xác định màu)

  • Tôi chỉ muốn tránh từng màu "quá gần" với nền. Vấn đề không chỉ là về màu sắc: Tôi hoàn toàn ổn với một quả bóng màu xanh nhạt trên nền màu xanh đậm (hoặc "toàn màu xanh" so với màu xanh "trắng-ish", v.v.)

  • Hiện tại, tôi không quan tâm nếu một quả bóng kết thúc với một màu tương tự (hoặc thậm chí giống hệt) với một quả bóng khác. Tránh đó là một phần thưởng, nhưng đó là một vấn đề nhỏ.

  • Màu nền là một màu RGB không đổi, đơn. Hiện tại tôi đang sử dụng màu xanh "cơ bản" (0, 0, 255), nhưng tôi không giải quyết được điều đó. Vì vậy, hãy xem xét nền có màu tùy ý (với màu sắc tùy ý, độ sáng, độ bão hòa, v.v.).

EDIT2:

Phiên bản TL, DR: Chỉ cần đưa ra cách tạo X màu ngẫu nhiên để không "phai quá nhiều" trên nền màu tùy ý (nhưng đơn và không đổi)



1
Tại sao không chỉ đưa ra một phác thảo xung quanh mỗi quả bóng?
tro999

1
Sau đó, có thể có một vấn đề với việc làm cho màu phác thảo khác biệt với cả màu nền VÀ bóng;)
Kromster nói hỗ trợ Monica

1
@AlexM.: Khó có thể tin rằng không có giải pháp dễ dàng nào để "tạo màu ngẫu nhiên tránh một màu tùy ý"
MestreLion

1
@MestreLion chỉ cần sử dụng màu đen cho phác thảo và tạo màu với giá trị RGB tối thiểu là 128. Thật dễ dàng.
tro999

Câu trả lời:


33

Bạn có thể sử dụng thực tế là màu sắc tạo nên một không gian màu (ba chiều) và tính khoảng cách trong không gian màu này. Sau đó, bạn cần xác định một số liệu trong không gian màu này để tìm khoảng cách giữa hai màu.

Vd x1) + (y2-x2) * (y2-x2) + (y3-x3) * (y3-x3)).

Bây giờ bạn có thể tính khoảng cách giữa màu bóng và màu nền của bạn và nếu nó quá nhỏ, hãy tạo màu ngẫu nhiên mới và kiểm tra lại.

Bạn sẽ thấy rằng cả RGB và HSV đều không phải là không gian màu tốt cho tác vụ này. Các bài viết trên wikipedia sự khác biệt màu sắc sử dụng các L một b không gian màu sắc và cung cấp cho một vài số liệu tốt.

Ngoài ra còn có một sự hỗn loạn về stackoverflow về chủ đề này.


Đó là một cách tiếp cận rất hay, tôi có thể làm điều đó :) Cảm ơn! Ngoài ra, quan tâm đến việc xây dựng một chút về cách tìm ngưỡng "khoảng cách tối thiểu" đầy đủ? Nếu RGB không đầy đủ, làm thế nào để chuyển đổi sang L a b? Tôi không phấn đấu cho các số liệu nhận thức chính xác, do đó, bất kỳ mặc định "đủ tốt" sẽ làm.
MestreLion

1
Yêu câu trả lời này, suy nghĩ tốt, giải thích tốt về cách thực hiện nhiệm vụ trong khi cung cấp các phương trình và tài liệu tham khảo cần thiết. Câu trả lời đầu tiên tốt.
Tom 'Blue' Piddock

1
Nếu bạn đang tìm kiếm một xấp xỉ "đủ tốt" về nhận thức của con người, bạn có thể muốn xem xét không gian màu YUV , có chuyển đổi trực tiếp từ RGB.
trm

5
Tiết kiệm một chút thời gian và đừng lấy căn bậc hai (đắt tiền). Chỉ cần làm cho giá trị khoảng cách màu tối thiểu của bạn mà bạn so sánh với hình vuông.
Chris Cudmore

1
@MestreLion Không gian màu L a b * được phát minh là đồng nhất về mặt nhận thức, nghĩa là khoảng cách cảm nhận giữa hai màu giống như khoảng cách thực tế trong không gian màu. Vì màu RGB phụ thuộc vào thiết bị, bạn không thể chuyển đổi trực tiếp giữa Lab và RGB. Tuy nhiên, nếu bạn sử dụng một không gian màu RGB tuyệt đối cụ thể, bạn có thể chuyển đổi chúng. Xem bài viết này: en.wikipedia.org/wiki/SRGB_color_space và bài viết này: en.wikipedia.org/wiki/Lab_color_space
jwir3

8

Trang tiêu chuẩn truy cập web của Liên hợp quốc ( http://www.un.org/webaccessibility/1_visual/13_colourcontrast.shtml ) không chỉ ra một tiêu chuẩn để đảm bảo độ tương phản văn bản phù hợp trên các trang web, lưu ý rằng một số người dùng bị mù màu. Điều này có thể đặc biệt quan trọng đối với bạn vì một số người dùng của bạn cũng có thể bị mù màu (rất khó để nói một quả bóng màu đỏ từ nền màu xanh lá cây nếu chúng có cùng độ chói).

Trang UN chỉ ra Công cụ phân tích tỷ lệ tương phản màu độ sáng của Juicy Studios tại ( http://juicystudio.com/service/luminositycontrastratio.php#specify ) trong đó nêu rõ văn bản trên nền phải có tỷ lệ tương phản 4,5: 1, ngoại trừ những gì tôi tin là tương tự như trường hợp của bạn:

  • Văn bản lớn: Văn bản quy mô lớn và hình ảnh của văn bản quy mô lớn có tỷ lệ tương phản ít nhất 3: 1

Bây giờ tỷ lệ tương phản là gì? Theo dõi các siêu liên kết xa hơn (điều này thật thú vị!) Chúng ta đến trang W3 xác định tỷ lệ tương phản là:

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

Trong đó L1 và L2 là độ chói tương đối của màu sắc. L1 là màu sáng hơn , L2 là màu ít sáng hơn . Một lần nữa, chúng tôi theo liên kết đến cùng trang W3 chỉ định:

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

LƯU Ý : Biểu tượng dấu mũ ^ ở trên đề cập đến lũy thừa (x²)

Chúng tôi có một khung công tác khá tốt cho thuật toán tương phản (thân thiện với màu sắc!)

  • Xác định giá trị R, G, B cho mỗi màu
  • Xác định độ chói cho từng màu
  • Nếu Tỷ lệ tương phản của màu sáng hơn so với màu ít chói nhất là ít hơn 3, reroll!

2
Có thể muốn lưu ý rằng ^ được cho là lũy thừa. Đối với chúng tôi, những người dùng giống như C điên rồ, điều đó có nghĩa là xor (Tôi thực sự nghĩ rằng bạn đang cố gắng thực hiện một thao tác bitwise trên các giá trị dấu phẩy động trong một phút).
Pharap

Đó là một cách tiếp cận tuyệt vời , tôi thích nó! :)
MestreLion

Và đừng lo lắng ^, tôi sẽ không bao giờ nghĩ về XOR bitwise trong bối cảnh này. . (hoặc trong bất kỳ Phreaks thực C'mon C, ^là simbol de-facto cho lũy thừa trong giả mã (mặc dù rất ít ngôn ngữ thực sự sử dụng nó ... trong python nó **)
MestreLion

1
Chỉ cần sửa lỗi chính tả. Thêm vào đó, nếu một người gặp rắc rối với ^, rất có thể ai đó trong tương lai cũng có thể. Không bị tổn thương để được cụ thể.
John

1
@ John Không phải lo lắng ,. Tôi không chắc chắn sự nhầm lẫn bắt nguồn từ đâu (nghĩa là ngôn ngữ nào được sử dụng ^ cho mục đích nào trước tiên). Tôi chỉ biết ^ đôi khi được sử dụng cho lũy thừa vì kinh nghiệm của tôi với VB (Tôi không biết bất kỳ ngôn ngữ nào khác sử dụng nó như lũy thừa, nhưng có lẽ có một số ngôn ngữ). Giống như một cái đầu, mặc dù đó là biểu tượng caret chứ không phải biểu tượng cà rốt . Có thể muốn thay đổi nó trước khi ai đó làm cho một vị thần nào đó đùa cợt khủng khiếp về lập trình với rau (đặc biệt là liên quan đến căn bậc hai).
Pharap

2

Sử dụng các giá trị RGB bằng cách tạo một 0-255giá trị ngẫu nhiên cho từng thành phần có thể không chỉ tạo ra các màu tương tự với nền, bạn cũng có thể kết thúc bằng các màu rất giống nhau cho các quả bóng.

Có lẽ tôi nên chọn một cách tiếp cận ít ngẫu nhiên hơn và tạo ra các màu được đảm bảo khác biệt thay thế. Bạn có thể tạo màu cho mỗi ~ 32 độ trong dải màu và xen kẽ độ sáng hoặc độ bão hòa (sử dụng mô hình màu HSV thay vì RGB).

Vì vậy, một cái gì đó như thế này:

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

Sẽ tạo ra 20 màu, phân phối độc đáo. Điều này giả sử bạn đang sử dụng toán học số nguyên, vì vậy i = 0i = 1sẽ tạo ra cùng một giá trị màu.

Tất nhiên, điều này không có tỷ lệ quá tốt .. nếu bạn có 100 giá trị màu để tạo, khoảng cách màu có thể không đủ và bạn sẽ lại có màu tương tự. Trong trường hợp đó, bạn cũng có thể thay đổi Vgiá trị (độ sáng).

Tôi không biết màu nền của bạn là như thế nào, nhưng HSV cũng giúp so sánh màu sắc dễ dàng hơn (chỉ cần so sánh 3 thành phần và đừng quên rằng HUE là hình tròn (0 == 360)).

CẬP NHẬT:

Vì tôi không thực sự trả lời câu hỏi của bạn mà chỉ cung cấp một cách tiếp cận khác, đây là cách thuật toán cho một nền tùy ý và các quả bóng màu hoàn toàn ngẫu nhiên có thể trông giống như (đây là một cách tiếp cận mạnh mẽ nhưng sẽ hoạt động tốt cho trường hợp sử dụng của bạn):

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

Về algoritm của bạn, làm thế nào để lấy màu nền vào tài khoản?
MestreLion

Hiện tại nó không tính đến màu nền ... bạn có thể điều chỉnh nó bằng cách so sánh các màu được tạo ra (như được mô tả trong đoạn cuối) và sau đó tạo một màu với một màu khác V(vì thuật toán hiện tại không thay đổi điều đó).
bummzack

@MestreLion Đã thêm một bản cập nhật với thuật toán thay thế
bummzack

Tuyệt vời, đó có vẻ là một chiến lược tốt đẹp. Brute force là OK, màu sắc chỉ được tạo một lần khi khởi tạo, không nằm trong vòng lặp trò chơi. Có vẻ như bạn đang sử dụng cách tiếp cận tương tự như của René, với khoảng cách euclide đơn giản trong HSV, đúng không? Bất kỳ tài liệu tham khảo về một ngưỡng phù hợp cho HSV? Do trọng lượng H, S và V có cùng khoảng cách như trong RGB không?
MestreLion

@MestreLion Vâng, thuật toán thứ hai của tôi khá giống với những gì René đã giải thích trong câu trả lời của anh ấy. Đáng buồn thay, không có giá trị dứt khoát cho một ngưỡng tốt vì sự thay đổi màu sắc không được nhận thấy đồng nhất. Chúng tôi nhận thấy những thay đổi của màu xanh lá cây nhanh hơn nhiều so với màu xanh lam ... vì vậy đối với tông màu xanh lục, ngưỡng nhỏ hơn có thể hoạt động nhưng sẽ không đủ cho các màu khác, v.v. Theo như tôi biết thì không gian màu của Lab gần với nhận thức màu của con người và có thể phù hợp nhất nếu bạn không nhận được kết quả mong muốn với không gian màu HSV.
bummzack

1

Vì bạn đã đề cập rằng bạn có một nền tảng đứng yên, màu sắc của các quả bóng vẫn có thể là ngẫu nhiên nhưng chúng phải rơi ở một số phạm vi nhất định mà vẫn khen nền.

Khái niệm cơ bản. Trước khi chúng tôi làm điều đó bạn cần biết những điều cơ bản. Hãy xem xét các màu sau:

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)

Hỗn hợp các màu RGB [(0..255), (0..255), (0..255)] tạo ra các màu mới như trên.

Tính toán cho các màu tiêu cực Tính toán cho màu âm giống như chuyển đổi màu đỏ thành màu lục lam, màu xanh lục màu tím, màu xanh lam màu vàng.

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)

Màu bổ sung

Theo tài liệu tham khảo về tính toán màu bổ sung: http://serennu.com/colour/rgbtohsl.php

Về HSL

HSL thể hiện màu sắc theo Huế, Độ bão hòa và Độ sáng của chúng, đưa ra một số cho mỗi ba thuộc tính của màu này.

Hue là vị trí của colour trên bánh xe màu, được biểu thị bằng độ từ 0 ° đến 359 °, đại diện cho 360 ° của bánh xe; 0 ° là màu đỏ, 180 ° là màu lục lam đối diện, v.v.

Độ bão hòa là cường độ của màu sắc, nó xỉn hay sáng như thế nào. Độ bão hòa càng thấp, màu càng đậm (màu xám). Điều này được biểu thị bằng phần trăm, 100% là bão hòa hoàn toàn, sáng nhất và 0% là không bão hòa, màu xám.

Sự nhẹ nhàng là màu sắc của ánh sáng. Hơi khác với bão hòa. Màu trắng càng nhiều thì giá trị Độ sáng của nó càng cao, màu đen càng nhiều, Độ sáng của nó càng thấp. Vì vậy, Độ sáng 100% chuyển sang màu trắng, 0% Độ sáng chuyển sang màu đen và màu "tinh khiết" sẽ là 50% Độ sáng.

Dễ dàng nhận thấy sự khác biệt giữa Saturation và Lightness hơn là giải thích nó. Nếu bạn muốn làm rõ, hãy thử xem các biến thể Độ sáng và Độ bão hòa trên trang máy tính màu, chọn màu khá sáng làm màu khởi đầu của bạn.

Vì vậy, ký hiệu HSL trông như thế này, đưa ra các giá trị Hue, Saturation và Lightness theo thứ tự đó: t

Màu đỏ: 0 ° 100% 50% Màu hồng nhạt: 0 ° 100% 90% Màu lục lam: 180 ° 100% 50% Dưới đây là các bước:

  1. Chuyển đổi màu của bạn sang HSL.

  2. Thay đổi giá trị Huế thành giá trị của Huế đối diện (ví dụ: nếu Huế của bạn là 50 °, giá trị ngược lại sẽ ở 230 ° trên bánh xe - xa hơn 180 ° xung quanh).

  3. Để lại các giá trị Saturation và Lightness như cũ.

  4. Chuyển đổi giá trị HSL mới này trở lại ký hiệu màu ban đầu của bạn (RGB hoặc bất cứ thứ gì).

Các trang web như EasyRGB.com có ​​thể thực hiện chuyển đổi chung cho bạn từ RGB sang HSL hoặc ngược lại.

Lập trìnhVí dụ được thực hiện trong PHP theo tham chiếu

Chuyển đổi từ RGB sang HSL

Giá trị trên Blue # 0000FF rgb (0,0,255) có thể được trình bày dưới dạng Red Hexadecimal 00 + Green Hexadecimal 00 + Blue Hexadecimal FF

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

Nó cũng có thể được trình bày dưới dạng số thập phân màu đỏ 0 + số thập phân màu xanh 0 + số thập phân màu xanh 255

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

Bây giờ cắm các giá trị này vào thói quen rgb2hsl. Dưới đây là phiên bản PHP của mã chung của EasyRGB.com cho chuyển đổi đó:

Đầu vào là $ var_r, $ var_g và $ var_b từ phía trên Đầu ra là HSL tương đương với $ h, $ s và $ l - chúng được biểu thị lại dưới dạng phân số 1, giống như các giá trị đầu vào

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

Vì vậy, bây giờ chúng ta có màu như một giá trị HSL, trong các biến $ h, $ s và $ l. Ba biến đầu ra này một lần nữa được giữ dưới dạng phân số 1 ở giai đoạn này, thay vì theo độ và tỷ lệ phần trăm. Vì vậy, ví dụ, màu lục lam (180 ° 100% 50%) sẽ xuất hiện dưới dạng $ h = 0,5, $ s = 1 và $ l = 0,5.

Tiếp theo, tìm giá trị của Huế đối diện, tức là cách 180 ° hoặc 0,5, (tôi chắc chắn các nhà toán học có cách chấm điểm này thanh lịch hơn, nhưng):

Tính màu sắc ngược lại, $ h2

            $h2 = $h + 0.5;

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

Giá trị HSL của màu bổ sung hiện ở $ h2, $ s, $ l. Vì vậy, chúng tôi đã sẵn sàng để chuyển đổi lại thành RGB (một lần nữa, phiên bản PHP của công thức EasyRGB.com). Lưu ý các định dạng đầu vào và đầu ra là khác nhau lần này, xem nhận xét của tôi ở đầu mã:

Đầu vào là giá trị HSL của màu bổ sung, được giữ ở $ h2, $ s, $ l dưới dạng phân số của 1 Đầu ra là RGB ở định dạng 255 255 255 bình thường, được giữ ở $ r, $ g, $ b Hue được chuyển đổi bằng hàm hue_2_rgb, được hiển thị ở cuối mã này

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

Và sau thói quen đó, cuối cùng chúng ta cũng có định dạng $ r, $ g và $ b ở định dạng 255 255 255 (RGB), chúng ta có thể chuyển đổi thành sáu chữ số hex:

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

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

$ rgbhex là câu trả lời của chúng tôi - màu bổ sung trong hex.

Vì nền màu của bạn là màu xanh hoặc 0,0,255, HSL là

Huế (H): 240 độ / Độ bão hòa (S): 100% / Độ sáng (L): 4,9%

đối diện với 240 là 60 trong một vòng tròn sau đó chuyển đổi trở lại RGB cho giá trị # 181800


Cảm ơn! Nhưng liên kết nói về việc tạo ra một "màu bổ sung" (bất kể đó là gì) của chính nó . Tôi vẫn không biết cách sử dụng nó để giải quyết vấn đề của mình: đảm bảo rằng mỗi màu ngẫu nhiên không giống với màu nền. Màu nền không đổi, một màu và có nhiều bóng.
MestreLion

Cảm ơn Krom đang làm điều đó bây giờ. @MestreLion, vì nền không đổi nên bạn có thể chỉ định một phạm vi cho các quả bóng của bạn vẫn bổ sung cho nền.
Ace Caserya

Hiện đang trả lời câu trả lời của tôi.
Ace Caserya

Làm xong. Tôi không có gì để thay đổi nhiều trên các giải thích trang web bởi vì nó được giải thích đủ tốt. Tín dụng cho những kẻ tại EasyRGB.com
Ace Caserya


1

Tôi muốn mở rộng dựa trên ý tưởng tạo ra một phác thảo.

Mã của tôi sẽ giống như con trăn như tôi có thể rời khỏi đỉnh đầu (Tôi chưa bao giờ viết một dòng trăn trong đời, nhưng tôi đã liếc qua một cuốn sách một hoặc hai lần).

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

Nó có thể trông không đặc biệt đẹp và nó không thực sự lý tưởng cho mã sản xuất, nhưng nó phải là một sửa chữa nhanh. Tôi đã không kiểm tra mã vì tôi không chính xác có một chương trình "quả bóng nảy trên màn hình" để đưa ra rằng tôi có thể cắt xén để kiểm tra nó.


Chỉnh sửa:

Khi nhìn thấy mã thực tế đang sử dụng, tình huống đã xảy ra, vì vậy thay vào đó tôi đưa ra giải pháp này.

Thay thế các dòng 276-284 bằng các dòng sau:

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

Trong phiên bản đơn giản hóa mới này, một phương thức xuất xưởng sẽ tạo ra các quả bóng và một phương thức chuyên dụng tạo ra màu sắc. Trình tạo màu kiểm tra màu được tạo ngẫu nhiên để xem liệu nó có nằm trong một phạm vi gần nhất định với màu nền không. Một màu được coi là quá gần với màu BG nếu cả ba kênh màu của nó nằm trong leewaymột trong hai phía của BG. Vì vậy, nếu độ trễ là 0, chỉ những màu khớp chính xác với BG mới bị từ chối. Tôi đã chọn 5 làm mặc định, từ chối màu BG và 5 màu hai bên. Vì màu BG là màu trắng, tôi không chắc liệu nó có từ chối màu đen không vì các chữ số bao quanh. Điều đó có thể tránh được bằng cách sử dụng các hàm min và max, nhưng tôi đã bỏ chúng đi vì lý do ngắn gọn.


Tôi sẵn sàng cho bất kỳ chiến lược nào :) vì để chương trình cắt xén, tôi có thể cung cấp cho bạn rằng: github.com/MestreLion/rainballs các dòng có liên quan sẽ là 279-284
MestreLion

Tôi đang sử dụng pygamenhư một thư viện. Không có Lerp, chỉ chuyển đổi RGB-HSV-CYMK cơ bản: pygame.org/docs/ref/color.html
MestreLion

@MestreLion Ôi chúa ơi, bây giờ tôi phải cài đặt pygame và python để kiểm tra nó. Tôi đã tự bắn vào chân mình bằng chiếc XP này. Dễ dàng, lerpchức năng trong câu trả lời của tôi là tất cả. (Lerp có nghĩa là 'Nội suy tuyến tính').
Pharap

@MestreLion Loay hoay một chút, hóa ra phiên bản trăn của tôi không giống như in được gọi mà không có dấu ngoặc đơn. Đã sửa lỗi đó, nhưng giờ tôi đã gặp lỗi từ pygame vì không thể tìm đúng thư viện. Tôi sẽ viết lại mã của mình để phù hợp với những gì bạn đã có, nhưng tôi không thể kiểm tra nó cho đến khi tôi sửa lỗi pygame. Tôi khuyên bạn nên thêm tệp đó vào câu hỏi nếu bạn chưa có (trong trường hợp có ai cảm thấy đủ tốt để viết một số trăn cho bạn).
Pharap

Bạn printkhác biệt bởi vì bạn đang sử dụng Python 3 và tôi vẫn ở trong Python 2. Và tôi không chắc pygameđã được chuyển sang Py3 chưa. Điểm mấu chốt: đừng bận tâm :) Câu hỏi là về màu sắc, bạn không cần những quả bóng thực sự nảy xung quanh :)
MestreLion

1

Đối với định dạng RGB, điều này dường như hoạt động đủ tốt và tầm thường:

sự đa dạng_score = (abs (r1 - r2) + abs (g1 - g2) + abs (b1 - b2)) / 765.0

Điều này sẽ cung cấp cho bạn một số điểm giữa 0,0 và 1,0. Càng thấp, càng khó phân biệt hai màu.

Điều này là hiển nhiên, nhưng để hoàn thiện: các giá trị r, g, b phải được chuyển thành số dấu phẩy động trước và giả định rằng giá trị tối đa của chúng là 255.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.