Linear interpolation help

Started by
7 comments, last by Zahlman 15 years, 4 months ago
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?
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
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)

Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]

there is no need to have each point unique

values can (and should) repeat in cases like these
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 / 25end

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?
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! :)
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.
My current game project Platform RPG
Awesome! thanks a lot!
Try to consider how you might adapt this to your problem.

This topic is closed to new replies.

Advertisement