termcol: generic h/s/v table generator function
authorMischa POSLAWSKY <perl@shiar.org>
Sat, 31 Oct 2015 23:11:47 +0000 (00:11 +0100)
committerMischa POSLAWSKY <perl@shiar.org>
Tue, 10 Nov 2015 21:24:03 +0000 (22:24 +0100)
Identical results for 256 colours but reusable for other bit sizes.

termcol.plp

index b5f08b2..d945079 100644 (file)
@@ -252,55 +252,68 @@ print "</table>\n\n";
 <div class="section">
 <h2>256-colour space</h2>
 <:
-my @colmap;  # saturation => value => hue => [name, r,g,b]
-my %greymap;  # name => value
-$greymap{232 + $_} = $_*10 + 8 for 0 .. 23;
+sub coltable_hsv {
+       my ($dim, $rgbval, $greyramp) = @_;
 
-for my $r (0 .. 5) {
-       for my $g (0 .. 5) {
-               for my $b (0 .. 5) {
-                       my $index = $r*6*6 + $g*6 + $b + 16;
-                       my @rgb = map { $_ && $_*40 + 55 } $r, $g, $b;
+       my $hmax = ($dim + $dim - 1) * 2 + ($dim - 2) * 2 + 3;
+       my $vmax = $dim - 1;
+       my $smax = $dim - 1;
 
-                       my $h = Shiar_Sheet::Colour->new(@rgb)->hue * 33;
-                       my $v = int(max(@rgb) / 255 * 5);
-                       my $s = abs(min(@rgb) - max(@rgb)) / 255 * 7;
+       my %greymap;  # name => value
+       my @colmap;  # saturation => value => hue => [name, r,g,b]
+       my $offset = 16;
 
-                       if (!$s) {
-                               $greymap{$index} = $rgb[0];
-                               next;
-                       }
+       for my $r (0 .. $dim - 1) {
+               for my $g (0 .. $dim - 1) {
+                       for my $b (0 .. $dim - 1) {
+                               my $index = $r*$dim*$dim + $g*$dim + $b + $offset;
+                               my @rgb = map { &$rgbval } $r, $g, $b;
+
+                               my $h = Shiar_Sheet::Colour->new(@rgb)->hue * $hmax;
+                               my $v = int(max(@rgb) / 255 * $vmax);
+                               my $s = abs(min(@rgb) - max(@rgb)) / 255 * $smax;
 
-                       $v = 5 - $v;
-                       $s = 7 - $s - $v;
-                       $s-- if $s;
+                               if (!$s) {
+                                       $greymap{$index} = $rgb[0];
+                                       next;
+                               }
 
-                       $colmap[$s][$v][$h] = [$index, @rgb];
+                               $v = $vmax - $v;
+                               $s = $smax - $s - $v;
+
+                               $colmap[$s][$v][$h] = [$index, @rgb];
+                       }
                }
        }
-}
 
-{
-       print '<table class=mapped>';
-       printf '<colgroup span=%d>', 3 * @{$_} for @colmap;
-       for my $h (grep { $colmap[0][0][$_] } 0 .. $#{ $colmap[0][0] }) {
-               print '<tr>';
-               print colcell(@$_) for map { $_->[$h] } map { @{$_} } @colmap;
+       my $out = '<table class=mapped>';
+       $out .= sprintf '<colgroup span=%d>', 3 * @{$_} for @colmap;
+       my $huerow = $colmap[0][0]; # first {$_} map { @{$_} } @colmap;
+       for my $h (grep { $huerow->[$_] } 0 .. $#{$huerow}) {
+               $out .= '<tr>';
+               $out .= colcell(@$_) for map { $_->[$h] } map { @{$_} } @colmap;
        }
-       print "</table>\n";
-}
-print "\n";
+       $out .= "</table>\n\n";
 
-       print '<table>';
-my $col = 0;
-my $colbreak = keys(%greymap) / 2;  # split into 2 rows
-for my $num (sort { $greymap{$a} <=> $greymap{$b} } keys %greymap) {
-       print '<tr>' unless $col++ % $colbreak;
-       print colcell($num, ($greymap{$num}) x 3);
+       $offset += $dim ** 3;
+       $greymap{$offset++} = $_ for @{$greyramp};
+
+       $out .= '<table>';
+       my $col = 0;
+       my $colbreak = keys(%greymap) / 2;  # split into 2 rows
+       for my $num (sort { $greymap{$a} <=> $greymap{$b} } keys %greymap) {
+               $out .= '<tr>' unless $col++ % $colbreak;
+               $out .= colcell($num, ($greymap{$num}) x 3);
+       }
+       $out .= "</table>\n\n";
+
+       return $out;
 }
-       print "</table>\n";
-print "\n";
 
+print coltable_hsv(6,
+       sub { $_ && $_*40 + 55 },
+       [ map { $_ * 10 + 8 } 0 .. 23 ],
+);
 :></div>
 <: } :>
 <hr>