Color wheel: Difference between revisions
Thundergnat (talk | contribs) m (→{{header|Perl 6}}: Better variable naming, minor style tweaks) |
(→{{header|Perl 6}}: added zkl) |
||
Line 72: | Line 72: | ||
Until local image uploading is re-enabled, see [https://github.com/thundergnat/rc/blob/master/img/Color-wheel-perl6.png Color-wheel-perl6.png] |
Until local image uploading is re-enabled, see [https://github.com/thundergnat/rc/blob/master/img/Color-wheel-perl6.png Color-wheel-perl6.png] |
||
=={{header|zkl}}== |
|||
A color square - I just fill a square with the color wheel, it could be clipped to a circle if needed. |
|||
Each point in the square is converted to polar coordinates, the angle is hue and the radius is saturation (which is scaled by the distance from the pole). |
|||
<lang zkl>var w=300,h=300,out=PPM(w,h); |
|||
colorWheel(out); |
|||
out.writeJPGFile("colorWheel.zkl.jpg"); |
|||
fcn colorWheel(ppm){ |
|||
centerX,centerY:=ppm.w/2,ppm.h/2; |
|||
d:=centerX.toFloat().hypot(centerY); |
|||
foreach x,y in (w,h){ |
|||
v,hue:=(x - centerX).toFloat().toPolar(y - centerY); |
|||
if((hue = hue.toDeg())<0) hue+=360; // (-pi..pi] to [0..2pi) |
|||
s:=v/d; // scale saturation zero at center to 1 at edge |
|||
ppm[x,y]=hsv2rgb(hue,1.0,s); |
|||
} |
|||
} |
|||
fcn hsv2rgb(hue,v,s){ // 0<=H<360, 0<=v(brightness)<=1, 0<=saturation<=1 |
|||
// --> 24 bit RGB each R,G,B in [0..255] |
|||
to24bit:=fcn(r,g,b,m){ |
|||
r,g,b=((r+m)*255).toInt(),((g+m)*255).toInt(),((b+m)*255).toInt(); |
|||
r*0x10000 + g*0x100 + b |
|||
}; |
|||
c:=v*s; |
|||
x:=c*(1.0 - (hue.toFloat()/60%2 - 1).abs()); |
|||
m:=v - c; |
|||
if (0 <=hue< 60) return(to24bit(c, x, 0.0,m)); |
|||
else if(60 <=hue<120) return(to24bit(x, c, 0.0,m)); |
|||
else if(120<=hue<180) return(to24bit(0.0,c, x, m)); |
|||
else if(180<=hue<240) return(to24bit(0.0,x, c, m)); |
|||
else if(240<=hue<300) return(to24bit(x, 0.0,c, m)); |
|||
else return(to24bit(c, 0.0,x, m)); |
|||
}</lang> |
|||
Until local image uploading is re-enabled, see [http://www.zenkinetic.com/Documents/colorWheel.zkl.jpg this image]. |
Revision as of 02:23, 24 August 2016
- Task
Write a function to draw a color wheel completely with code. This is strictly for learning purposes only. It's highly recommended that you use an image in an actual application to actually draw the color wheel as procedurally drawing this is super slow. This does help you understand how color wheels work and this can easily be used to determine a color value based on a position within a circle.
GML
<lang GML> for (var i = 1; i <= 360; i++) {
for (var j = 0; j < 255; j++) {
var hue = 255*(i/360); var saturation = j; var value = 255;
var c = make_colour_hsv(hue,saturation,value); //size of circle determined by how far from the center it is //if you just draw them too small the circle won't be full. //it will have patches inside it that didn't get filled in with color var r = max(1,3*(j/255));
//Math for built-in GMS functions //lengthdir_x(len,dir) = +cos(degtorad(direction))*length; //lengthdir_y(len,dir) = -sin(degtorad(direction))*length; draw_circle_colour(x+lengthdir_x(m_radius*(j/255),i),y+lengthdir_y(m_radius*(j/255),i),r,c,c,false); }
} </lang>
Perl 6
<lang perl6>use Image::PNG::Portable;
my ($w, $h) = 300, 300;
my $out = Image::PNG::Portable.new: :width($w), :height($h);
my $center = $w/2 + $h/2*i;
color-wheel($out);
$out.write: 'Color-wheel-perl6.png';
sub color-wheel ( $png ) {
for ^$w -> $x { for ^$h -> $y { my $vector = $center - $x - $y*i; my $magnitude = $vector.abs * 2 / $w; my $direction = ( π + atan2( |$vector.reals ) ) / τ; $png.set: $x, $y, |hsv2rgb( $direction, $magnitude, $magnitude < 1 ); } }
}
sub hsv2rgb ( $h, $s, $v ){ # inputs normalized 0-1
my $c = $v * $s; my $x = $c * (1 - abs( (($h*6) % 2) - 1 ) ); my $m = $v - $c; my ($r, $g, $b) = do given $h { when 0..^(1/6) { $c, $x, 0 } when 1/6..^(1/3) { $x, $c, 0 } when 1/3..^(1/2) { 0, $c, $x } when 1/2..^(2/3) { 0, $x, $c } when 2/3..^(5/6) { $x, 0, $c } when 5/6..1 { $c, 0, $x } } ( $r, $g, $b ) = map { (($_+$m) * 255).Int }, $r, $g, $b;
}</lang>
Until local image uploading is re-enabled, see Color-wheel-perl6.png
zkl
A color square - I just fill a square with the color wheel, it could be clipped to a circle if needed. Each point in the square is converted to polar coordinates, the angle is hue and the radius is saturation (which is scaled by the distance from the pole). <lang zkl>var w=300,h=300,out=PPM(w,h); colorWheel(out); out.writeJPGFile("colorWheel.zkl.jpg");
fcn colorWheel(ppm){
centerX,centerY:=ppm.w/2,ppm.h/2; d:=centerX.toFloat().hypot(centerY); foreach x,y in (w,h){ v,hue:=(x - centerX).toFloat().toPolar(y - centerY); if((hue = hue.toDeg())<0) hue+=360; // (-pi..pi] to [0..2pi) s:=v/d; // scale saturation zero at center to 1 at edge ppm[x,y]=hsv2rgb(hue,1.0,s); }
}
fcn hsv2rgb(hue,v,s){ // 0<=H<360, 0<=v(brightness)<=1, 0<=saturation<=1 // --> 24 bit RGB each R,G,B in [0..255]
to24bit:=fcn(r,g,b,m){ r,g,b=((r+m)*255).toInt(),((g+m)*255).toInt(),((b+m)*255).toInt(); r*0x10000 + g*0x100 + b }; c:=v*s; x:=c*(1.0 - (hue.toFloat()/60%2 - 1).abs()); m:=v - c; if (0 <=hue< 60) return(to24bit(c, x, 0.0,m)); else if(60 <=hue<120) return(to24bit(x, c, 0.0,m)); else if(120<=hue<180) return(to24bit(0.0,c, x, m)); else if(180<=hue<240) return(to24bit(0.0,x, c, m)); else if(240<=hue<300) return(to24bit(x, 0.0,c, m)); else return(to24bit(c, 0.0,x, m));
}</lang> Until local image uploading is re-enabled, see this image.