I think you want to
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";
In reply to Re: RGBgradient
by grinder
in thread RGBgradient
by japhy
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |