Multivariate interpolation error in GML

154 views Asked by At

everybody. I am using Game Maker, a program with syntax somewhat similar to Python (aside from spacing) to implement interpolation between multiple data values, as described here. Imagine a scatterplot with x = 0 at the origin and x = 100 at the end, with equal spacing between each data value. The x-positions are constant, but the y-positions may have any value. If lines were connected between each data point, then ideally, a script would be able to find the y for a given x-position. Here was my original implementation:

// This is executed once.

nums = 3; // the number of values to interpolate between
t = 0; // the position along the "scatterplot" of values

// Values may be decimals with any sign.  There should be values >= nums.
ind[0] = 100;
ind[1] = 0;
ind[2] = 100;

//This is executed each step.

intervals = 100 / (nums - 1);
index = round(percent / intervals);
if percent != 0 {newpercent=  (intervals / (percent - index)) / 100;}
else {newpercent = 0;}
newval = ind[index] * (1 - newpercent) + ind[index + 1] * newpercent;

This should've used a lerp() after finding which two points surround the given x-position to return an interpolation between their two values, but it didn't, so my question is:
What went wrong and how could I fix it? Thanks in advance.

Edit: Here is the finished and working code:

// This is executed once.

nums = 3; // the number of values to interpolate between
t = 0; // the position along the "scatterplot" of values

// Values may be decimals with any sign.  There should be values >= nums.
ind[0] = 100;
ind[1] = 0;
ind[2] = 100;

// This is executed each step; setting the result to 'alpha'.

if (nums > 1) {
    if (t != 1) {
        _temp1 = 1 / (nums - 1);
        _temp2 = floor(t / _temp1);
        _temp3 = (t - (_temp1 * _temp2)) * (nums - 1);
        alpha = ind[_temp2] + _temp3 * (ind[_temp2 + 1] - ind[_temp2]);
    }
    else {
        alpha = ind[nums - 1];
    }
}
1

There are 1 answers

3
Simon On BEST ANSWER

What you want to do is interpolate the value of property of your game (sound volume, danger level, gravity etc.) let's call the variable you want to caluculate y as some other property changes (like time, x-position etc.) let's call it t.

We have n points where we know the value of y. Let's call each of these points p0, p1 ... pn-1 where each number is the index of that point. Lets call the values in these points y0, y1 ... yn-1. So for any given value of t we want to do the following:

First we find the two points closest to t. Since all points are evenly spaced out we know that the value of t for a given point is t = index/(n-1) and by reordering this equation we can get the "index" of any given t like this index = t*(n-1). When t isn't exactly in the same position as one of our points it's going to be a number in between the index values of the two closest points pk and pk1. So pk = floor(index) gets you the index previous to your t and pk1 = pk + 1 is the next point.

Then we have to find out how close t is to each of these two points (value between 0 and 1) as that determines how much influence the value from each point will get in out interpolation. Let's call this measurement alpha. Then alpha = (t - pk)/(pk1 - pk).

Finally if pk and pk1 have values yk and yk1 you get your interpolated value y like this

y = (1-alpha)*yk + alpha*yk1;