Skip to main content
GameDev.net gamedev.net
🔒 Locked

Exact height value

Started by Christoph Jul 4, 2004 at 12:24 PM 6 replies 1.3k views
Original Post
Christoph
Christoph
Hi, I want to extract precise y values from a 256x256-Heightmap. For exaple, I need the interpolated value for 100,5|80,2. Is there any simple function which doesn't use square roots? Can you please post your algorithms? Thanks, Chris
C-Junkie
C-Junkie
How do you want to interpolate? linearly?
LilBudyWizer
LilBudyWizer
Looking at just the horizontal components draw a line through the point parallel to one side. Then find the height of each end of that line. Then find the height of the point. If you are t percent of the way from a to b then a linear interpolation is y=a+t*(b-a).
Keys to success: Ability, ambition and opportunity.
higherspeed
higherspeed
A simple mistake, but in the last post it's not t percent. The percentage ofcourse is 100*t.
hplus0603
hplus0603
You need some interpolator order. Linear or cubic are commonly used. Linear is very cheap, but looks pretty bad (all angles and sharp creases). Cubic is a little more expensive, but looks much better (soft and smooth). Cubic allows you to extract more detail by using multiple samples from within the same "cell" in the height field.

The trick is, as someone said, to first interpolate along the integer grid lines (say, integer X values), to get reference points along the other grid line (say, the Y line) to interpolate between.

For linear interpolation, the pseudo-code looks like so:

I(F,x,y) {  xi = floor(x);  yi = floor(y);  xt = x - xi;  yt = y - yi;  y0 = F[xi][yi]*(1-xt)+F[xi][yi+1]*xt;  y1 = F[xi+1][yi]*(1-xt)+F[xi+1][yi+1]*xt;  return y0*(1-yt)+y1*yt;}


For cubic, it looks something like (taken from some old terrain code I wrote):

    inline float hermite4( float frac, float * ptr )    {      const float    c     = (ptr[2] - ptr[0]) * 0.5f;      const float    v     = ptr[1] - ptr[2];      const float    w     = c + v;      const float    a     = w + v + (ptr[3] - ptr[1]) * 0.5f;      const float    b     = w + a;      return ((((a * frac) - b) * frac + c) * frac + ptr[1]);    }    static float do_sample( unsigned char const * data, uint pitch, uint x, uint z, float xp, float zp )    {      assert( xp < 1 && zp < 1 );      assert( xp >= 0 && zp >= 0 );      assert( x > 0 && z > 0 );      float xx[ 4 ];      float yy[ 4 ];      for( int iz = 0; iz < 4; ++iz ) {        unsigned char const * data2 = data + x - 1 + (iz + z - 1) * pitch;        for( int ix = 0; ix < 4; ++ix ) {          xx[ ix ] = data2[ ix ];        }        yy[ iz ] = hermite4( xp, xx );      }      float sv = (hermite4( zp, yy ) - 128.f) * (1.f / 128.f);      return sv;    }

enum Bool { True, False, FileNotFound };
LilBudyWizer
LilBudyWizer
No, 50% of the way from a to b in half way from a to b and not 50 times the distance from a to b.
Keys to success: Ability, ambition and opportunity.
justo
justo
he meant that, yes, half way would be 50%, but the value of t would be .5
Christoph
Christoph
Thank you guys. That helped! :-)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.