#!/usr/bin/perl -w use strict; use lib '.'; use common; sub pi() { 4 * atan2(1, 1) } print ""; my $c = { 'red' => 0, 'green' => 0, 'blue' => 0, 'low' => 0, }; convertsRGBtoHCY($c); my @forceColours = ( { 'red' => 0, 'green' => 0, 'blue' => 0, }, { 'red' => 255, 'green' => 0, 'blue' => 0, }, { 'red' => 0, 'green' => 255, 'blue' => 0, }, { 'red' => 0, 'green' => 0, 'blue' => 255, }, { 'red' => 255, 'green' => 255, 'blue' => 0, }, { 'red' => 0, 'green' => 255, 'blue' => 255, }, { 'red' => 255, 'green' => 0, 'blue' => 255, }, { 'red' => 255, 'green' => 128, 'blue' => 0, }, { 'red' => 128, 'green' => 128, 'blue' => 128, }, { 'red' => 32, 'green' => 32, 'blue' => 32, }, { 'red' => 172, 'green' => 172, 'blue' => 172, }, { 'red' => 172, 'green' => 173, 'blue' => 172, }, { 'red' => 254, 'green' => 255, 'blue' => 255, }, { 'red' => 255, 'green' => 255, 'blue' => 255, }, { 'red' => 161, 'green' => 195, 'blue' => 41, }); my @colours = ($c); my $maxH = 360; my $reqDH = 30; my $reqDRGB = 125; my $attempts = 0; colour: while (@colours < 200) { $attempts += 1; last colour if $attempts > 1000; my $forced; if (@forceColours) { $c = pop @forceColours; $forced = 1; } else { $c = { 'red' => randcomp(), 'green' => randcomp(), 'blue' => randcomp(), }; $forced = 0; } convertsRGBtoHCY($c); warn sprintf "\ntrying %d,%d,%d %s H=%d, C=%d, Y'=%d\n", $c->{red}, $c->{green}, $c->{blue}, $forced ? 'forced' : '', $c->{H}, $c->{C}, $c->{"Y'"}; my $low; foreach (@colours) { warn sprintf "against %d,%d,%d %s H=%d, C=%d, Y'=%d\n", $_->{red}, $_->{green}, $_->{blue}, '', $_->{H}, $_->{C}, $_->{"Y'"}; my $DRGB = abs($c->{red}-$_->{red}) + abs($c->{green}-$_->{green}) + abs($c->{blue}-$_->{blue}); my $DH = abs($_->{H}-$c->{H}); my $DC = abs($_->{C}-$c->{C}); my $MC = ($_->{C}+$c->{C})/2; if ($DH > $maxH/2) { $DH = $maxH - $DH; } my $DY = abs($_->{"Y'"}-$c->{"Y'"}); my $MY = ($_->{"Y'"}+$c->{"Y'"})/2; warn "DRGB=$DRGB; DH=$DH; DC=$DC; DY=$DY; MC=$MC; MY=$MY\n"; if ($DRGB < $reqDRGB) { warn sprintf "losing forced colour %d,%d,%d because DRGB is only $DRGB\n", $c->{red}, $c->{green}, $c->{blue} if $forced; next colour; } if ($DY < 50 and $DC < 50) { #$DH *= abs(128-$MY)/128 * $MC/255; if ($DH < $reqDH) { warn sprintf "losing forced colour %d,%d,%d with DH=$DH\n", $c->{red}, $c->{green}, $c->{blue} if $forced; next colour; } } else { warn "good enough DY or DC\n"; $DH = 999; } if (not defined $low or $low > $DH) { $low = $DH; } } $c->{low} = $low; push(@colours, $c); warn "keeping forced colour\n" if $forced; $attempts = 0; } foreach (@colours) { printf "
%f %f
\n", $_->{red}, $_->{green}, $_->{blue}, 0, $_->{low}; } print '
'; foreach (sort { $a->{'H'} <=> $b->{'H'} } @colours) { printf "
%f %f
\n", $_->{red}, $_->{green}, $_->{blue}, $_->{'H'}, $_->{low}; } print '
'; foreach (sort { $a->{"Y'"} <=> $b->{"Y'"} } @colours) { printf "
%f %f
\n", $_->{red}, $_->{green}, $_->{blue}, $_->{"Y'"}, $_->{low}; } sub randcomp { return (cos(pi*rand(1))+1)*128; } sub convertsRGBtoHCY { my($c) = @_; my $r = $c->{red}; my $g = $c->{green}; my $b = $c->{blue}; my $alpha = (1/2) * (2*$r-$g-$b); my $beta = (sqrt(3)/2) * ($g-$b); my $H = atan2($beta, $alpha); $H += 2*pi if ($H < 0); $H *= 180/pi; # if ($H > 100) { # if ($H > 140) { # $H -= 40; # } else { # $H = 100; # } #} $c->{H} = $H; $c->{C} = sqrt($alpha**2+$beta**2); # Luma (Y') with sRGB (Rec. 709) primaries: # http://en.wikipedia.org/wiki/HSL_and_HSV#Lightness $c->{"Y'"} = 0.21*$r + 0.72*$g + 0.07*$b; }