|
![](/i/fill.gif) |
Le Forgeron <jgr### [at] free fr> wrote:
> I would agree... would you mind sharing your SDL interpolation code ?
I don't mind. It can be likely far better optimized. It is quite easy to do as
a macro using #if, #range, etc., but was quite cumbersome to make a continuous
function through creative use of select(), especially since functions don't
handle vectors, so each component has to be split out separately and
recombined.
I have also influded the function for converting HSV/HSL to XYZ and back
The formulae for these are based on the ones from wikipedia
http://en.wikipedia.org/wiki/HSV_color_space
Let me know if you see any errors or have questions.
//RGB to HSV
#declare HHSV=function(R,G,B)
{
60*
select(
min(R,G,B)-max(R,G,B)
,//min<max
select(
R-max(R,G,B)
,//R<max
select(
B-max(R,G,B)
,//G=max
(B-R)/(max(R,G,B)-min(R,G,B))+2
,//B=max
(R-G)/(max(R,G,B)-min(R,G,B))+4
)
,//R=max
(G-B)/(max(R,G,B)-min(R,G,B))+
select(
G-B
,//G>B
6
,//B>G
0
)
)
,//min=max
0
)
}
#declare SHSV=function(R,G,B) {select(-max(R,G,B),1-min(R,G,B)/max(R,G,B),0)}
#declare VHSV=function(R,G,B) {max(R,G,B)}
//END RGB to HSV
//RGB to HSL
#declare HHSL=function(R,G,B) {HHSV(R,G,B)} //same as HSV
#declare SHSL=function(R,G,B)
{
select(
min(R,G,B)-max(R,G,B)
,//max>min
(max(R,G,B)-min(R,G,B))/
select(
1-(max(R,G,B)+min(R,G,B))
,//l>1/2
2-(max(R,G,B)+min(R,G,B))
,//1/2=>l
max(R,G,B)+min(R,G,B)
)
,//max=min
0
)
}
#declare LHSL=function(R,G,B){(max(R,G,B)+min(R,G,B))/2}
//END RGB to HSL
//HSL to RGB
#declare tHSL=function(H,C){(H/360+C/3)-floor(H/360+C/3)}
#declare qHSL=function(H,S,L){select(L-1/2,L*(1+S),L+S-L*S)}
#declare pHSL=function(H,S,L){2*L-qHSL(H,S,L)}
#declare CHSL=function(H,S,L,C)
{
select(
-S
,//S>0
select(
tHSL(H,C)-1/6
,//tc<1/6
pHSL(H,S,L)+2*(qHSL(H,S,L)-L)*6*tHSL(H,C)
,
select(
tHSL(H,C)-1/2
,//tc<1/2
qHSL(H,S,L)
,
select(
tHSL(H,C)-2/3
,//tc<2/3
pHSL(H,S,L)+2*(qHSL(H,S,L)-L)*6*(2/3-tHSL(H,C))
,//esle
pHSL(H,S,L)
)
)
)
,//S=0
L
)
}
#declare RHSL=function (H,S,L){CHSL(H,S,L,+1)}
#declare GHSL=function (H,S,L){CHSL(H,S,L, 0)}
#declare BHSL=function (H,S,L){CHSL(H,S,L,-1)}
//END HSL to RGB
//HSV to RGB
#declare hHSV=function (H){floor(mod(H/60,6))}
#declare fHSV=function (H){H/60-hHSV(H)}
#declare pHSV=function (H,S,V){V*(1-S)}
#declare qHSV=function (H,S,V){V*(1-fHSV(H)*S)}
#declare tHSV=function (H,S,V){V*(1-(1-fHSV(H))*S)}
#declare RHSV=function (H,S,V)
{
select(hHSV(H)-0.5
,//0
V
,
select(hHSV(H)-1.5
,//1
qHSV(H,S,V)
,
select(hHSV(H)-2.5
,//2
pHSV(H,S,V)
,
select(hHSV(H)-3.5
,//3
pHSV(H,S,V)
,
select(hHSV(H)-4.5
,//4
tHSV(H,S,V)
,//5
V
)
)
)
)
)
}
#declare GHSV=function (H,S,V)
{
select(hHSV(H)-0.5
,//0
tHSV(H,S,V)
,
select(hHSV(H)-1.5
,//1
V
,
select(hHSV(H)-2.5
,//2
V
,
select(hHSV(H)-3.5
,//3
qHSV(H,S,V)
,//4,5
pHSV(H,S,V)
)
)
)
)
}
#declare BHSV=function (H,S,V)
{
select(hHSV(H)-0.5
,//0
pHSV(H,S,V)
,
select(hHSV(H)-1.5
,//1
pHSV(H,S,V)
,
select(hHSV(H)-2.5
,//2
tHSV(H,S,V)
,
select(hHSV(H)-3.5
,//3
V
,
select(hHSV(H)-4.5
,//4
V
,//5
qHSV(H,S,V)
)
)
)
)
)
}
//END HSV to RGB
//CONVERT HSV to XYZ (polar to caresian) for interpolation and back
#declare HSVX=function(H,S,V){sin(radians(H))*S}
#declare HSVY=function(H,S,V){cos(radians(H))*S}
#declare HSVZ=function(H,S,V){V}
#declare
XYZH=function(X,Y,Z){select(-sqrt(X*X+Y*Y),abs(degrees(acos(Y/sqrt(X*X+Y*Y)))-select(X,360,0)),0)}
#declare XYZS=function(X,Y,Z){sqrt(X*X+Y*Y)}
#declare XYZV=function(X,Y,Z){Z}
#declare HSLX=function(H,S,L){sin(radians(H))*S}
#declare HSLY=function(H,S,L){cos(radians(H))*S}
#declare HSLZ=function(H,S,L){L}
//H & S same as above
#declare XYZL=function(X,Y,Z){Z}
//END CONVERT HSV to XYZ
#declare INTRGB=function (PTA,PTB,K){PTA+(PTB-PTA)*K}
Post a reply to this message
|
![](/i/fill.gif) |
|
![](/i/fill.gif) |
Le Forgeron <jgr### [at] free fr> wrote:
> Le 30.11.2007 18:44, Trevor G Quayle nous fit lire :
>
> > I have also influded the function for converting HSV/HSL to XYZ and back
>
> Thanks, that's interesting.
> I trusted the povray macro for CRGB2HSV/CRGB2HSL and opposite for
> HSV/L <->RGB.
> XYZ opens an interesting path.
>
> --
> The superior man understands what is right;
> the inferior man understands what will sell.
> -- Confucius
The problem with the macro is that it can't be used in a function, which is what
I wanted.
Here is the pigment declaration for an HSV gradient:
#macro PIG2(RGB1,RGB2)//HSV gradient
#declare RA=RGB1.x;#declare GA=RGB1.y;#declare BA=RGB1.z;
#declare RB=RGB2.x;#declare GB=RGB2.y;#declare BB=RGB2.z;
average
pigment_map{
[function{
RHSV(
XYZH(
INTRGB(HSVX(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVX(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
,
INTRGB(HSVY(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVY(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
,
INTRGB(HSVZ(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVZ(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
)
,
XYZS(
INTRGB(HSVX(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVX(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
,
INTRGB(HSVY(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVY(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
,
INTRGB(HSVZ(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVZ(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
)
,
XYZV(
INTRGB(HSVX(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVX(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
,
INTRGB(HSVY(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVY(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
,
INTRGB(HSVZ(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVZ(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
)
)
} color_map{[0 rgb 0][1 rgb <1,0,0>]}]
[function{
GHSV(
XYZH(
INTRGB(HSVX(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVX(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
,
INTRGB(HSVY(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVY(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
,
INTRGB(HSVZ(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVZ(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
)
,
XYZS(
INTRGB(HSVX(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVX(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
,
INTRGB(HSVY(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVY(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
,
INTRGB(HSVZ(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVZ(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
)
,
XYZV(
INTRGB(HSVX(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVX(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
,
INTRGB(HSVY(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVY(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
,
INTRGB(HSVZ(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVZ(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
)
)
} color_map{[0 rgb 0][1 rgb <0,1,0>]}]
[function{
BHSV(
XYZH(
INTRGB(HSVX(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVX(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
,
INTRGB(HSVY(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVY(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
,
INTRGB(HSVZ(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVZ(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
)
,
XYZS(
INTRGB(HSVX(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVX(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
,
INTRGB(HSVY(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVY(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
,
INTRGB(HSVZ(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVZ(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
)
,
XYZV(
INTRGB(HSVX(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVX(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
,
INTRGB(HSVY(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVY(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
,
INTRGB(HSVZ(HHSV(RA,GA,BA),SHSV(RA,GA,BA),VHSV(RA,GA,BA)),HSVZ(HHSV(RB,GB,BB),SHSV(RB,GB,BB),VHSV(RB,GB,BB)),x)
)
)
} color_map{[0 rgb 0][1 rgb <0,0,1>]}]
}
#end
box{<0,0,0>,<1,0,1>
pigment{PIG2(COLA,COLB)}
finish{ambient 3 diffuse 0}
translate <-1/2,0,-1/2>
scale <LEN,1,WID/3*2>
translate z*WID/3*2
}
Post a reply to this message
|
![](/i/fill.gif) |