You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
444 lines
13 KiB
444 lines
13 KiB
% Copyright 2008 by Till Tantau and others
|
|
% CMYK and grayscale shadings adaptation copyright 2019 by David Purton
|
|
%
|
|
% This file may be distributed and/or modified
|
|
%
|
|
% 1. under the LaTeX Project Public License and/or
|
|
% 2. under the GNU Public License.
|
|
%
|
|
% See the file doc/generic/pgf/licenses/LICENSE for more details.
|
|
|
|
\ProvidesFileRCS{pgflibraryshadings.code.tex}
|
|
|
|
|
|
%
|
|
% An hsv color wheel. Initial code graciously donated by Ken Starks.
|
|
%
|
|
|
|
\pgfdeclarefunctionalshading[black]{color wheel white center}
|
|
{\pgfpoint{-50bp}{-50bp}}
|
|
{\pgfpoint{50bp}{50bp}}
|
|
{}
|
|
{ % x y
|
|
2 copy % ... x y x y
|
|
2 copy abs exch abs add 0.0001 ge
|
|
{atan 360.0 div} % ... x y heading; heading being in
|
|
%the interval [0, 1.0]
|
|
{ pop } % silently deal with error: return
|
|
% arbitrary heading of zero for origin
|
|
ifelse % because we will use it for 'Hue'
|
|
3 1 roll % ... heading x y
|
|
dup mul % ... heading x y*y
|
|
exch dup mul % ... heading y*y x*x
|
|
add sqrt % ... heading ra_pt (distance from origin in points)
|
|
25.0 div % scale it means a ra of 25bp
|
|
dup 1.0 ge % BOOLEAN. ready to clamp to interval [0, 1.0]
|
|
{ pop 1.0 }{} ifelse % We shall use the scaled ra as 'Saturation'
|
|
%2.5 mul 0.25 sub % now, Ra in [0.1, 0.5] --> Saturation
|
|
% in [0.0, 1.0]. Saturation varies between the two radii
|
|
1.0 % ... H S V ( with 'Value' set to literal constant of 1.0 )
|
|
% C version to use as model:
|
|
% H' = H * 6
|
|
% i = floor(H')
|
|
% f = H' - i
|
|
% P = V * (1.0 - S)
|
|
% Q = V * (1.0 - (S*f))
|
|
% T = V * (1.0 - (S * (1.0 - f)))
|
|
3 2 roll 6.0 mul dup 4 1 roll % H' S V H'
|
|
floor cvr % H' S V i
|
|
dup 5 1 roll % i H' S V i
|
|
3 index sub neg % i H' S V f
|
|
1.0 3 index sub % i H' S V f (1.0 - S )
|
|
2 index mul % i H' S V f P
|
|
6 1 roll % P i H' S V f
|
|
dup 3 index mul neg 1.0 add % P i H' S V f ( 1.0 - (f*S))
|
|
2 index mul % P i H' S V f Q
|
|
7 1 roll % Q P i H' S V f
|
|
neg 1.0 add % Q P i H' S V (1.0 - f)
|
|
2 index mul neg 1.0 add % Q P i H' S V (1.0 - S * (1.0 - f))
|
|
1 index mul % Q P i H' S V T
|
|
7 2 roll % V T Q P i H' S
|
|
pop pop % V T Q P i
|
|
%%%
|
|
% end of BLOCK B. The rest is just stack manipulation
|
|
dup 0.5 le % TEST II [ i == 0 ]
|
|
{ % BLOCK C [ take stack to V T P ]
|
|
pop exch pop
|
|
}
|
|
{ dup 1.5 le % TEST III [ i == 1 ]
|
|
{ % BLOCK D [ take stack to Q V P ]
|
|
pop exch 4 1 roll exch pop
|
|
}
|
|
{ dup 2.5 le % TEST IV [ i == 2 ]
|
|
{ % BLOCK E [ take stack to P V T ]
|
|
pop 4 1 roll pop
|
|
}
|
|
{ dup 3.5 le % TEST V [ i == 3 ]
|
|
{ % BLOCK F [ take stack to P Q V ]
|
|
pop exch 4 2 roll pop
|
|
}
|
|
{ dup 4.5 le % TEST VI [ i == 4 ]
|
|
{ % BLOCK G [ take stack to T P V ]
|
|
pop exch pop 3 -1 roll
|
|
}
|
|
{ % BLOCK H [ take stack to V P Q ]
|
|
pop 3 1 roll exch pop
|
|
}
|
|
ifelse
|
|
}
|
|
ifelse % for V
|
|
}
|
|
ifelse % for IV
|
|
}
|
|
ifelse % for III
|
|
}
|
|
ifelse % for II
|
|
\ifpgfshadingmodelcmyk
|
|
\pgffuncshadingrgbtocmyk
|
|
\fi
|
|
\ifpgfshadingmodelgray
|
|
\pgffuncshadingrgbtogray
|
|
\fi
|
|
}%
|
|
|
|
\pgfdeclarefunctionalshading[black]{color wheel black center}
|
|
{\pgfpoint{-50bp}{-50bp}}
|
|
{\pgfpoint{50bp}{50bp}}
|
|
{}
|
|
{ % x y
|
|
2 copy % ... x y x y
|
|
2 copy abs exch abs add 0.0001 ge
|
|
{atan 360.0 div} % ... x y heading; heading being in
|
|
%the interval [0, 1.0]
|
|
{ pop } % silently deal with error: return
|
|
% arbitrary heading of zero for origin
|
|
ifelse % because we will use it for 'Hue'
|
|
3 1 roll % ... heading x y
|
|
dup mul % ... heading x y*y
|
|
exch dup mul % ... heading y*y x*x
|
|
add sqrt % ... heading ra_pt (distance from origin in points)
|
|
25.0 div % scale it means a ra of 25bp
|
|
dup 1.0 ge % BOOLEAN. ready to clamp to interval [0, 1.0]
|
|
{ pop 1.0 }{} ifelse % We shall use the scaled ra as 'Saturation'
|
|
%2.5 mul 0.25 sub % now, Ra in [0.1, 0.5] --> Saturation
|
|
% in [0.0, 1.0]. Saturation varies between the two radii
|
|
1.0 exch % ... H S V ( with 'Value' set to literal constant of 1.0 )
|
|
% C version to use as model:
|
|
% H' = H * 6
|
|
% i = floor(H')
|
|
% f = H' - i
|
|
% P = V * (1.0 - S)
|
|
% Q = V * (1.0 - (S*f))
|
|
% T = V * (1.0 - (S * (1.0 - f)))
|
|
3 2 roll 6.0 mul dup 4 1 roll % H' S V H'
|
|
floor cvr % H' S V i
|
|
dup 5 1 roll % i H' S V i
|
|
3 index sub neg % i H' S V f
|
|
1.0 3 index sub % i H' S V f (1.0 - S )
|
|
2 index mul % i H' S V f P
|
|
6 1 roll % P i H' S V f
|
|
dup 3 index mul neg 1.0 add % P i H' S V f ( 1.0 - (f*S))
|
|
2 index mul % P i H' S V f Q
|
|
7 1 roll % Q P i H' S V f
|
|
neg 1.0 add % Q P i H' S V (1.0 - f)
|
|
2 index mul neg 1.0 add % Q P i H' S V (1.0 - S * (1.0 - f))
|
|
1 index mul % Q P i H' S V T
|
|
7 2 roll % V T Q P i H' S
|
|
pop pop % V T Q P i
|
|
%%%
|
|
% end of BLOCK B. The rest is just stack manipulation
|
|
dup 0.5 le % TEST II [ i == 0 ]
|
|
{ % BLOCK C [ take stack to V T P ]
|
|
pop exch pop
|
|
}
|
|
{ dup 1.5 le % TEST III [ i == 1 ]
|
|
{ % BLOCK D [ take stack to Q V P ]
|
|
pop exch 4 1 roll exch pop
|
|
}
|
|
{ dup 2.5 le % TEST IV [ i == 2 ]
|
|
{ % BLOCK E [ take stack to P V T ]
|
|
pop 4 1 roll pop
|
|
}
|
|
{ dup 3.5 le % TEST V [ i == 3 ]
|
|
{ % BLOCK F [ take stack to P Q V ]
|
|
pop exch 4 2 roll pop
|
|
}
|
|
{ dup 4.5 le % TEST VI [ i == 4 ]
|
|
{ % BLOCK G [ take stack to T P V ]
|
|
pop exch pop 3 -1 roll
|
|
}
|
|
{ % BLOCK H [ take stack to V P Q ]
|
|
pop 3 1 roll exch pop
|
|
}
|
|
ifelse
|
|
}
|
|
ifelse % for V
|
|
}
|
|
ifelse % for IV
|
|
}
|
|
ifelse % for III
|
|
}
|
|
ifelse % for II
|
|
\ifpgfshadingmodelcmyk
|
|
\pgffuncshadingrgbtocmyk
|
|
\fi
|
|
\ifpgfshadingmodelgray
|
|
\pgffuncshadingrgbtogray
|
|
\fi
|
|
}%
|
|
|
|
\pgfdeclarefunctionalshading[black]{color wheel}
|
|
{\pgfpoint{-50bp}{-50bp}}
|
|
{\pgfpoint{50bp}{50bp}}
|
|
{}
|
|
{ % x y
|
|
2 copy abs exch abs add 0.0001 ge
|
|
{atan 360.0 div} % ... x y heading; heading being in
|
|
%the interval [0, 1.0]
|
|
{ pop } % silently deal with error: return
|
|
% arbitrary heading of zero for origin
|
|
ifelse % because we will use it for 'Hue'
|
|
1.0 1.0 % ... H S V
|
|
% C version to use as model:
|
|
% H' = H * 6
|
|
% i = floor(H')
|
|
% f = H' - i
|
|
% P = V * (1.0 - S)
|
|
% Q = V * (1.0 - (S*f))
|
|
% T = V * (1.0 - (S * (1.0 - f)))
|
|
3 2 roll 6.0 mul dup 4 1 roll % H' S V H'
|
|
floor cvr % H' S V i
|
|
dup 5 1 roll % i H' S V i
|
|
3 index sub neg % i H' S V f
|
|
1.0 3 index sub % i H' S V f (1.0 - S )
|
|
2 index mul % i H' S V f P
|
|
6 1 roll % P i H' S V f
|
|
dup 3 index mul neg 1.0 add % P i H' S V f ( 1.0 - (f*S))
|
|
2 index mul % P i H' S V f Q
|
|
7 1 roll % Q P i H' S V f
|
|
neg 1.0 add % Q P i H' S V (1.0 - f)
|
|
2 index mul neg 1.0 add % Q P i H' S V (1.0 - S * (1.0 - f))
|
|
1 index mul % Q P i H' S V T
|
|
7 2 roll % V T Q P i H' S
|
|
pop pop % V T Q P i
|
|
%%%
|
|
% end of BLOCK B. The rest is just stack manipulation
|
|
dup 0.5 le % TEST II [ i == 0 ]
|
|
{ % BLOCK C [ take stack to V T P ]
|
|
pop exch pop
|
|
}
|
|
{ dup 1.5 le % TEST III [ i == 1 ]
|
|
{ % BLOCK D [ take stack to Q V P ]
|
|
pop exch 4 1 roll exch pop
|
|
}
|
|
{ dup 2.5 le % TEST IV [ i == 2 ]
|
|
{ % BLOCK E [ take stack to P V T ]
|
|
pop 4 1 roll pop
|
|
}
|
|
{ dup 3.5 le % TEST V [ i == 3 ]
|
|
{ % BLOCK F [ take stack to P Q V ]
|
|
pop exch 4 2 roll pop
|
|
}
|
|
{ dup 4.5 le % TEST VI [ i == 4 ]
|
|
{ % BLOCK G [ take stack to T P V ]
|
|
pop exch pop 3 -1 roll
|
|
}
|
|
{ % BLOCK H [ take stack to V P Q ]
|
|
pop 3 1 roll exch pop
|
|
}
|
|
ifelse
|
|
}
|
|
ifelse % for V
|
|
}
|
|
ifelse % for IV
|
|
}
|
|
ifelse % for III
|
|
}
|
|
ifelse % for II
|
|
\ifpgfshadingmodelcmyk
|
|
\pgffuncshadingrgbtocmyk
|
|
\fi
|
|
\ifpgfshadingmodelgray
|
|
\pgffuncshadingrgbtogray
|
|
\fi
|
|
}%
|
|
|
|
|
|
%
|
|
% A bilinear interpolation.
|
|
%
|
|
|
|
\colorlet{lower left}{white}%
|
|
\colorlet{lower right}{white}%
|
|
\colorlet{upper left}{white}%
|
|
\colorlet{upper right}{white}%
|
|
|
|
\pgfdeclarefunctionalshading[lower left,lower right,upper left,upper right]{bilinear interpolation}
|
|
{\pgfpointorigin}
|
|
{\pgfpoint{100bp}{100bp}}
|
|
{
|
|
\pgfshadecolortorgb{lower left}{\pgf@lib@shadings@ll}\pgfshadecolortorgb{lower right}{\pgf@lib@shadings@lr}
|
|
\pgfshadecolortorgb{upper right}{\pgf@lib@shadings@ur}\pgfshadecolortorgb{upper left}{\pgf@lib@shadings@ul}
|
|
}{
|
|
25 sub 50 div exch 25 sub 50 div 2 copy % Calculate y/100 x/100.
|
|
% 100 div exch 100 div 2 copy % Calculate y/100 x/100.
|
|
neg 1 add exch neg 1 add % Calculate 1-y/100 1-x/100.
|
|
3 1 roll 2 copy exch 5 2 roll 6 copy 6 copy % Set up stack.
|
|
\pgf@lib@shadings@llred mul exch \pgf@lib@shadings@lrred mul add mul % Process red component.
|
|
4 1 roll
|
|
\pgf@lib@shadings@urred mul exch \pgf@lib@shadings@ulred mul add mul
|
|
add
|
|
13 1 roll
|
|
\pgf@lib@shadings@llgreen mul exch \pgf@lib@shadings@lrgreen mul add mul % Process green component.
|
|
4 1 roll
|
|
\pgf@lib@shadings@urgreen mul exch \pgf@lib@shadings@ulgreen mul add mul
|
|
add
|
|
7 1 roll
|
|
\pgf@lib@shadings@llblue mul exch \pgf@lib@shadings@lrblue mul add mul % Process blue component.
|
|
4 1 roll
|
|
\pgf@lib@shadings@urblue mul exch \pgf@lib@shadings@ulblue mul add mul
|
|
add
|
|
\ifpgfshadingmodelcmyk
|
|
\pgffuncshadingrgbtocmyk
|
|
\fi
|
|
\ifpgfshadingmodelgray
|
|
\pgffuncshadingrgbtogray
|
|
\fi
|
|
}%
|
|
|
|
|
|
%
|
|
% A Mandelbrot set shading. Just for fun...
|
|
%
|
|
|
|
\pgfdeclarefunctionalshading[black]{Mandelbrot set}
|
|
{\pgfpoint{-50bp}{-50bp}}
|
|
{\pgfpoint{50bp}{50bp}}{}
|
|
{
|
|
12.5 div exch 12.5 div exch
|
|
1 index 1 index
|
|
% Stack: c_r c_i z_r z_i
|
|
% Formula: z' = z^2 + c = (z_r + i z_i)^2 + c_r + i c_i
|
|
% = (z_r^2 - z_i^2 + c_r) + i (2 z_r z_i + c_i)
|
|
%
|
|
% First iteration
|
|
% 1. Compute z_r^2 -z_i^2 + c_r
|
|
1 index dup mul % z_r^2
|
|
1 index dup mul % z_i^2
|
|
sub % z_r^2 - z_i^2
|
|
4 index add % z_r^2 -z_i^2 + c_r
|
|
% 2. Compute 2 z_r z_i + c_i
|
|
3 1 roll
|
|
mul 2 mul % 2 z_r z_i
|
|
2 index add % 2 z_r z_i + c_i
|
|
% Second iteration
|
|
% 1. Compute z_r^2 -z_i^2 + c_r
|
|
1 index dup mul % z_r^2
|
|
1 index dup mul % z_i^2
|
|
sub % z_r^2 - z_i^2
|
|
4 index add % z_r^2 -z_i^2 + c_r
|
|
% 2. Compute 2 z_r z_i + c_i
|
|
3 1 roll
|
|
mul 2 mul % 2 z_r z_i
|
|
2 index add % 2 z_r z_i + c_i
|
|
% Third iteration
|
|
% 1. Compute z_r^2 -z_i^2 + c_r
|
|
1 index dup mul % z_r^2
|
|
1 index dup mul % z_i^2
|
|
sub % z_r^2 - z_i^2
|
|
4 index add % z_r^2 -z_i^2 + c_r
|
|
% 2. Compute 2 z_r z_i + c_i
|
|
3 1 roll
|
|
mul 2 mul % 2 z_r z_i
|
|
2 index add % 2 z_r z_i + c_i
|
|
% Fourth iteration
|
|
% 1. Compute z_r^2 -z_i^2 + c_r
|
|
1 index dup mul % z_r^2
|
|
1 index dup mul % z_i^2
|
|
sub % z_r^2 - z_i^2
|
|
4 index add % z_r^2 -z_i^2 + c_r
|
|
% 2. Compute 2 z_r z_i + c_i
|
|
3 1 roll
|
|
mul 2 mul % 2 z_r z_i
|
|
2 index add % 2 z_r z_i + c_i
|
|
% Check for break (to avoid too large numbers)
|
|
1 index dup mul 1 index dup mul add
|
|
4 lt {
|
|
% Fifth iteration
|
|
% 1. Compute z_r^2 -z_i^2 + c_r
|
|
1 index dup mul % z_r^2
|
|
1 index dup mul % z_i^2
|
|
sub % z_r^2 - z_i^2
|
|
4 index add % z_r^2 -z_i^2 + c_r
|
|
% 2. Compute 2 z_r z_i + c_i
|
|
3 1 roll
|
|
mul 2 mul % 2 z_r z_i
|
|
2 index add % 2 z_r z_i + c_i
|
|
% Sixth iteration
|
|
% 1. Compute z_r^2 -z_i^2 + c_r
|
|
1 index dup mul % z_r^2
|
|
1 index dup mul % z_i^2
|
|
sub % z_r^2 - z_i^2
|
|
4 index add % z_r^2 -z_i^2 + c_r
|
|
% 2. Compute 2 z_r z_i + c_i
|
|
3 1 roll
|
|
mul 2 mul % 2 z_r z_i
|
|
2 index add % 2 z_r z_i + c_i
|
|
% Seventh iteration
|
|
% 1. Compute z_r^2 -z_i^2 + c_r
|
|
1 index dup mul % z_r^2
|
|
1 index dup mul % z_i^2
|
|
sub % z_r^2 - z_i^2
|
|
4 index add % z_r^2 -z_i^2 + c_r
|
|
% 2. Compute 2 z_r z_i + c_i
|
|
3 1 roll
|
|
mul 2 mul % 2 z_r z_i
|
|
2 index add % 2 z_r z_i + c_i
|
|
% Check for break (to avoid too large numbers)
|
|
1 index dup mul 1 index dup mul add
|
|
4 lt {
|
|
% Eighth iteration
|
|
% 1. Compute z_r^2 -z_i^2 + c_r
|
|
1 index dup mul % z_r^2
|
|
1 index dup mul % z_i^2
|
|
sub % z_r^2 - z_i^2
|
|
4 index add % z_r^2 -z_i^2 + c_r
|
|
% 2. Compute 2 z_r z_i + c_i
|
|
3 1 roll
|
|
mul 2 mul % 2 z_r z_i
|
|
2 index add % 2 z_r z_i + c_i
|
|
% Ninth iteration
|
|
% 1. Compute z_r^2 -z_i^2 + c_r
|
|
1 index dup mul % z_r^2
|
|
1 index dup mul % z_i^2
|
|
sub % z_r^2 - z_i^2
|
|
4 index add % z_r^2 -z_i^2 + c_r
|
|
% 2. Compute 2 z_r z_i + c_i
|
|
3 1 roll
|
|
mul 2 mul % 2 z_r z_i
|
|
2 index add % 2 z_r z_i + c_i
|
|
% Tenth iteration
|
|
% 1. Compute z_r^2 -z_i^2 + c_r
|
|
1 index dup mul % z_r^2
|
|
1 index dup mul % z_i^2
|
|
sub % z_r^2 - z_i^2
|
|
4 index add % z_r^2 -z_i^2 + c_r
|
|
% 2. Compute 2 z_r z_i + c_i
|
|
3 1 roll
|
|
mul 2 mul % 2 z_r z_i
|
|
2 index add % 2 z_r z_i + c_i
|
|
} { pop pop 1000.0 1000.0 } ifelse
|
|
} { pop pop 1000.0 1000.0 } ifelse
|
|
% Compute distance
|
|
dup mul exch
|
|
dup mul
|
|
add sqrt
|
|
dup 4 1 roll
|
|
2 gt { pop pop 2.0 exch div 1.0 exch sub dup dup} {pop pop pop 0.0 0.0 0.0} ifelse
|
|
\ifpgfshadingmodelcmyk
|
|
\pgffuncshadingrgbtocmyk
|
|
\fi
|
|
\ifpgfshadingmodelgray
|
|
\pgffuncshadingrgbtogray
|
|
\fi
|
|
}%
|
|
|