0

I'm working on implementation of the Diamond-square algorithm but the outcoming heightmap looks strange like some points are not filled:
HeightMap
I've tried to change for stateents but I still can't find where these points can be missed. Here is my code of a function which is filling the one-dimensional heightMap of values between 0.0 and 1.0.

func diamond(x1 int, y1 int, x2 int, y2 int, l int, size int, r float32)  {
    var a, b, c, d float32
    var cx, cy int
    a = heightMap[x1 + y1*size]
    b = heightMap[x1 + y2*size]
    c = heightMap[x2 + y2*size]
    d = heightMap[x2 + y1*size]

    cx = (x2 - x1)/2
    cy = (y2 - y1)/2

    heightMap[cx + cy*size] = float32(a + b + c + d)/float32(4) + rand.Float32()*r
}

func square(cx int, cy int, l int, size int, r float32)  {
    var a, b, c, d float32
    var isBorder = float32(0)
    if cx == 0 {
        isBorder = 1
        a = 0
    } else {
        a = heightMap[cx - l/2 + cy*size]
    }
    if cy == size - 1 {
        isBorder = 1
        b = 0
    } else {
        b = heightMap[cx + (cy + l/2)*size]
    }
    if cx == size - 1 {
        isBorder = 1
        c = 0
    } else {
        c = heightMap[cx + l/2 + cy*size]
    }
    if cy == 0 {
        isBorder = 1
        d = 0
    } else {
        d = heightMap[cx + (cy - l/2)*size]
    }
    heightMap[cx + cy*size] = float32(a + b + c + d)/float32(4 - isBorder) + rand.Float32()*r
}

func initHeightMap(size int) {
    rand.Seed(3256)
    heightMap = make([]float32, size*size)
    heightMap[0] = rand.Float32()
    heightMap[size-1] = rand.Float32()
    heightMap[(size-1)*size] = rand.Float32()
    heightMap[size*size-1] = rand.Float32()
    var t int
    t = size - 1
    for l := size - 1; l > 0; l /= 2 {
        //diamond steps
        for y := 0; y < size - 1; y += l {
            for x := 0; x < size - 1; x += l {
                diamond(x, y, x + l, y + l, l, size, float32(l)/float32(size-1))
            }
        }
        //square steps
        if l > 1 {
            for y := 0; y < size - 1; y += l/2 {
                if t%2 == 0 {
                    for x := l/2; x < size; x += l {
                        square(x, y, l, size, float32(l)/float32(size-1))
                    }
                } else {
                    for x := 0; x < size; x += l {
                        square(x, y, l, size, float32(l)/float32(size-1))
                    }
                }
                t++
            }
        }
    }
}

Size is a value which is always a power of 2 plus 1 and a random number range is halfed with l.

I've seen a similar heightmap in this question Unexpected Diamond square Algorithm results but there was a different mistake in the algorithm.

EvilTak
  • 7,091
  • 27
  • 36
vigorge
  • 9
  • 1
  • 2
    debug each iteration ... output image after first diamond, then square , ... so you see when it starts filling map wrongly (ideally progress on key press to next iteration) that should hint if the problem is diamond, square or both. If you want something to compare with see my [iterative Diamond&square](https://stackoverflow.com/a/36258843/2521214) and the same with biomes [island generator](https://stackoverflow.com/a/36647622/2521214) – Spektre Jan 08 '21 at 18:47
  • @Spektre Thanks a lot, there really were few silly mistakes that I've missed. Now It works fine, but I've noticed that there's still a pattern with midpoints of bigger squares being much darker then their surroundings. It looks like in your answer here [link](https://stackoverflow.com/questions/36246535/diamond-square-algorithm-not-working-rewrite-code-from-js-to-java/36258843#36258843) and a heightMap in your Island algorithm looks much smother and random. Could you please tell, why is it so? Is there something to do with a random numbers range? – vigorge Jan 09 '21 at 15:11
  • @Spektre I got it myself. Thanks a lot again for these useful links, they really helped. – vigorge Jan 09 '21 at 15:38
  • glad to be of help... You might post an answer with your solution ... – Spektre Jan 09 '21 at 22:29

0 Answers0