# # @color=colorlist($ncolor,$mag) # # Returns a list of $ncolor colors which are equally # distinguishable. These colors all have the smae # magnitude (defined as r^2+g^2+b^2) and lie equidistant # on a circle in the rgb cube (255x255x255). This circle # forms the bottom of a cone whose apex is either at # (0,0,0) or (255,255,255) in rgb space. # # # @color list of rgb colors in HTML compatible format rrggbb # where (rr,gg,bb) is 2 digit hex for red,green,blue # for example, 00ffa9 is (in decimal) 0 red, # 255 green, 169 blue. # $ncolor Number of colors returned. # $mag Magnitude of color, magnitude of 0,1 corresponds # to rgb 000000 and ffffff. Intermediate values # determine color magnitude defined as r^2+g^+b^2/(3*255^2) # Magnitudes ouside the range (0,1) are mapped to (0,1). # sub colorlist { my ($ncolor,$mag) = @_; my ($i,$invert,$pi,$afac,$mfac,$color,$angle,$c,$s,$phase); my (@vec); return () if $ncolor<1; $mag=0 if $mag<0; $mag=1 if $mag>1; @axis=(0.5,0.5,0.5); @nor0=(0.25,0.25,-0.5); @nor1=(sqrt(3.0)/4.0, -sqrt(3.0)/4.0, 0); $pi = 4*atan2(1,1); # Scaling factor to go from index to angle $afac = 2*$pi/$ncolor; $invert = $mag>0.5; $mag = 1-$mag if $invert; # Scaling factor for color components $mfac = $mag*255*4*sqrt(2)/3.0; # Without phase change color[0] will become complemntary # when inverting $phase = $invert ? $pi : 0; # Find color components for each color on wheel for ($color=0;$color<$ncolor;$color++) { $angle = $afac*$color+$phase; $c = cos($angle); $s = sin($angle); for ($i=0;$i<3;$i++) { $vec[$i] = $mfac*($axis[$i] + $c*$nor0[$i] + $s*$nor1[$i]); $vec[$i] = 255-$vec[$i] if $invert; } # Convert color to HTML compatible hex string $color[$color] = sprintf ("%02x%02x%02x", @vec); } return @color; }