Posted: 24th Jun 2007 18:21
I have tried and tried to code this.... and done an extensive search for code over the internet... but my attempts at coding it fail... I am getting close to giving up...

let's say tleft,bleft,tright,bright are integers representing the heights (0-255) at the four corners of the heightmap

let's say the heightmap is the array hmap(heightmapsize,heightmapsize)... how would I go about coding this...?

I am writing some commands within my plugin to create heightmaps using fractal terrain algorithm(s).... those of you who know about this will probably know how to code the diamond square algorithm in secs/mins.... can you help / point me in the correct direction...
Posted: 24th Jun 2007 18:28
these are some of the links I found helpful - but not enough:-

http://www.gameprogrammer.com/fractal.html#structure

http://en.wikipedia.org/wiki/Diamond-square_algorithm

http://www.answers.com/topic/diamond-square-algorithm

http://www.fractal-landscapes.co.uk/maths.html

this one seemed to 'get me there' but didnt...

http://www.m0rph.com/bbs/messages/14420.html

some more useful links:-

http://www.lighthouse3d.com/opengl/terrain/index.php3?introduction

http://www.robot-frog.com/3d/hills/
Posted: 24th Jun 2007 22:36
OK so I gave up (for now) on the Diamond Square algorithm (please can someone show me the way...) but I managed some rather satisfying results with a variant of the "Hill" algorithm... see attached the DBPro program...
Posted: 24th Jun 2007 22:55
The diamond square thing sounds simple enough but coding it is a bit more difficult. I started coding it a while back for a terrain coding challenge but did not finish it. However, here is the final code. It also does some basic smoothing and normal setting. You may only be interested in the diamond square bit.

+ Code Snippet
set display mode 1024,768,32
sync on : sync rate 60 : autocam off : randomize timer()

set camera range 1,5000

` make a texture
cls rgb(0,255,0)
ink rgb(255,255,255),0
box 1,1,8,8
get image 1,0,0,8,8,1

av as float
rn as float

s=64 : ` matrix units and array size; must be a power of 2
m=2000 : ` size of matrix in db units
rn=0.2 : ` bigger numbers = smoother, smaller = spikier
smt=3 : ` how many times to smooth matrix

dim a(s,s,1) as float

make matrix 1,m,m,s,s
prepare matrix texture 1,1,1,1
cull=1
set matrix 1,0,0,cull,1,1,1,1

` do the diamond square algorithm
` paying special attention to wrapping around

c=s
repeat
   for z=0 to (s-c) step c
      for x=0 to (s-c) step c
         av=(a(x,z)+a(x+c,z)+a(x,z+c)+a(x+c,z+c))/4.0
         av=av+((-100+rnd(200))/rn)
         a(x+(c/2),z+(c/2))=av
      next x
   next z
   w=1
   for z=0 to (s-(c/2)) step (c/2)
      for x=0 to (s-c) step c
         x2=x+(w*(c/2))
         av=a(x2,z+(c/2))+a(x2+(c/2),z)
         if x2=0
            av=av+a(s-(c/2),z)
         else
            av=av+a(x2-(c/2),z)
         endif
         if z=0
            av=av+a(x2,s-(c/2))
         else
            av=av+a(x2,z-(c/2))
         endif
         av=av/4.0
         av=av+((-100+rnd(200))/rn)
         a(x2,z,0)=av
         if x2=0 then a(s,z,0)=av
         if z=0 then a(x2,s,0)=av
      next x
      w=1-w
   next z
   c=c/2
   rn=rn*2.0
until c < 2

` smooth the result
for multiple=1 to smt
   for x=0 to s-1
      x2=x-1 : if x2 < 0 then x2=s-1
      for z=0 to s-1
         z2=z-1 : if z2 < 0 then z2=s-1
         v1#=a(x2,z+1,0)
         v2#=a(x,z+1,0)
         v3#=a(x+1,z+1,0)
         v4#=a(x+1,z,0)
         v5#=a(x+1,z2,0)
         v6#=a(x,z2,0)
         v7#=a(x2,z2,0)
         v8#=a(x2,z,0)
         av#=(v1#+v2#+v3#+v4#+v5#+v6#+v7#+v8#)/8.0
         a(x,z,0)=av#
      next z
   next x
   for f=0 to s
      a(s,f,0)=a(0,f,0)
      a(f,s,0)=a(f,0,0)
   next f
next multiple

` calculate normals
for x=0 to s
   x2=x+1 : if x=s then x2=1
   for z=0 to s
      n#=1.0
      a1#=a(x,z,0)
      z2=z+1 : if z=s then z2=1
      a2#=a(x2,z2,0)
      ar#=a1#-a2#
      if a1# > a2#
         tw#=m*1.0/s
         if ar# > tw#
            n#=0
         else
            n#=ar#/(tw#/100.0)
            n#=(1.0-(n#/100.0))
         endif
      endif
      a(x,z,1)=n#
   next z
next x

` update matrix from array
for z=0 to s
   for x=0 to s
      av=a(x,z,0)
      n#=a(x,z,1)
      if x <> s and z <> s
         set matrix tile 1,x,z,1
      endif
      set matrix height 1,x,z,av
      if n# < 1.0
         set matrix normal 1,x,z,n#,n#,0
      endif
   next x
next z

update matrix 1

ink rgb(255,255,255),0
g=get ground height(1,m/2,m/2)
position camera m/2,m/2,-m/8
pitch camera down 45
do
   u=0
   if upkey() then shift matrix up 1 : u=1
   if downkey() then shift matrix down 1 : u=1
   if leftkey() then shift matrix left 1 : u=1
   if rightkey() then shift matrix right 1 : u=1
   if u=1 then update matrix 1
   text 0,0,"Scroll matrix with cursors"
   sync
loop
Posted: 24th Jun 2007 22:58
@ Spooky - brilliant, thanks.... check out the program I've attached above - takes its precious time but produces mighty fine results.. I suspect that the diamond-square algorithm (if I can make it work) will be hugely faster because there are far fewer iterations...

I'm looking at putting both in as commands in a dll Im working on...
Posted: 24th Jun 2007 23:21
@Spooky,

How would I go about setting the height of the four corners? presumably I can limit all values between 0-255 by normalising between 0.0 and 1 and then re-applying to 255?
Posted: 24th Jun 2007 23:36
I've already posted a demo of this - on the Code Snippets board I think. Will try to find it later (busy right now).

Try searching on fractal/terrain/clouds/sky etc.

And it should be quite quick.

Edit

Here it is:

http://forum.thegamecreators.com/?m=forum_view&t=68577&b=6
Posted: 25th Jun 2007 0:03
Here's one too

+ Code Snippet
Global HeightmapSize  As Integer
Global HeightmapDepth As Integer
Global Half           As Integer

Randomize Timer()

HeightmapSize  = 256
HeightmapDepth = 200
Half           = HeightmapSize * 0.5
Dim Heightmap(HeightmapSize,HeightmapSize) As Float

` Set the corner heights
Heightmap(0,0)                         = Rnd(HeightmapDepth)
Heightmap(0,HeightmapSize)             = Rnd(HeightmapDepth)
Heightmap(HeightmapSize,0)             = Rnd(HeightmapDepth)
Heightmap(HeightmapSize,HeightmapSize) = Rnd(HeightmapDepth)

` Passes
While Half >= 1

   HeightmapDepth = HeightmapDepth * 0.5

   For  X = Half To HeightmapSize - Half Step Half * 2
      For  Y = Half To HeightmapSize - Half Step Half * 2
         Heightmap(X,Y) = ( Heightmap(X-Half,Y-Half)+Heightmap(X+Half,Y-Half)+Heightmap(X-Half,Y+Half)+Heightmap(X+Half,Y+Half) ) * 0.25 + Rnd( HeightmapDepth ) - HeightmapDepth * 0.5
      Next Y
      Heightmap(X,0)              = ( Heightmap(X-Half,0)+Heightmap(X+Half,0) ) * 0.5                         + Rnd( HeightmapDepth ) - HeightmapDepth * 0.5
      Heightmap(X,HeightmapSize)  = ( Heightmap(X-Half,HeightmapSize)+Heightmap(X+Half,HeightmapSize) ) * 0.5 + Rnd( HeightmapDepth ) - HeightmapDepth * 0.5
      Heightmap(0,X)              = ( Heightmap(0,X-Half)+Heightmap(0,X+Half) ) * 0.5                         + Rnd( HeightmapDepth ) - HeightmapDepth * 0.5
      Heightmap(HeightmapSize,X)  = ( Heightmap(HeightmapSize,X-Half)+Heightmap(HeightmapSize,X+Half) ) * 0.5 + Rnd( HeightmapDepth ) - HeightmapDepth * 0.5
   Next X

   For  X = Half * 2 To HeightmapSize-1 Step Half * 2
      For  Y = Half To HeightmapSize-1 Step Half * 2
         Heightmap(X,Y) = ( Heightmap(X,Y-Half)+Heightmap(X,Y+Half)+Heightmap(X+Half,Y)+Heightmap(X-Half,Y) ) * 0.25 + Rnd( HeightmapDepth ) - HeightmapDepth * 0.5
         Heightmap(Y,X) = ( Heightmap(Y-Half,X)+Heightmap(Y+Half,X)+Heightmap(Y,X+Half)+Heightmap(Y,X-Half) ) * 0.25 + Rnd( HeightmapDepth ) - HeightmapDepth * 0.5
      Next Y
   Next X
   Half = Half * 0.5

EndWhile

` Output heightmap
For  X = 0 To HeightmapSize
   For  Y = 0 To HeightmapSize
      If Heightmap(X,Y) > 255 Then Heightmap(X,Y) = 255
      If Heightmap(X,Y) < 0   Then Heightmap(X,Y) = 0
      Dot X , Y , RGB(Heightmap(X,Y),Heightmap(X,Y),Heightmap(X,Y))
   Next Z
Next X

Wait Key
End


Credit to El Goorf, as my version totally didn't work so I just ported his cpp code.
Posted: 25th Jun 2007 0:46
@ GreenGandalf & Dark Coder,

Many thanks- more than enough to go on...