Here the man says:
remade everything into an iterative method so that it was correctly counted by layers
I have the same situation, there are methods, but I do not know how to call them in layers?
I can not register on this forum to ask him.
There on the forum he briefly explains the principle of the algorithm.
I will try to explain.
The Square method receives two corners at the entrance, the lower left and the upper right, and considers the center point of the square thus defined.
Diamond accepts only the coordinates of the point to be counted (i.e. the midpoint of the square from the previous step) and the half side of this square, considers the coordinates of four points to the right, left, top and bottom of the accepted point and also, as in Square, averages them and adds a random number proportional to the side. If any of the coordinates of these four points goes beyond the boundaries of the map, then it takes the value of the point lying on the other side, i.e. as if collapses the plane.
The DiamondSquare method combines these two methods, taking the same parameters as Square. First, he calls Square for the input square, then Diamond for all four means of his sides, and then recursively calls himself for four sub-squares until he counts all the pixels.
The recursive function itself:
public void diamondSquare(Vec2int L, Vec2int R, int l) { if (l > 0) { Vec2int[] points = GetPoints(L, R, l); foreach (Vec2int elem in points) { diamond (elem, l); } square (L, new Vec2int (points [3].x, points [2].y), l); square (new Vec2int (points [3].x, points [2].y), R, l); square (points [0], points [1], l); square (points [3], points [2], l); diamondSquare (L, new Vec2int (points [3].x, points [2].y), l / 2); diamondSquare (new Vec2int (points [3].x, points [2].y), R, l / 2); diamondSquare (points [0], points [1], l / 2); diamondSquare (points [3], points [2], l / 2); } } The rest of the code:
public int size = 32; [Range(0,1f)] public float Roughnees = 0.5f; private float[,] map; public void square(Vec2int L, Vec2int R, int l) { Vec2int Center = new Vec2int (Rx - l, Ry - l); float a = map [Lx, Ly]; float b = map [Lx, Ry]; float c = map [Rx, Ry]; float d = map [Rx, Ly]; map [Center.x, Center.y] = (a + b + c + d) / 4 + Random.Range (-l / (size - 1) * (Roughnees), l / (size - 1) * (Roughnees)); } public void diamond(Vec2int point,int l) { float a, b, c, d; if (point.y - l >= 0) a = map [point.x, point.y - l]; else a = map[point.x, size - l]; if (point.x - l >= 0) b = map [point.x - l, point.y]; else b = map [size - l, point.y]; if (point.y + l < size) c = map [point.x, point.y + l]; else c = map [point.x, l]; if (point.x + l < size) d = map [point.x + l, point.y]; else d = map [l, point.y]; map [point.x, point.y] = (a + b + c + d) / 4 + Random.Range (-l / (size - 1) * Roughnees, l / (size - 1) * Roughnees); } public static Vec2int[] GetPoints(Vec2int L, Vec2int R, int l) { return new Vec2int[] { new Vec2int (Lx, Ly + l), new Vec2int (Rx - l, Ry), new Vec2int (Rx, Ry - l), new Vec2int (Lx + l, Ly) }; } public struct Vec2int { public int x; public int y; public Vec2int(int x,int y){ this.x=x; this.y=y; } } So I would be glad to links to what you can read in this direction.
It is important to note that these two heights that we got in the previous step should already be calculated - so you need to calculate the “layers”, first perform the “square” step for all squares - then perform the “diamond” step for all diamonds - and go to smaller squares.
From an article on Habré.
In my case, the recursion goes deep into the left lower square and each of its right and upper sides is incorrectly considered, and only after this recursion ends, the next one starts for the right upper one, for which the left and lower sides are also incorrectly considered.
The number of method calls in the first 3 iterations with a picture resolution of 64px
1 x Square and Diamond
4 x Square and Diamond
16 x Square and Diamond
And for each method you need to know the coordinates.
