• Advertisement
Sign in to follow this  

Linear interpolation help

This topic is 3339 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Im trying to figure out how to calculate mid-values between two numbers point A: 0 point B: 10 the number of points to calculate are 25 my problem is that I need these points to be of an Int32 type, I tried calculating an increment amount by dividing the end value by the number of points needed but this gives me wrong data. Any ideas on how to approach this?

Share this post


Link to post
Share on other sites
Advertisement
int32 means whole numbers. there are not 25 whole (integer) numbers between 0 and 10 (there are 9 not counting 0 and 10). Use a float

If you're really bound by int32, I suppose you could also make 0 == 0 and 10 == 1000 and treat the 2 least significant digits as decimal points (thus, 1.5 would become 150, 2.3 -> 230, etc).

-me

Share this post


Link to post
Share on other sites
Quote:
Original post by EvilNando
Im trying to figure out how to calculate mid-values between two numbers

point A: 0
point B: 10

the number of points to calculate are 25. my problem is that I need these points to be of an Int32 type.
Well, an obvious problem is that there are not 25 unique integers between 0 and 10, instead there are only 9. Something like this might do the trick:
def interpolate(points, start, end, count):
diff = end - start # take the difference
if count > diff: # clamp the count to the distance
count = diff
step = diff / count # calculate a step increment

for i in range(count): # loop over count
start += step # generate point
points.append(start)

Share this post


Link to post
Share on other sites
Well I'm not exactly sure of how you want to divide the 25 numbers in that range, but wouldn't integer arithmetic suffice?
Something along the lines of:

for i from 1 to 25 do
midpoint := 0 + 10 * i / 25
end

Note that this is uses integer division, which usually rounds the result down to the nearest integer. This means you will get more low numbers and only one 10. Sticking to integer division, a way to make this a little better would be something like:

midpoint := 0 + ((10 * i) + 25 / 2) / 25

You mentioned your resulting data was wrong. What was wrong with it?

Share this post


Link to post
Share on other sites
nevermind got it working

A : 0;
B : 10;

numpoints = 25;

increment = B - A / numpoints;

for (numpoints)
point = (Int32)(A + increment * idx);

thank you for the ideas! :)

Share this post


Link to post
Share on other sites
I would just interpolate with floats, then cast them to integers.


double inc = (pointB - pointA) / pointCount;

double currentPoint = pointA;
for (int i = 0; i <= pointCount, currentPoint += inc; i++)
{
int point = (int)floor(currentPoint + 0.5); // round to the nearest int
// store the point or use it, whatever you need to do here
}


This version will also have the interpolated points as part of the end points. (see below)

Point A Point B
. .
. . . . . . . . <- interpolated points



If you absolutely need to keep them as int use fixed point.


int inc = ((pointB - pointA) << 16) / pointCount;

int currentPoint = pointA << 16;
for (int i = 0; i <= pointCount, currentPoint += inc; i++)
{
int point = (currentPoint + 0x8000) >> 16; // round to the nearest int
// store the point or use it, whatever you need to do here
}



As long as the pointA and pointB don't exceed 65535 and pointCount doesn't get close to that same number this should work fairly well. If you will reach those numbers you will have to change the integers to long longs, double the 16s to 32s and change 0x8000 to 0x80000000. Unless you are looking to squeeze out extra speed because this is a critical routine, I would just go with the float version.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement