On 1/9/2025 10:44 PM, Florent Michel wrote:
Hi,
I was trying to see if I could use MetaFun / MetaPost as my main tool
for generating figures. I really like its close integration with
ConTeXt, speed, and expressivity making it, even for a beginner like me,
a pleasure to work with.
One difficulty I encountered is for generating 2D functional shadings.
For instance, I am not sure what is the best way to reproduce the
following pgfplots picture in MetaPost:
____________________________________________________________
\usemodule[pgfplots]
\pgfplotsset{width=10cm,compat=1.18}
\usepgfplotslibrary{patchplots}
\starttext
\startTEXpage
\starttikzpicture
\startaxis[
hide axis=true,
axis lines=none,hide axis,
enlargelimits=false,
scale only axis,
clip bounding box=upper bound,
clip=true,
]
\addplot[
patch,
shader=interp,
mesh/color input=explicit,
data cs=polar,
]
coordinates {
(90,4) [color=red]
(210,4) [color=green]
(-30,4) [color=blue]
};
\stopaxis
\stoptikzpicture
\stopTEXpage
\stoptext
____________________________________________________________
One idea is to draw a sequence of triangles, each with a linear gradient:
____________________________________________________________
\startMPpage
def LinearIntTriangle(expr pa, pb, pc, cola, colb, colc, n_iter) =
for i = n_iter step -1 until 1 :
path p;
x := i / n_iter;
y := (i - 0.5) / n_iter;
p := pa -- (pa + x * (pb - pa)) -- (pa + x * (pc - pa)) -- cycle;
sh := define_linear_shade(pa + y * (pb - pa), pa + y * (pc - pa),
(1 - y) * cola + y * colb, (1 - y) *
cola + y * colc);
fill p withshade sh;
endfor
enddef;
color cola, colb, colc;
cola := (0,1,0);
colb := (1,0,0);
colc := (0,0,1);
LinearIntTriangle((0,0), (50,50*(3**0.5)), (100,0), cola, colb, colc,
30);
\stopMPpage
____________________________________________________________
or to use a slight variation (decomposing the triangle in three so that
the color is ‘right’) along each edge:
____________________________________________________________
\startMPpage
def LinearIntTriangleB(expr pa, pb, pc, cola, colb, colc, n_iter) =
color centre_color;
centre_color := (cola + colb + colc) / 3;
LinearIntTriangle((pa + pb + pc) / 3, pa, pb, centre_color, cola,
colb, n_iter);
LinearIntTriangle((pa + pb + pc) / 3, pb, pc, centre_color, colb,
colc, n_iter);
LinearIntTriangle((pa + pb + pc) / 3, pc, pa, centre_color, colc,
cola, n_iter);
enddef;
color cola, colb, colc;
cola := (0,1,0);
colb := (1,0,0);
colc := (0,0,1);
LinearIntTriangleB((0,0), (50,50*(3**0.5)), (100,0), cola, colb,
colc, 10);
\stopMPpage
____________________________________________________________
This approach gives ‘good enough’ results for large values of n_iter.
However, the size of the generated pdf is somewhat larger than the
pgfplots version: for instance, the first version above generates a 5KiB
pdf versus 3.8KiB for the pgfplots version, while being somewhat less
accurate. Increasing n_iter to 100 gives a result which is (to my not-
very-good eyes) very close to the pgfplots version but the pdf size
increases to about 20KiB, and takes significantly longer to render using
MuPDF.
I'd be grateful if someone could point me to a better way to generate
such shadings in MetaFun / MetaPost.
these things can often be found in the test suite
\startMPpage
fill unittriangle rotated 90 xyscaled (200,100)
withshademethod "linear"
withshadecenteronefraction (0,1)
withshadecentertwofraction (0,0)
withshadestep (
withshadefraction 0
withshadecolors (green, green)
)
withshadestep (
withshadefraction 0.75
withshadecolors (blue, green)
)
withshadestep (
withshadefraction 0.25
withshadecolors (green, blue)
)
withshadestep (
withshadefraction 1
withshadecolors (green, red)
)
;
\stopMPpage
-----------------------------------------------------------------
Hans Hagen | PRAGMA ADE
Ridderstraat 27 | 8061 GH Hasselt | The Netherlands
tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl
-----------------------------------------------------------------
___________________________________________________________________________________
If your question is of interest to others as well, please add an entry to the
Wiki!
maillist : ntg-context@ntg.nl /
https://mailman.ntg.nl/mailman3/lists/ntg-context.ntg.nl
webpage : https://www.pragma-ade.nl / https://context.aanhet.net (mirror)
archive : https://github.com/contextgarden/context
wiki : https://wiki.contextgarden.net
___________________________________________________________________________________