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.
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], settings[max]) else -- return nil if outside of range if input < settings[r] or input > settings[max] then return nil end end while r < max do -- check for applicable row if input > settings[r+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