注册 | 登录 忘记密码? 51cto首页 | 博客 | 论坛 | 招聘
热点文章 企鹅咬死珊瑚虫,窗口夹烂..
 帮助

地形高度算法小结


2007-03-25 12:53:35
 标签:算法 地形高度   [推送到技术圈]

版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://xiaoxiang.blog.51cto.com/88051/21443
地形一般是用网格再从高度图里读取每个顶点的高度来生成。若进一步,想实现摄像机在地形上行走的效果,就需要算出地形上任意一点的高度。总结了3个方法:
 
一:
《Introduction to 3D Game Programming With Directx 9.0》这本书里介绍的,利用向量来算。
 
http://xiaoxiang.blog.51cto.com/

float Terrain::GetHeight(float x, float z)
{
  // Translate on xz-plane by the transformation that takes
 // the terrain START point to the origin.

 x = ((float)_width / 2.0f) + x;
 z = ((float)_depth / 2.0f) - z;
 // Scale down by the transformation that makes the
 // cellspacing equal to one.  This is given by
 // 1 / cellspacing since; cellspacing * 1 / cellspacing = 1.

 x /= (float)_CellSpacing;
 z /= (float)_CellSpacing;
 // From now on, we will interpret our positive z-axis as
 // going in the 'down' direction, rather than the 'up' direction.
 // This allows to extract the row and column simply by 'flooring'
 // x and z:
 float col = ::floorf(x);
 float row = ::floorf(z);
 // get the heights of the quad we're in:
 //
    //  A   B
    //  *---*
    //    | / |
    //  *---* 
    //  C   D
 float A = GetHeightMapEntry(row,   col);
 float B = GetHeightMapEntry(row,   col+1);
 float C = GetHeightMapEntry(row+1, col);
 float D = GetHeightMapEntry(row+1, col+1);
 //
 // Find the triangle we are in:
 //
 // Translate by the transformation that takes the upper-left
 // corner of the cell we are in to the origin.  Recall that our
 // cellspacing was nomalized to 1.  Thus we have a unit square
 // at the origin of our +x -> 'right' and +z -> 'down' system.

 float dx = x - col;
 float dz = z - row;
 // Note the below compuations of u and v are unneccessary, we really
 // only need the height, but we compute the entire vector to emphasis
 // the books discussion.

 float height = 0.0f;
 if(dz < 1.0f - dx)  // upper triangle ABC
 {
  float uy = B - A; // A->B
  float vy = C - A; // A->C
  // Linearly interpolate on each vector.  The height is the vertex
  // height the vectors u and v originate from {A}, plus the heights
  // found by interpolating on each vector u and v.

  height = A + Lerp(0.0f, uy, dx) + Lerp(0.0f, vy, dz);
 }
 else // lower triangle DCB
 {
  float uy = C - D; // D->C
  float vy = B - D; // D->B
  // Linearly interpolate on each vector.  The height is the vertex
  // height the vectors u and v originate from {D}, plus the heights
  // found by interpolating on each vector u and v.

  height = D + Lerp(0.0f, uy, 1.0f - dx) + Lerp(0.0f, vy, 1.0f - dz);
 }
 return height;
}
 
用到的2个函数
float Terrain::Lerp(float a, float b, float t)     //一个插值函数
{
 return (a - (a*t) + (b*t));
}
 
int Terrain::GetHeightMapEntry(int row, int col)         //读取高度函数
{
 return _heightmap[row * _numVertsPerRow + col];   // 高度图数据存在_heightmap里
}
 
二:
先计算出摄像机所在三角形的平面方程,然后带入摄像机的X,Z坐标,即可得高度Y
具体实现过程见http://creatorchen1984.spaces.live.com/ 《获取地形上某一点高度》,写的十分详细
 
三:
网上找的一个方法
假设你的地形为terrain[][];用下面的函数求出地形上点(x,z);的y值,将人物的高度加上这个y值即可.
float GetHeight(GLfloat x, GLfloat z)
{
float h=0;
float Xb,Yb;
int Xa,Ya;
Xa=(int)x;
Ya=(int)z;
Xb=x-Xa;
Yb=z-Ya;
float a=terrain[Xa][Ya].y;
float b=terrain[Xa+1][Ya].y;
float c=terrain[Xa][Ya+1].y;
float d=terrain[Xa+1][Ya+1].y;
h=(a*(1-Xb)+b*Xb)*(1-Yb)+(c*(1-Xb)+d*Xb)*Yb;
return h;
}

本文出自 “小祥” 博客,请务必保留此出处http://xiaoxiang.blog.51cto.com/88051/21443





    文章评论
 
2007-03-25 14:34:29
看过。很详细

2007-04-02 13:05:40
总结的很不错。继续努力。。呵呵。。。。

2007-04-02 13:08:18
对了,我已经买了域名和空间。等域名解析完了就可以用了。。
http://creatorchen1984.spaces.live.com不再更新。
新空间弄好后我会把网址告诉你。

 

发表评论

昵   称:
验证码:  点击图片可刷新验证码  博客过2级,无需填写验证码
内   容: