ntg-context - mailing list for ConTeXt users
 help / color / mirror / Atom feed
From: Hans Hagen <j.hagen@xs4all.nl>
To: Florent Michel <florent.m42@gmail.com>,
	mailing list for ConTeXt users <ntg-context@ntg.nl>
Subject: [NTG-context] Re: Functional shading with MetaPost / MetaFun
Date: Fri, 10 Jan 2025 01:17:35 +0100	[thread overview]
Message-ID: <868b0721-4789-4361-8b77-2b0c6ba4b270@xs4all.nl> (raw)
In-Reply-To: <CALOhoe+573GiRWTpC=iLC2Se_cDidfRaz4jvAtudxvr-VTrwzg@mail.gmail.com>

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
___________________________________________________________________________________

  reply	other threads:[~2025-01-10  0:19 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-01-09 21:44 [NTG-context] " Florent Michel
2025-01-10  0:17 ` Hans Hagen [this message]
2025-01-10  7:17   ` [NTG-context] " Florent Michel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=868b0721-4789-4361-8b77-2b0c6ba4b270@xs4all.nl \
    --to=j.hagen@xs4all.nl \
    --cc=florent.m42@gmail.com \
    --cc=ntg-context@ntg.nl \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).