Linear interpolation help
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?
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
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 EvilNandoWell, 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:
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.
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)
there is no need to have each point unique
values can (and should) repeat in cases like these
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:
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:
You mentioned your resulting data was wrong. What was wrong with it?
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! :)
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.
This version will also have the interpolated points as part of the end points. (see below)
If you absolutely need to keep them as int use fixed point.
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.
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.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement