luametafun-shade.tex /size: 8670 b    last modification: 2025-02-21 11:03
1% language=us runpath=texruns:manuals/luametafun
2
3\environment luametafun-style
4
5\startcomponent luametafun-shade
6
7\startchapter[title={Shade}]
8
9\startsection[title={Shading operators}]
10
11{\em see \METAFUN\ manual.}
12
13\stopsection
14
15\startsection[title={Shading interface.}]
16
17{\em This interface is still experimental!}
18
19Shading is complex. We go from one color to another on a continuum either linear
20or circular. We have to make sure that we cover the whole shape and that means
21that we have to guess a little, although one can influence this with parameters.
22It can involve a bit of trial and error, which is more complex that using a
23graphical user interface but this is the price we pay. It goes like this:
24
25\startbuffer[1]
26\startMPcode
27definecolor [ name = "MyColor3", r = 0.22, g = 0.44, b = 0.66 ] ;
28definecolor [ name = "MyColor4", r = 0.66, g = 0.44, b = 0.22 ] ;
29
30draw lmt_shade [
31    path      = fullcircle scaled 4cm,
32    direction = "right",
33    domain    = { 0, 2 },
34    colors    = { "MyColor3", "MyColor4" },
35] ;
36
37draw lmt_shade [
38    path      = fullcircle scaled 3cm,
39    direction = "left",
40    domain    = { 0, 2 },
41    colors    = { "MyColor3", "MyColor4" },
42] shifted (45mm,0) ;
43
44draw lmt_shade [
45    path      = fullcircle scaled 5cm,
46    direction = "up",
47    domain    = { 0, 2 },
48    colors    = { "MyColor3", "MyColor4" },
49] shifted (95mm,0) ;
50
51draw lmt_shade [
52    path      = fullcircle scaled 1cm,
53    direction = "down",
54    domain    = { 0, 2 },
55    colors    = { "MyColor3", "MyColor4" },
56] shifted (135mm,0) ;
57\stopMPcode
58\stopbuffer
59
60\typebuffer[1][option=TEX]
61
62Normally this is good enough as demonstrated in \in {figure} [shade:1] because
63we use shades as backgrounds. In the case of a circular shade we need to tweak
64the domain because guessing doesn't work well.
65
66\startplacefigure[reference=shade:1,title={Simple circular shades.}]
67    \getbuffer[1]
68\stopplacefigure
69
70\startbuffer[2]
71\startMPcode
72draw lmt_shade [
73    path        = fullsquare scaled 4cm,
74    alternative = "linear",
75    direction   = "right",
76    colors      = { "MyColor3", "MyColor4" },
77] ;
78
79draw lmt_shade [
80    path        = fullsquare scaled 3cm,
81    direction   = "left",
82    alternative = "linear",
83    colors      = { "MyColor3", "MyColor4" },
84] shifted (45mm,0) ;
85
86draw lmt_shade [
87    path        = fullsquare scaled 5cm,
88    direction   = "up",
89    alternative = "linear",
90    colors      = { "MyColor3", "MyColor4" },
91] shifted (95mm,0) ;
92
93draw lmt_shade [
94    path        = fullsquare scaled 1cm,
95    direction   = "down",
96    alternative = "linear",
97    colors      = { "MyColor3", "MyColor4" },
98] shifted (135mm,0) ;
99\stopMPcode
100\stopbuffer
101
102\typebuffer[2][option=TEX]
103
104\startplacefigure[reference=shade:2,title={Simple rectangular shades.}]
105    \getbuffer[2]
106\stopplacefigure
107
108The \type {direction} relates to the boundingbox. Instead of a keyword you can
109also give two values, indicating points on the boundingbox. Because a boundingbox
110has four points, the \type {up} direction is equivalent to \type {{0.5,2.5}}.
111
112The parameters \type {center}, \type {factor}, \type {vector} and \type {domain}
113are a bit confusing but at some point the way they were implemented made sense,
114so we keep them as they are. The center moves the center of the path that is used
115as anchor for one color proportionally to the bounding box: the given factor is
116multiplied by half the width and height.
117
118\startbuffer[3]
119\startMPcode
120draw lmt_shade [
121    path      = fullcircle scaled 5cm,
122    domain    = { .2, 1.6 },
123    center    = { 1/10, 1/10 },
124    direction = "right",
125    colors    = { "MyColor3", "MyColor4" },
126    trace     = true,
127] ;
128\stopMPcode
129\stopbuffer
130
131\typebuffer[3][option=TEX]
132
133\startplacefigure[reference=shade:3,title={Moving the centers.}]
134    \getbuffer[3]
135\stopplacefigure
136
137A vector takes the given points on the path as centers for the colors, see \in
138{figure} [shade:4].
139
140\startbuffer[4]
141\startMPcode
142draw lmt_shade [
143    path      = fullcircle scaled 5cm,
144    domain    = { .2, 1.6 },
145    vector    = { 2, 4 },
146    direction = "right",
147    colors    = { "MyColor3", "MyColor4" },
148    trace     = true,
149] ;
150\stopMPcode
151\stopbuffer
152
153\typebuffer[4][option=TEX]
154
155\startplacefigure[reference=shade:4,title={Using a vector (points).}]
156    \getbuffer[4]
157\stopplacefigure
158
159Messing with the radius in combination with the previously mentioned domain
160is really trial and error, as seen in \in {figure} [shade:5].
161
162\startbuffer[5]
163\startMPcode
164draw lmt_shade [
165    path      = fullcircle scaled 5cm,
166    domain    = { 0.5, 2.5 },
167    radius    = { 2cm, 6cm },
168    direction = "right",
169    colors    = { "MyColor3", "MyColor4" },
170    trace     = true,
171] ;
172\stopMPcode
173\stopbuffer
174
175\typebuffer[5][option=TEX]
176
177\startplacefigure[reference=shade:5,title={Tweaking the radius.}]
178    \getbuffer[5]
179\stopplacefigure
180
181But actually the radius used alone works quite well as shown in \in {figure}
182[shade:6].
183
184\startbuffer[6]
185\startMPcode
186draw lmt_shade [
187    path        = fullcircle scaled 5cm,
188    colors      = { "red", "green" },
189    trace       = true,
190] ;
191
192draw lmt_shade [
193    path        = fullcircle scaled 5cm,
194    colors      = { "red", "green" },
195    radius      = 2.5cm,
196    trace       = true,
197] shifted (6cm,0) ;
198
199draw lmt_shade [
200    path        = fullcircle scaled 5cm,
201    colors      = { "red", "green" },
202    radius      = 2.0cm,
203    trace       = true,
204] shifted (12cm,0) ;
205\stopMPcode
206\stopbuffer
207
208\typebuffer[6][option=TEX]
209
210\startplacefigure[reference=shade:6,title={Just using the radius.}]
211    \getbuffer[6]
212\stopplacefigure
213
214\starttabulate[|T|T|T|p|]
215\FL
216\BC name         \BC type           \BC default      \BC comment \NC \NR
217\ML
218\NC alternative \NC string          \NC circular \NC or \type {linear} \NC \NR
219\NC path        \NC path            \NC          \NC \NC \NR
220\NC trace       \NC boolean         \NC false    \NC \NC \NR
221\NC domain      \NC set of numerics \NC          \NC \NC \NR
222\NC radius      \NC numeric         \NC          \NC \NC \NR
223\NC             \NC set of numerics \NC          \NC \NC \NR
224\NC factor      \NC numeric         \NC          \NC \NC \NR
225\NC origin      \NC pair            \NC          \NC \NC \NR
226\NC             \NC set of pairs    \NC          \NC \NC \NR
227\NC vector      \NC set of numerics \NC          \NC \NC \NR
228\NC colors      \NC set of strings  \NC          \NC \NC \NR
229\NC center      \NC numeric         \NC          \NC \NC \NR
230\NC             \NC set of numerics \NC          \NC \NC \NR
231\NC direction   \NC string          \NC          \NC \type{up}, \type {down}, \type {left}, \type {right} \NC \NR
232\NC             \NC set of numerics \NC          \NC two points on the boundingbox \NC \NR
233\LL
234\stoptabulate
235
236\stopsection
237
238\startsection[title=Patterns]
239
240\setupexternalfigure[location={default,global,local}]
241
242Instead using a shade one can use a pattern which is basically a fill with a repeated
243image. Here are some examples:
244
245\startbuffer
246\startMPcode
247draw
248    (
249        (fulldiamond xscaled 8cm yscaled 5cm randomizedcontrols 10mm) && reverse
250        (fulldiamond xscaled 6cm yscaled 3cm randomizedcontrols 10mm) && cycle
251    )
252    withpattern image (fill fullcircle scaled 2mm withcolor "darkyellow" ;)
253;
254\stopMPcode
255\stopbuffer
256
257\typebuffer[option=TEX]
258
259The \type {image} macro produces a picture that is then used for the filling:
260
261\startlinecorrection \getbuffer \stoplinecorrection
262
263That image can also be an (external) figure:
264
265\startbuffer
266\startMPcode
267draw
268    (
269        (fullcircle xscaled 8cm yscaled 4cm randomizedcontrols 5mm) && reverse
270        (fullcircle xscaled 6cm yscaled 2cm randomizedcontrols 5mm) && cycle
271    )
272    withpattern image (draw figure "hacker.jpg" ;)
273    withpatternscale (1/10,1/20)
274;
275\stopMPcode
276\stopbuffer
277
278Of course one needs to find a suitable image for this, but here we just use one of
279the test figures:
280
281\startlinecorrection \getbuffer \stoplinecorrection
282
283\typebuffer[option=TEX]
284
285\stopsection
286
287\startsection[title=Luminance]
288
289{\em Todo: groups and such.}
290
291\stopsection
292
293\stopchapter
294
295\stopcomponent
296
297%    fill unittriangle rotated 90 xyscaled (200,100)
298%        withshademethod "linear"
299%        withshadecenteronefraction (0,1)
300%        withshadecentertwofraction (0,0)
301%        withshadestep (
302%            withshadefraction 0
303%            withshadecolors (green, green)
304%        )
305%        withshadestep (
306%            withshadefraction 0.75
307%            withshadecolors (blue, green)
308%        )
309%        withshadestep (
310%            withshadefraction 0.25
311%            withshadecolors (green, blue)
312%        )
313%        withshadestep (
314%            withshadefraction 1
315%            withshadecolors (green, red)
316%        )
317%     ;
318