BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Finding the 'slope' at a x,z point on a heightmap...
Goto page 1, 2  Next
 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Graphics
View previous topic :: View next topic  
Author Message
Paul Nicholls
Guest





PostPosted: Thu Jun 10, 2004 2:32 am    Post subject: Finding the 'slope' at a x,z point on a heightmap... Reply with quote



Hi all, I am interested in finding out the approximate slope at any x,z
point in a Byte filled heightmap...

I am at the moment creating each pixel in the heightmap texture array
depending on the height range, but I now want to add in that if the slope is
too steep for some terrain types then I will use rock for example instead.

So I need to find out the slope at any x,z point...

Does anyone have a small code snipit that can help me?

Thanks in advance,
Paul Nicholls (Delphi 5/6 Professional)
"The plastic veneer of civilization is easily melted in the heat of the
moment" - Paul Nicholls
[email]paul-nicholls (AT) hotmail (DOT) com[/email]

Replace '-' with '_' to reply


Back to top
Lord Crc
Guest





PostPosted: Thu Jun 10, 2004 3:02 am    Post subject: Re: Finding the 'slope' at a x,z point on a heightmap... Reply with quote



On Thu, 10 Jun 2004 12:32:35 +1000, "Paul Nicholls" <.> wrote:

Quote:
So I need to find out the slope at any x,z point...

normalX = hmap[x+1, z] - hmap[x-1, z];
normalZ = hmap[x, z+1] - hmap[x, z-1];

simplest is to set normalY = 1 and normalize, and use this normal

- Asbjørn

Back to top
Paul Nicholls
Guest





PostPosted: Thu Jun 10, 2004 3:15 am    Post subject: Re: Finding the 'slope' at a x,z point on a heightmap... Reply with quote



Thanks Asbjorn Smile
I'll try this...

Cheers,
Paul.
"Lord Crc" <lordcrc (AT) hotmail (DOT) com> wrote

Quote:
On Thu, 10 Jun 2004 12:32:35 +1000, "Paul Nicholls" <.> wrote:

So I need to find out the slope at any x,z point...

normalX = hmap[x+1, z] - hmap[x-1, z];
normalZ = hmap[x, z+1] - hmap[x, z-1];

simplest is to set normalY = 1 and normalize, and use this normal

- Asbjørn



Back to top
Sean
Guest





PostPosted: Thu Jun 10, 2004 3:20 am    Post subject: Re: Finding the 'slope' at a x,z point on a heightmap... Reply with quote

"Paul Nicholls" <.> wrote


Quote:
Hi all, I am interested in finding out the approximate slope at any x,z
point in a Byte filled heightmap...

I am at the moment creating each pixel in the heightmap texture array
depending on the height range, but I now want to add in that if the slope
is
too steep for some terrain types then I will use rock for example instead.

So I need to find out the slope at any x,z point...

For your case:

MaxGrad[i,j] := Max ( Abs(y[i,j]-y[i-1,j]) , Abs(y[i,j]-y[i,j-1]) {,
Abs(y[i,j]-y[i-1,j-1])/1.41) } )



Back to top
Lord Crc
Guest





PostPosted: Thu Jun 10, 2004 4:46 am    Post subject: Re: Finding the 'slope' at a x,z point on a heightmap... Reply with quote

On Thu, 10 Jun 2004 13:15:46 +1000, "Paul Nicholls" <.> wrote:

Quote:
Thanks Asbjorn Smile

Btw, adjust the size of Y to determine how "slopy" you want it. Ie, if
it's 1, then since dX or dZ is 1 max too, you wont get any slope
angles < 45 deg. So you prob want to decrease it.

Here's a small sample of a heightmap "texture" which i made by using
the formulate i stated http://lordcrc.no-ip.com/public/hmap.jpg
Just a quicky i made after writing this post :)

- Asbjørn

Back to top
Paul Nicholls
Guest





PostPosted: Thu Jun 10, 2004 6:08 am    Post subject: Re: Finding the 'slope' at a x,z point on a heightmap... Reply with quote

erm, I'm actually having trouble using the normal from the calculation you
provided so I can blend the two textures...

lets say I have the two texture rgb values like so:

(r1,g1,b1) = snow (for example)
(r2,g2,b2) = rock (for example)

t = 0..1 (how to calculate)

r := (1-t) * r1 + t * r2;
g := (1-t) * g1 + t * g2;
b := (1-t) * b1 + t * b2;

Given the normal, n, from your calculation and some slope (from vertical)
threshold angle, a (0-90), after which the colour interpolates between the
snow to the rock depending on the slope, how do I calculate t?

So, let say I have a threshold angle of 60 degrees, how can I test it
against the normal, and get t?

Can you share your code snipit that you used to create the texturemap you
posted?

"Lord Crc" <lordcrc (AT) hotmail (DOT) com> wrote

Quote:
On Thu, 10 Jun 2004 13:15:46 +1000, "Paul Nicholls" <.> wrote:

Thanks Asbjorn :-)

Btw, adjust the size of Y to determine how "slopy" you want it. Ie, if
it's 1, then since dX or dZ is 1 max too, you wont get any slope
angles < 45 deg. So you prob want to decrease it.

Here's a small sample of a heightmap "texture" which i made by using
the formulate i stated http://lordcrc.no-ip.com/public/hmap.jpg
Just a quicky i made after writing this post :)

- Asbjørn



Back to top
Paul Nicholls
Guest





PostPosted: Thu Jun 10, 2004 6:08 am    Post subject: Re: Finding the 'slope' at a x,z point on a heightmap... Reply with quote

erm, I'm actually having trouble using the normal from the calculation you
provided so I can blend the two textures...

lets say I have the two texture rgb values like so:

(r1,g1,b1) = snow (for example)
(r2,g2,b2) = rock (for example)

t = 0..1 (how to calculate)

r := (1-t) * r1 + t * r2;
g := (1-t) * g1 + t * g2;
b := (1-t) * b1 + t * b2;

Given the normal, n, from your calculation and some slope (from vertical)
threshold angle, a (0-90), after which the colour interpolates between the
snow to the rock depending on the slope, how do I calculate t?

So, let say I have a threshold angle of 60 degrees, how can I test it
against the normal, and get t?

Can you share your code snipit that you used to create the texturemap you
posted?

"Lord Crc" <lordcrc (AT) hotmail (DOT) com> wrote

Quote:
On Thu, 10 Jun 2004 13:15:46 +1000, "Paul Nicholls" <.> wrote:

Thanks Asbjorn :-)

Btw, adjust the size of Y to determine how "slopy" you want it. Ie, if
it's 1, then since dX or dZ is 1 max too, you wont get any slope
angles < 45 deg. So you prob want to decrease it.

Here's a small sample of a heightmap "texture" which i made by using
the formulate i stated http://lordcrc.no-ip.com/public/hmap.jpg
Just a quicky i made after writing this post :)

- Asbjørn



Back to top
Nils Haeck
Guest





PostPosted: Thu Jun 10, 2004 8:18 pm    Post subject: Re: Finding the 'slope' at a x,z point on a heightmap... Reply with quote

Hello Paul,

I normally visualise Z as the height, based on a field in x and y. If you
use that, then:

DeltaZx := h(x+1, y) - h(x-1, y); // The difference in Z due to change in x
over 2 cells
DeltaZy := h(x, y+1) - h(x, y-1); // The difference in Z due to change in y
over 2 cells

Next you calculate the resulting normal vector using crossproduct:

Normal = (2 0 DeltaZx)' x (0 2 DeltaZy) = (-2 * DeltaZx, -2 * DeltaZy, 4),
or (-DeltaZx, -DeltaZy, 2)

As a result, the slope at (x, y) will be:

Slope := sqrt(sqr(DeltaZx) + sqr(DeltaZy)) / 2;

So the slope is the biggest amount of change for each one unit of change in
the XY plane. It assumes you determine this for * based on the 4
neighbouring cells ABCD see below, so special treatment is neccesary at the
edges.

B
A*C
D

You could make a small 2D lookup table for most values of DeltaZx and
DeltaZy (e.g. in a range of -10 .. 10) and only calculate the slope for
values outside of that range. This saves you on the expensive sqrt
instruction.

Kind regards,

Nils Haeck
www.simdesign.nl


"Paul Nicholls" <.> wrote

Quote:
Hi all, I am interested in finding out the approximate slope at any x,z
point in a Byte filled heightmap...

I am at the moment creating each pixel in the heightmap texture array
depending on the height range, but I now want to add in that if the slope
is
too steep for some terrain types then I will use rock for example instead.

So I need to find out the slope at any x,z point...

Does anyone have a small code snipit that can help me?

Thanks in advance,
Paul Nicholls (Delphi 5/6 Professional)
"The plastic veneer of civilization is easily melted in the heat of the
moment" - Paul Nicholls
[email]paul-nicholls (AT) hotmail (DOT) com[/email]

Replace '-' with '_' to reply





Back to top
somebody
Guest





PostPosted: Thu Jun 10, 2004 11:10 pm    Post subject: Re: Finding the 'slope' at a x,z point on a heightmap... Reply with quote

"Nils Haeck" <n.haeckno (AT) spamchello (DOT) nl> wrote

Quote:
Hello Paul,

I normally visualise Z as the height, based on a field in x and y. If you
use that, then:

DeltaZx := h(x+1, y) - h(x-1, y); // The difference in Z due to change in
x
over 2 cells
DeltaZy := h(x, y+1) - h(x, y-1); // The difference in Z due to change in
y
over 2 cells

Technically you should have h(x,y) somewhere above, ie either

DeltaZx := h(x+1, y) - h(x, y);
or
DeltaZx := h(x, y) - h(x-1, y);

The problem is, with your definintion, the function

h(x,y) = 255*( (x+y) mod 2)

would have 0 slope everywhere, which is probably not what one would expect.

Quote:
Next you calculate the resulting normal vector using crossproduct:

Normal = (2 0 DeltaZx)' x (0 2 DeltaZy) = (-2 * DeltaZx, -2 * DeltaZy, 4),
or (-DeltaZx, -DeltaZy, 2)

As a result, the slope at (x, y) will be:

Slope := sqrt(sqr(DeltaZx) + sqr(DeltaZy)) / 2;

That's not quite correct either, well, there's no single slope in 3D but a
gradient (a vector quantity). So, depending on how "precise" you want to be
you can calculate the 4 (or Cool gradients approaching from those directions
(for a continuous surface there would only be 2 independent components) and
in this case, take the maximum of the absolute values:

MaxSlope := Max (
Abs(h(x, y) - h(x-1, y)),
Abs(h(x, y) - h(x+1, y)),
Abs(h(x, y) - h(x, y-1)),
Abs(h(x, y) - h(x, y+1)),

0.71*Abs(h(x, y) - h(x-1, y-1)),
0.71*Abs(h(x, y) - h(x+1, y-1)),
0.71*Abs(h(x, y) - h(x-1, y+1)),
0.71*Abs(h(x, y) - h(x+1, y+1)),
);




Back to top
Paul Nicholls
Guest





PostPosted: Thu Jun 10, 2004 11:14 pm    Post subject: Re: Finding the 'slope' at a x,z point on a heightmap... Reply with quote

Thanks Nils, I'll give it a go :-)

Just one other question, if I have a threshold angle (from vertical),
Athreshold, and when the slope is greater than this value (from the
vertical), how can I calculate t (0-1) for interpolating between 2 textures
(t1 at Athreshold to t2 at 90 degrees)?

Can I do this?

For example:

Athreshold = Cos(60*PI/180); // ignoring the fact I could put in as
radians straight off...

Normal := Normalise(calculated value at height map point)...

D := Dot(Normal,Vector3d(0,1,0));

if(D < Athreshold)then
begin
t := D / Athreshold;

if(t < 0)then
t := 0;

Rt1 := t1.r; // texture 1 colour
Gt1 := t1.g;
Bt1 := t1.b;

Rt2 := t2.r; // texture 2 colour
Gt2 := t2.g;
Bt2 := t2.b;

R := t * Rt1 + (1-t) * Rt2;
G := t * Gt1 + (1-t) * Gt2;
B := t * Bt1 + (1-t) * Bt2;
end;

"Nils Haeck"
Quote:
Hello Paul,

I normally visualise Z as the height, based on a field in x and y. If you
use that, then:

DeltaZx := h(x+1, y) - h(x-1, y); // The difference in Z due to change in
x
over 2 cells
DeltaZy := h(x, y+1) - h(x, y-1); // The difference in Z due to change in
y
over 2 cells

Next you calculate the resulting normal vector using crossproduct:

Normal = (2 0 DeltaZx)' x (0 2 DeltaZy) = (-2 * DeltaZx, -2 * DeltaZy, 4),
or (-DeltaZx, -DeltaZy, 2)

As a result, the slope at (x, y) will be:

Slope := sqrt(sqr(DeltaZx) + sqr(DeltaZy)) / 2;

So the slope is the biggest amount of change for each one unit of change
in
the XY plane. It assumes you determine this for * based on the 4
neighbouring cells ABCD see below, so special treatment is neccesary at
the
edges.

B
A*C
D

You could make a small 2D lookup table for most values of DeltaZx and
DeltaZy (e.g. in a range of -10 .. 10) and only calculate the slope for
values outside of that range. This saves you on the expensive sqrt
instruction.

Kind regards,

Nils Haeck
www.simdesign.nl


"Paul Nicholls" <.> wrote

Hi all, I am interested in finding out the approximate slope at any x,z
point in a Byte filled heightmap...

I am at the moment creating each pixel in the heightmap texture array
depending on the height range, but I now want to add in that if the
slope
is
too steep for some terrain types then I will use rock for example
instead.

So I need to find out the slope at any x,z point...

Does anyone have a small code snipit that can help me?

Thanks in advance,
Paul Nicholls (Delphi 5/6 Professional)
"The plastic veneer of civilization is easily melted in the heat of the
moment" - Paul Nicholls
[email]paul-nicholls (AT) hotmail (DOT) com[/email]

Replace '-' with '_' to reply







Back to top
Lord Crc
Guest





PostPosted: Thu Jun 10, 2004 11:25 pm    Post subject: Re: Finding the 'slope' at a x,z point on a heightmap... Reply with quote

On Thu, 10 Jun 2004 16:08:40 +1000, "Paul Nicholls" <.> wrote:

Quote:
So, let say I have a threshold angle of 60 degrees, how can I test it
against the normal, and get t?

I used a power curve to blend in the rocks, however i used a elevation
threshold for WHEN i started to blend in rocks. You can look at that
code to see if does what you want.

Quote:
Can you share your code snipit that you used to create the texturemap you
posted?

http://lordcrc.no-ip.com/public/heightmap_slope.zip

Its on my home box, so it might die, but i'll make it come back up
when i notice :)

- Asbjørn

Back to top
Paul Nicholls
Guest





PostPosted: Fri Jun 11, 2004 12:04 am    Post subject: Re: Finding the 'slope' at a x,z point on a heightmap... Reply with quote

Thanks, I got the code...I'll take a gander :-)

Cheers,
Paul.
"Lord Crc" <lordcrc (AT) hotmail (DOT) com> wrote

Quote:
On Thu, 10 Jun 2004 16:08:40 +1000, "Paul Nicholls" <.> wrote:

So, let say I have a threshold angle of 60 degrees, how can I test it
against the normal, and get t?

I used a power curve to blend in the rocks, however i used a elevation
threshold for WHEN i started to blend in rocks. You can look at that
code to see if does what you want.

Can you share your code snipit that you used to create the texturemap you
posted?

http://lordcrc.no-ip.com/public/heightmap_slope.zip

Its on my home box, so it might die, but i'll make it come back up
when i notice :)

- Asbjørn



Back to top
Nils Haeck
Guest





PostPosted: Fri Jun 11, 2004 2:30 pm    Post subject: Re: Finding the 'slope' at a x,z point on a heightmap... Reply with quote

Quote:
h(x,y) = 255*( (x+y) mod 2)

would have 0 slope everywhere, which is probably not what one would
expect.


Sure that's what I would expect. After all, you want the slope for the pixel
value itself. If it goes up by 255 at one end and goes down by 255 at the
other end, the average of that is 0.

You will only get slopes here if you create an image that is twice as big,
or shifted by half a pixel. Calculating slopes on such a high-frequency
image makes no sense anyway due to aliasing effects. You would have to
filter it first and find that in fact the value of all pixels goes to 127.5.

Quote:
Slope := sqrt(sqr(DeltaZx) + sqr(DeltaZy)) / 2;

That's not quite correct either, well, there's no single slope in 3D but a

I don't agree at all. It is absolutely correct when looking at the problem
in 3D. If you have both slopes in X and Y at 1 pixel height change at one
pixel horizontal change, your slope calculation would still yield 1.0 as
slope, while in fact if you come from a 45deg angle you would see a slope of
sqrt(2)=1.41. And a marble rolling down at that point would not roll along
any of the slopes in X and Y but along the 45degree where the slope is
maximum.

Of course it depends on how far you would want to look around, but above
method is generally used for square grids.

Nils



Back to top
Nils Haeck
Guest





PostPosted: Fri Jun 11, 2004 2:36 pm    Post subject: Re: Finding the 'slope' at a x,z point on a heightmap... Reply with quote

Why not simply convert the slope to degrees?

That way you'll get a value from 0 to 90 degrees (0 being horizontal, 90
being vertical). The 90 will never be reached in a height map of bytes, I
think the theoretical maximum of the slope would be (at the edge)

sqrt(sqr(255) * 2) / 2 = (calculate this yourself)

So the slope angle would be: Angle = arctan(Slope) - in radians

Then you can interpolate like this:

t = Arctan(Slope) / (0.5 * pi);

R := t * Rt1 + (1-t) * Rt2;
G := t * Gt1 + (1-t) * Gt2;
B := t * Bt1 + (1-t) * Bt2;

Or substitute for 0.5 * pi the value of sqrt(sqr(255) * 2) / 2.

Kind regards,

Nils


"Paul Nicholls" <.> wrote

Quote:
Thanks Nils, I'll give it a go :-)

Just one other question, if I have a threshold angle (from vertical),
Athreshold, and when the slope is greater than this value (from the
vertical), how can I calculate t (0-1) for interpolating between 2
textures
(t1 at Athreshold to t2 at 90 degrees)?

Can I do this?

For example:

Athreshold = Cos(60*PI/180); // ignoring the fact I could put in as
radians straight off...

Normal := Normalise(calculated value at height map point)...

D := Dot(Normal,Vector3d(0,1,0));

if(D < Athreshold)then
begin
t := D / Athreshold;

if(t < 0)then
t := 0;

Rt1 := t1.r; // texture 1 colour
Gt1 := t1.g;
Bt1 := t1.b;

Rt2 := t2.r; // texture 2 colour
Gt2 := t2.g;
Bt2 := t2.b;

R := t * Rt1 + (1-t) * Rt2;
G := t * Gt1 + (1-t) * Gt2;
B := t * Bt1 + (1-t) * Bt2;
end;

"Nils Haeck" news:40c8bf9b (AT) newsgroups (DOT) borland.com...
Hello Paul,

I normally visualise Z as the height, based on a field in x and y. If
you
use that, then:

DeltaZx := h(x+1, y) - h(x-1, y); // The difference in Z due to change
in
x
over 2 cells
DeltaZy := h(x, y+1) - h(x, y-1); // The difference in Z due to change
in
y
over 2 cells

Next you calculate the resulting normal vector using crossproduct:

Normal = (2 0 DeltaZx)' x (0 2 DeltaZy) = (-2 * DeltaZx, -2 * DeltaZy,
4),
or (-DeltaZx, -DeltaZy, 2)

As a result, the slope at (x, y) will be:

Slope := sqrt(sqr(DeltaZx) + sqr(DeltaZy)) / 2;

So the slope is the biggest amount of change for each one unit of change
in
the XY plane. It assumes you determine this for * based on the 4
neighbouring cells ABCD see below, so special treatment is neccesary at
the
edges.

B
A*C
D

You could make a small 2D lookup table for most values of DeltaZx and
DeltaZy (e.g. in a range of -10 .. 10) and only calculate the slope for
values outside of that range. This saves you on the expensive sqrt
instruction.

Kind regards,

Nils Haeck
www.simdesign.nl


"Paul Nicholls" <.> wrote in message
news:40c7c906 (AT) newsgroups (DOT) borland.com...
Hi all, I am interested in finding out the approximate slope at any
x,z
point in a Byte filled heightmap...

I am at the moment creating each pixel in the heightmap texture array
depending on the height range, but I now want to add in that if the
slope
is
too steep for some terrain types then I will use rock for example
instead.

So I need to find out the slope at any x,z point...

Does anyone have a small code snipit that can help me?

Thanks in advance,
Paul Nicholls (Delphi 5/6 Professional)
"The plastic veneer of civilization is easily melted in the heat of
the
moment" - Paul Nicholls
[email]paul-nicholls (AT) hotmail (DOT) com[/email]

Replace '-' with '_' to reply









Back to top
Nils Haeck
Guest





PostPosted: Fri Jun 11, 2004 2:40 pm    Post subject: Re: Finding the 'slope' at a x,z point on a heightmap... Reply with quote

Correction:

Quote:
Or substitute for 0.5 * pi the value of sqrt(sqr(255) * 2) / 2.

Or substitute for 0.5 * pi the value of arctan(sqrt(sqr(255) * 2) / 2).



Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> Delphi Graphics All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.