|
|
I have tested the CHSL2RGB macro and fixed some bugs in it and I've also
coded a CRGB2HSL macro that converts the other way. The conversion back and
forth is perfect at least in the tests I've made. Here are the two macros
and some code that shows that multiple conversions back and forth produce
consistent results.
I will include these macros in colors.inc. The other color formats will be
dropped.
Please feel free to make lots of tests, as there might still be some bugs
left!
#macro CHSL2RGB(Color)
#local Color = color Color;
// Extract Hue, Saturation and Lightness components
#local H = (Color.red);
#local S = (Color.green);
#local L = (Color.blue);
#local H = mod(H, 360);
#local H = (H < 0 ? H+360 : H);
// Construct saturaed RGB from Hue
#switch (H)
#range (0, 120)
#local SR = (120 - H)/60;
#local SG = ( H - 0)/60;
#local SB = 0;
#break
#range (120, 240)
#local SR = 0;
#local SG = (240 - H)/60;
#local SB = ( H - 120)/60;
#break
#range (240, 360)
#local SR = ( H - 240)/60;
#local SG = 0;
#local SB = (360 - H)/60;
#break
#end // switch
#local SaturatedRGB = <min(SR,1), min(SG,1), min(SB,1)>;
// Incorporate saturation and lightness
#switch (L)
#range (0.0, 0.5)
#local RGB = ((SaturatedRGB*S+0.5*(1-S))*L*2);
#break
#range (0.5, 1.0)
#local RGB = ((SaturatedRGB*S+0.5*(1-S))*(2-L*2)+1*(L*2-1));
#break
#end
<RGB.red,RGB.green,RGB.blue,Color.filter,Color.transmit>
#end // macro CHSL2RGB
#macro CRGB2HSL(Color)
#local Color = color Color;
// Extract Red, Green and Blue components
#local R = (Color.red);
#local G = (Color.green);
#local B = (Color.blue);
// Find minimum and maximum component of RGB
#local MIN = min(R,min(G,B));
#local MAX = max(R,max(G,B));
// Find Lightness
#local L = (MAX+MIN)/2;
#if (L<=0|L>=1)
#local HSL = <0,0,min(1,max(0,L))>;
#else
// Find Saturation
#local S = (MAX-MIN) / ( L<0.5 ? (L*2) : (2-L*2) );
#if (S<=0)
#local HSL = <0,0,L>;
#else
// Find fully saturated version of Red, Green and Blue
#local SR = (R-MIN)/(MAX-MIN);
#local SG = (G-MIN)/(MAX-MIN);
#local SB = (B-MIN)/(MAX-MIN);
// Construct Angle from SR, SG and SB
#if (SB=0)
#if (SR=1)
#local Angle = ( SG)*60 ;
#else
#local Angle = (1-SR)*60 + 60;
#end
#end
#if (SR=0)
#if (SG=1)
#local Angle = ( SB)*60 + 120;
#else
#local Angle = (1-SG)*60 + 180;
#end
#end
#if (SG=0)
#if (SB=1)
#local Angle = ( SR)*60 + 240;
#else
#local Angle = (1-SB)*60 + 300;
#end
#end
#local HSL = <Angle,S,L>;
#end
#end
<HSL.x,HSL.y,HSL.z,Color.filter,Color.transmit>
#end // macro CRGB2HSL
#declare Xm = 20;
#declare Ym = 20;
#declare X = 0;
#while (X<=Xm)
#declare Y = 0;
#while (Y<=Ym)
#declare Xv = (X/Xm);
#declare Yv = (Y/Ym);
sphere {
<Xv,Yv,0>-0.6*x, 0.1
pigment {color CHSL2RGB(<0,Xv,Yv>)}
finish {ambient 1 diffuse 0}
}
sphere {
<Xv,Yv,0>+0.6*x, 0.1
pigment {color CHSL2RGB(CRGB2HSL(CHSL2RGB(<0,Xv,Yv>)))}
finish {ambient 1 diffuse 0}
}
#declare Y=Y+1;
#end
#declare X=X+1;
#end
camera {translate <0.5,0.5,-2>}
background {color rgb 0.5}
Rune
--
3D images and anims, include files, tutorials and more:
Rune's World: http://rsj.mobilixnet.dk (updated June 26)
POV-Ray Users: http://rsj.mobilixnet.dk/povrayusers/
POV-Ray Webring: http://webring.povray.co.uk
Post a reply to this message
|
|