# Bilinear Interpollation

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

## Recommended Posts

Hi, I've written a function to find the height of a particle based on its position on a quad defined by 4 points. we know the xyz of all four points, and the xz of the point. Here's the code:
void GetTileHeight(float x, float z)
{
char buffer[200];
float heightO = Height(g_HeightMap, x, z );
float points[4][3];		//four vercies making up the patch
float ABDifference;		//Difference in height between AB and CD
float CDDifference;
int i;
double intx;			//integer parts of each coordinate
double intz;
float floatx;			//and float parts of each coordinate
float floatz;
float u,v;				//Represent ratio of tile the point is at (float between 1 and 0)
float interp1[2];		//stores the start and end height of the first interpollated line
float interp1Diff;		//difference in height between the two heights of the first interp
float Change;
float FinalPoint;		//the final y value of the equation

//Record the four points making up the patch as a set of coordinates

//Z
///C----D
///¦    ¦
///¦    ¦
///A----B
//////////X
//Point A (Bottom Left)
points[0][0] = x;
points[0][1] = Height(g_HeightMap, x, z );
points[0][2] = z;

//Point B (Bottom Right)
points[1][0] = x;
points[1][1] = Height(g_HeightMap, x, z + STEP_SIZE);
points[1][2] = z + STEP_SIZE;

//Point C (Top Left)
points[2][0] = x + STEP_SIZE;
points[2][1] = Height(g_HeightMap, x + STEP_SIZE, z );
points[2][2] = z;

//Point D (Top Right)
points[3][0] = x + STEP_SIZE;
points[3][1] = Height(g_HeightMap, x + STEP_SIZE, z + STEP_SIZE );
points[3][2] = z + STEP_SIZE;

//Now we find the position on the tile as an expression between 0.0 and 1.0 in the x and z

//Find the integer and float parts of the coordinates
floatx = modf(x, &intx);
floatz = modf(z, &intz);

//Shrink the intx variable down to being in terms of a single tile
while(intx>16)intx -= STEP_SIZE;
x = intx+floatx;  //Add to give the distance of the point from the origin of tile

//Ditto for z
while(intz>16)	intz -= STEP_SIZE;
z = intz+floatz;
u = x/STEP_SIZE;	//u and v are floats between 0.0 and 1.0 that define where the point is
v = z/STEP_SIZE;    //in terms of the width/height of the tile

//So now we find the difference in height between AB and CD

ABDifference = ( points[1][1] -  points[0][1]); //Change in y going from A to B
CDDifference = ( points[3][1] -  points[2][1]); //Change in y going from C to D

//Now we find the height at u by adding the starting point plus u* the difference
//this gives us a point along lines AB and CD.  We use the above method with v to
//find the height at point u,v

interp1[0] = points[0][1] + (ABDifference *= u);
interp1[1] = points[2][1] + (CDDifference *= u);

//This gives the change in height between the two interp1 points
interp1Diff = interp1[1] - interp1[0];

FinalPoint = interp1[0] + (interp1Diff *= v);
User->position[1] = FinalPoint;

I've followed the math through on paper and it looks sound, can anyone explain why this doesn't work?

##### Share on other sites
Have you tried stepping through the code line by line to see if you're getting correct values? The use of fmod and the accompanying code looks suspicious. I might try condensing all that into something like this:

u = (x - (int)(x / STEP_SIZE) * STEP_SIZE) / STEP_SIZE;
v = (z = (int)(z / STEP_SIZE) * STEP_SIZE) / STEP_SIZE;

The rest of code looks alright to me, so the problem could be somewhere else. Maybe the Height function isn't doing something right?

##### Share on other sites
I've done a run through with liberal message boxes....

Point 1:
5.76
124.0
40.759998

Point 2:
5.76
125.0
56.759998

Point 3:
21.76
118.0
40.759998

Point 4:
21.76
120.0
56.759998

Player Coords x, z = 5.76, 40.759998
xFloat = 0.76 xInt = 5
zFloat = 0.7998 zInt = 40

Coords in term of current tile: 5.76, 8.759998

U = 0.36, v = 0.5475

AB Diff = 1 CDDiff = 2

Interp1[0] = 124.36 Interp[1] = 118.72
interp1diff = -5.64

Final Point = 124.36 + (-5.64 * 0.5475)
= 121.2721