Module:CurveTable

local p = {}

-- Parses a string of the format `x,y` with numerical `x` and `y` into an array with named numbers `x` and `y`. function parsePoint(string) local stringArray = mw.text.split(string, ",")

local point = {} point["x"] = tonumber(stringArray[1]) point["y"] = tonumber(stringArray[2])

return point end

-- Interpolates (or extrapolates) the x-coordinate `c` based on points `a` and `b` function interpolate(a, b, c)   return a["y"] + (c - a["x"]) * (b["y"] - a["y"]) / (b["x"] - a["x"]) end

-- See documentation at Template:CurveTable. function p.evaluate(frame) local curveTable = mw.text.split(frame.args[1], " ") local target = tonumber(frame.args[2])

if #curveTable == 0 then -- Empty curve table return "Not enough points in curve table." elseif #curveTable == 1 then -- One point in curve table; interpret as horizontal line return parsePoint(curveTable[1])["y"] end

for i = 1, #curveTable, 1 do       local point = parsePoint(curveTable[i])

if target == point["x"] then -- No interpolation/extrapolation required return point["y"] elseif target < point["x"] then if i == 1 then -- Extrapolate from first two points in table return interpolate(parsePoint(curveTable[1]), parsePoint(curveTable[2]), target) else -- Interpolate between current and previous point return interpolate(parsePoint(curveTable[i - 1]), parsePoint(curveTable[i]), target) end end end

-- Target is after last point. Extrapolate from last two points in table return interpolate(parsePoint(curveTable[#curveTable - 1]), parsePoint(curveTable[#curveTable]), target) end

return p