Archived

This topic is now archived and is closed to further replies.

Getting the height at a location

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

Recommended Posts

I have a quad with four vertices of variable height which is 1 unit square. 2 is 0,0 3 is 1,1
1--3
|  |
|  |
2--4

The first step I''m assuming is to determine which way the quad folds.
v1[0]=(int)x*1.0;
v1[1]=(int)y*1.0+1.0;
v2[0]=(int)x*1.0;
v2[1]=(int)y*1.0;
v3[0]=(int)x*1.0+1.0;
v3[1]=(int)y*1.0+1.0;
v4[0]=(int)x*1.0+1.0;
v4[1]=(int)y*1.0;
v1[2]=height_field[(int)v1[1]][(int)v1[0]];
v2[2]=height_field[(int)v2[1]][(int)v2[0]];
v3[2]=height_field[(int)v3[1]][(int)v3[0]];
v4[2]=height_field[(int)v4[1]][(int)v4[0]];
if((v1[2]+v4[2])/2.0f>(v2[2]+v3[2])/2.0f)

If the height in the center of vertices 1 and 4 are greater then the height in the center of vertices 2 and three the the quad is folded along 1 and 4
-----
|\  |
| \ |
|  \|
-----

Other wise the fold is along 2 and 3
-----
|  /|
| / |
|/  |
-----

And that determines my two planes that I could be standing on. If the height in the center is equal, it doesn''t really matter since the quad is flat so going either way will work since it''s actually a single plane. The next step is to figure out which plane I''m standing on. In case of the first one
if(y-(int)y<1-x+(int)x)

Then I''m on the left plane otherwise I''m on the right plane. In case of the second one
if(y-(int)y>x-(int)x)

I''m on the left plane, otherwise the right. Once it''s determined which plane I''m standing on, the vertices that make up the plane are passed to a function which does the vector math where v2 is the center vertice. Vector v1v2 and v2v3 are used to determine the plane.
float getHeight(float v1[3], float v2[3], float v3[3], float x, float y)
{
float val;
val=-((v1[1]-v2[1])*(v3[2]-v2[2])-(v1[2]-v2[2])*(v3[1]-v2[1]))*(x-v2[0]);
val-=((v1[2]-v2[2])*(v3[1]-v2[1])-(v1[0]-v2[0])*(v3[2]-v2[2]))*(y-v2[1]);
val/=((v1[0]-v2[0])*(v3[1]-v2[1])-(v1[1]-v2[1])*(v3[0]-v2[0]));
val+=v2[2];
return val;
}

This works approximatly well however, although it gets the general solution (in that I can take partial steps around a quad and end up at the right height), moving around results in a jerky motion. I''m thinking it might be the transition between quads that''s confusing it. I was wondering if anyone could spot any obvious errors in my math or suggest a simpler solution. Ben [ IcarusIndie.com | recycledrussianbrides.com | Got Linux? ]

Share on other sites
with a bit of help from The Senshi at

http://www.gamedev.net/community/forums/topic.asp?topic_id=62935

The theory was perfect (figuring out which triangle I was over was amazingly overthought out) but my ability to copy even my own code/equations from paper to PC has yet again been demonstrated as lacking. Getting Y and Z flipped around didn''t help either.

All the equations in the first getHeight can easily be combined into a single return. It''s all laid out for readability.

Senshi uses DirectX functions to get the intersection where I do all the math by hand so the concepts here can be used with anything. I happen to use OpenGL.

float terrainSystem::getHeight(float v1[3], float v2[3], float v3[3], float x, float z){	float ax=v2[0]-v1[0];	float ay=v2[1]-v1[1];	float az=v2[2]-v1[2];	float bx=v2[0]-v3[0];	float by=v2[1]-v3[1];	float bz=v2[2]-v3[2];	float c=ay*bz-az*by;	float d=az*bx-ax*bz;	float e=ax*by-ay*bx;	return -(e*(z-v2[2])+c*(x-v2[0]))/d+v2[1];}float terrainSystem::getHeight(float x, float z){	float v1[3],v2[3],v3[3];	int rx, rz;	rx=x;	rz=z;	if(height_field!=NULL)		if(mapy>0)			if(mapx>0)				if((int)x<mapx-1 && (int)x>=0)				if((int)z<mapy-1 && (int)z>=0)				{					if(z-(int)z > x -(int)x)					{						v1[0]=rx;						v1[1]=height_field[rz+1][rx];						v1[2]=rz+1.0;						v2[0]=rx;						v2[1]=height_field[rz][rx];						v2[2]=rz;						v3[0]=rx+1.0;						v3[1]=height_field[rz+1][rx+1];						v3[2]=rz+1.0;						return getHeight(v2,v1,v3,x,z);								}					else					{						v1[0]=rx;						v1[1]=height_field[rz+1][rx];						v1[2]=rz+1.0;						v2[0]=rx+1;						v2[1]=height_field[rz+1][rx+1];						v2[2]=rz+1.0;						v3[0]=rx+1.0;						v3[1]=height_field[rz][rx+1];						v3[2]=rz;						return getHeight(v1,v3,v2,x,z);								}				}	return -1.0f;}

[ IcarusIndie.com | recycledrussianbrides.com | Got Linux? ]

1. 1
2. 2
Rutin
21
3. 3
4. 4
frob
16
5. 5

• 9
• 12
• 9
• 33
• 13
• Forum Statistics

• Total Topics
632593
• Total Posts
3007277

×