On Mon, 8 Oct 2018 17:56:24 -0400 (EDT)
Aditya Mahajan
Here is a proof of concept implementation in Lua + MP so that you can use:
\ContourPlot [ function=2*x^5 + x*y + y^5, x={0, 2}, y={-2, 0.5}, n=1000, % Number of discretization points ]
The code is fairly fast. But be careful. As with all ConTeXt key-value assignment, `x = { ...}` is different from `x={...}`. I am being a bit lazy here, and haven't adapted the metapost code to draw the axes to adapt to the function.
Hans and I played with Aditya's demonstration, to complete the example. It demonstrates some fun lua+MP+ConTeXt tricks: Alan \startluacode userdata = userdata or { } userdata.contour = { } userdata.xlim = { 0, 0 } userdata.ylim = { 0, 0 } function userdata.contourplot(f, xlim, ylim, length, ef) local xmin, xmax = xlim[1], xlim[2] local ymin, ymax = ylim[1], ylim[2] local t = { } local n = 0 for x = xmin, xmax, (xmax - xmin)/length do for y = ymin, ymax, (ymax - ymin)/length do local e = ef(x,y) local z = f(x,y) if z < e and z > -e then n = n + 1 t[n] = { x, y } end end end userdata.xlim = xlim userdata.ylim = ylim userdata.contour = t end function mp.ContourPath() mp.path(userdata.contour) end function mp.ContourX() mp.pair(userdata.xlim) end function mp.ContourY() mp.pair(userdata.ylim) end \stopluacode \startuseMPgraphic{doublefun::ContourPlot}{width} save xmin, xmax, ymin, ymax ; (xmin, xmax) = lua.mp.ContourX() ; (ymin, ymax) = lua.mp.ContourY() ; draw lua.mp.ContourPath() withpen pencircle scaled ((xmax-xmin)/200) ; setbounds currentpicture to boundingbox ((xmin,ymin)--(xmax,ymax)); currentpicture := currentpicture xsized \MPvar{width} ; save pic ; picture pic ; pic := currentpicture ; drawarrow llcorner pic--lrcorner pic ; drawarrow llcorner pic--ulcorner pic ; label.rt ("$x$", lrcorner pic) ; label.top("$y$", ulcorner pic) ; label.bot(decimal xmin,llcorner pic) ; label.bot(decimal xmax,lrcorner pic) ; label.lft(decimal ymin,llcorner pic) ; label.lft(decimal ymax,ulcorner pic) ; \stopuseMPgraphic \unexpanded\def\ContourPlot {\dosingleempty\doContourPlot} \def\doContourPlot[#1]% {\setvariables [ContourPlot] [x={0,0}, y={0,0}, w=10cm, n=1000, e=1e-2, #1]% \ctxlua{userdata.contourplot( function(x,y) return \getvariable{ContourPlot}{function} end, {\getvariable{ContourPlot}{x}},{\getvariable{ContourPlot}{y}}, \getvariable{ContourPlot}{n}, function(x,y) return \getvariable{ContourPlot}{e} end )}% \useMPgraphic{doublefun::ContourPlot}{width=\getvariable{ContourPlot}{w}}} \starttext \ContourPlot [function={2*x^5 + x*y + y^5}, x={0,2},y={-2,0.5}, n=1000,e={x/1000},w=5cm] \stoptext