As I prefer receiving the boundary values for such cases I did my own interpolate function (see code below). I expected it to be a slower than the original because it does not remember previous values. So I did some measurements. To my surprise it was twice as fast, with random values almost tree times as fast (Performance measured once with 2^26 sequential values and once with 2^26 random values)
So i decidedd to give it away for free. I also added compatibility with the original function.
Usage:
value = interpolate_linear(settings, value, cap)
With the optional third (boolean) argument "cap" set to 'true', it provides the boundary values, without the third argument it provides nil for out of range values.
Code: Select all
function interpolate_linear(settings, value, cap)
local r = 1 -- start with first row
local max = #settings -- last row
local input = value
if cap then -- limit value to settings range
input = var_cap(value, settings[r][1], settings[max][1])
else -- return nil if outside of range
if input < settings[r][1] or input > settings[max][1] then
return nil
end
end
while r < max do -- check for applicable row
if input > settings[r+1][1] then -- check next row
r = r+1
else -- applicable row found
break
end
end
x0, y0 = table.unpack(settings[r])
x1, y1 = table.unpack(settings[r+1])
return y0 + (input - x0) * (y1 - y0)/(x1 - x0)
end
Paul