Four points and some point in the middle, need weighted average

Started by
6 comments, last by PlasmicSoup 17 years, 5 months ago
-plasmicsoup
Advertisement
f(s,t) = a00st + a01s(1-t) + a10(1-s)t + a11(1-s)(1-t)
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
Centroid
.
Whoa! Thanks guys/gals... obviously my post didn't go through (I really did have a long and descriptive post!) but you helped anyway, how generous :-)

Note to future posters: Have a specific topic! It helps!
-plasmicsoup
Actually, I spoke to soon.... that isn't what I needed! :-X... I keep trying to post some code but the forums keep acting up (see my initial post -_-)... so I'll try again.

I have a 2d character walking along a 3d curvy terrain, with lookup z values that approximate the height of the curvy terrain in an evenly spaced (by x and y position) grid. Right now, as the character moves, I round the x and y position to the nearest point on the lookup grid and use that height... obviously making for some jolty movement in the z axis. I need figure out a way to move the player smoothly along, by averaging the surrounding points in the grid, based on where the player is between those points. Any thoughts?

Thank you!
-plasmicsoup
Couple of questions:

1. What do you mean by the character being 2D? From your description it sounds like the environment is 3D.

2. What you describe sounds like a heightmap. How is it rendered? Is it just two triangles for each set of 4 gridpoints, or is the heightmap 'smoothed out' in some way?

At this point I'm guessing that you're asking how to find the height associated with a point on a heightmap (i.e. terrain). If this is the case, you can find the triangle directly under the point using some simiple math, and then use either barycentric coordinates or ray-plane intersection to find the height corresponding to the point.
The first question is whether you want the height reading to perfectly map what your renderer will do, or whether a "close enough" value will be good enough.

If you want to perfectly match the renderer, you need to turn the height map into triangles in exactly the same way as the renderer does (which needs some careful study if you render with quads). Then do a collision test against the two triangles in the quad containing the player, along the gravity normal, to find the height.

If you want to be good enough, the first answer to your question is very close to what you need.

Assuming you have samples s00, s01, s10 and s11, where s00 is sample at h[y][x], s01 is sample at h[y][x+1], ... for integer x, y, and dx = xp - x and dy = yp - y, where x and y are still integer, and xp,yp is the floating point position, and the height field is quantized to one sample per coordinate. Then you can find a position average by linearly interpolating across two edges, and then linearly interpolating between those two points:

z1 = s00 * (1-dy) + s10 * dy;
z2 = s01 * (1-dy) + s11 * dy;
z3 = z1 * (1-dx) + z2 * dx;

In this code, z3 is the final output value.

If you have one sample at a grid spacing other than 1, you will have to divide xp and yp by your grid spacing (and offset by the heightfield origin) before calculating x, y, dx and dy.
enum Bool { True, False, FileNotFound };
Good enough is exactly what I need, and your explanation worked wonders! Thank you so much for your help!

(In the meantime I did think of an approximation that did work but is even more of an approximation, ontop of an approximation ^_^... what I did was find the center of the surrounding points (with integer x,y), which divides the square into 4 quadrants around the center... I then found which quadrant the floating point x,y's were in, and then setup a new square around those, subdividing the grid/averaging new height values for those new points each time, until the center was within x distance from the player... works! But yours is much better :-)... thanks again!)
-plasmicsoup

This topic is closed to new replies.

Advertisement