This is how I would do it in ConTeXt. I don't know if similar functionality is available in a LaTeX package. Basically, I do the calculations in lua and write the result inside a \startMPcode
.. \stopMPcode
environment.
\startluacode
require("math")
local sin = math.sin
local cos = math.cos
local pi = math.pi
local function scale(x)
return x .. " * 1cm"
end
local function pair(x,y)
return "(" .. scale(x) .. "," .. scale(y) .. ")"
end
local function point(f,x)
return pair(x, f(x))
end
userdata = userdata or {}
function userdata.draw_function(f, a, b, n)
local step = (b-a)/n
local path = {}
local i = 0
for x = a, b, step do
path[i] = point(f,x)
i = i + 1
end
path = table.concat(path, "--")
context("draw " .. path .. " withpen pencircle scaled 2bp;")
end
function userdata.draw_x_axis(from, to)
context(" drawarrow " .. pair(from,0) .. " -- " .. pair(to,0) .. "; ")
context(" label.rt ( btex $x$ etex , " .. pair(to,0) .. ") ;")
end
function userdata.draw_y_axis(from, to)
context(" drawarrow " .. pair(0, from) .. " -- " .. pair(0,to) .. "; ")
context(" label.top ( btex $y$ etex , " .. pair (0,to) .. ") ;")
end
function userdata.plot()
userdata.draw_x_axis(-2, 6.5)
userdata.draw_y_axis(-2.2, 2.2)
local f = function (x)
return sin(2*x) + cos(x)
end
userdata.draw_function(f, 0, 2*pi, 40)
end
\stopluacode
\starttext
\ctxlua
{context.startMPcode() ;
userdata.plot() ;
context.stopMPcode() ; }
\stoptext
However, this assumes that everything that is written inside teh userdata.plot()
function is MP code. If you also want that function to print stuff to the TeX stream, then you can store all the MP code inside a \startMPdrawing
and \stopMPdrawing
environment and retrieve them using \getMPdrawing
.
\startluacode
require("math")
local sin = math.sin
local cos = math.cos
local pi = math.pi
local function scale(x)
return x .. " * 1cm"
end
local function pair(x,y)
return "(" .. scale(x) .. "," .. scale(y) .. ")"
end
local function point(f,x)
return pair(x, f(x))
end
userdata = userdata or {}
function userdata.draw_function(f, a, b, n)
local step = (b-a)/n
local path = {}
local i = 0
for x = a, b, step do
path[i] = point(f,x)
i = i + 1
end
path = table.concat(path, "--")
context.startMPdrawing()
context("draw " .. path .. " withpen pencircle scaled 2bp;")
context.stopMPdrawing()
end
function userdata.draw_x_axis(from, to)
context.startMPdrawing()
context(" drawarrow " .. pair(from,0) .. " -- " .. pair(to,0) .. "; ")
context(" label.rt ( btex $x$ etex , " .. pair(to,0) .. ") ;")
context.stopMPdrawing()
end
function userdata.draw_y_axis(from, to)
context.startMPdrawing()
context(" drawarrow " .. pair(0, from) .. " -- " .. pair(0,to) .. "; ")
context(" label.top ( btex $y$ etex , " .. pair (0,to) .. ") ;")
context.stopMPdrawing()
end
function userdata.plot()
userdata.draw_x_axis(-2, 6.5)
userdata.draw_y_axis(-2.2, 2.2)
local f = function (x)
return sin(2*x) + cos(x)
end
userdata.draw_function(f, 0, 2*pi, 40)
end
\stopluacode
\starttext
\ctxlua
{ context.resetMPdrawing() ;
userdata.plot() ;
context.MPdrawingdonetrue() ;
context.getMPdrawing() ; }
\stoptext