sub {{
my $ret = [ map {int} @$c ];
...
to stop returning floating point back to the caller.
Makes for funny HTML otherwise.
Update:
Actually, you're rounding too early.
$w = [ map {
my $v = $f + $s*$_/$i;
$f = $v - int($v);
$v # not int $v
} @$w ];
$w->[-1] += $f;
The problem is that it works fine for linear gradients, but when
you use non-linear gradients the round-off adds up and your
iterator poops out before it gets to the end.
Why would you want to use a non-linear gradient? Because
the (in)?famous Netscape Color Cube(TM) is a terrible thing:
it lends to much emphasis to highly saturated colors, and as
a result there are too few colors to represent the many
subtle hues the eye is capable of distinguishing.
So what I attempted to do was to create a sinusoidal
curve, peaking at 1 in the middle of the gradient and
dropping to 0 at the ends. That's where I uncovered the
int problem. Once I had my weight array the way
I wanted it, I plugged it into the iterator, but for some
reason that escapes me, I'm not seeing the behaviour I
expect. The numbers should climb away quickly from first value in
the interval move slowly around the midpoint, and then drop
quickly down to the end value.
It may be that I have completely misunderstood what
the weights' purpose. Whatever, here's the code. No, I
didn't use CGI, this is a quick hack, not production code.
use constant PI => 4 * atan2(1,1);
my $intervals = 40;
my $iterlin = range( [ 0,255,255] => [ 0,255, 0],
[(1) x $intervals],
$intervals );
my $itersin = range( [ 0,255,255] => [ 0,255, 0],
[ map {sin(($_/$intervals)*PI) } 0..$intervals],
$intervals );
print qq{<html><head><title>Gradient</title></head>
<body bgcolor="#ffffff"><table>\n};
while (my ($rgb_lin, $width) = $iterlin->()) {
my ($rgb_sin, $widthsin) = $itersin->();
my $lin = join '', '#',
map { sprintf '%02x',$_ } @$rgb_lin;
my $sin = join '', '#',
map { sprintf '%02x',$_ } @$rgb_sin;
print qq{<tr>
<td bgcolor="$lin"><tt>$$rgb_lin[0]</tt></td>
<td bgcolor="$lin"><tt>$$rgb_lin[1]</tt></td>
<td bgcolor="$lin"><tt>$$rgb_lin[2]</tt></td>
<td bgcolor="$sin"><tt>$$rgb_sin[0]</tt></td>
<td bgcolor="$sin"><tt>$$rgb_sin[1]</tt></td>
<td bgcolor="$sin"><tt>$$rgb_sin[2]</tt></td>
</tr>};
}
print "</table></body></html>\n";
|