# [NTG-context] Implicit plots/level curves possible?

Alan Braslau braslau.list at comcast.net
Wed Oct 10 00:23:41 CEST 2018

On Mon, 8 Oct 2018 17:56:24 -0400 (EDT)

> 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