意外的钻石方形算法结果
Unexpected Diamond square Algorithm results
我目前正在尝试实现 Diamond Square 算法,虽然它在某种程度上可以工作,但我对 HeightMap 感到困惑。
这里是:
如您所见,正方形由较亮的值清楚地勾勒出轮廓,而低色值由较暗的值勾勒出轮廓。
我真的不明白为什么。我知道地图的尺寸确实很小,但我不认为这是预期的结果,而且我在更大尺寸的情况下得到了相同的行为。
这是我的代码:
public class TerrainBuilder
{
private Terrain Terrain = null;
private Random r = new Random();
private int espace;
public void Init(Terrain _terrain)
{
Terrain = _terrain;
espace = Terrain.SIZE - 1;
}
public void DiamondAlgoritm()
{
if (Terrain == null)
return;
//Initialization
Terrain.HeightMap[0, 0] = r.Next() % 255;
Terrain.HeightMap[0, Terrain.SIZE - 1] = r.Next() % 255;
Terrain.HeightMap[Terrain.SIZE - 1, 0] = r.Next() % 255;
Terrain.HeightMap[Terrain.SIZE - 1, Terrain.SIZE - 1] = r.Next() % 255;
//randominess
int decalage = 128;
while (espace > 1)
{
int demiSpace = espace / 2;
//diamond phase
for (int i = demiSpace; i < espace; i = i + espace)
{
for (int j = demiSpace; j < espace; j = j + espace)
{
var avg = Terrain.HeightMap[i + demiSpace, j + demiSpace] + Terrain.HeightMap[i + demiSpace, j - demiSpace] + Terrain.HeightMap[i - demiSpace, j + demiSpace] + Terrain.HeightMap[i - demiSpace, j - demiSpace];
avg /= 4;
Terrain.HeightMap[i, j] = Normalize(avg + r.Next() % decalage);
}
}
//carre phase
for (int i = 0; i < Terrain.SIZE; i += demiSpace)
{
int delay = 0;
if (i % espace == 0)
delay = demiSpace;
for (int j = delay; j < Terrain.SIZE; j += espace)
{
double somme = 0;
int n = 0;
if (i >= demiSpace)
somme = somme + Terrain.HeightMap[i - demiSpace, j];
n = n + 1;
if (i + demiSpace < Terrain.SIZE)
somme = somme + Terrain.HeightMap[i + demiSpace, j];
n = n + 1;
if (j >= demiSpace)
somme = somme + Terrain.HeightMap[i, j - demiSpace];
n = n + 1;
if (j + demiSpace < Terrain.SIZE)
somme = somme + Terrain.HeightMap[i, j + demiSpace];
n = n + 1;
Terrain.HeightMap[i, j] = Normalize(somme / n + r.Next() % decalage);
}
}
espace = demiSpace;
}
}
private double Normalize(double value)
{
return Math.Max(Math.Min(value, 255), 0);
}
}
我需要一些帮助来理解这个问题。
在菱形阶段,您不会遍历整个地图。你只计算第一个平方(等于espace
)。
像这样更改循环终止条件:
for (int i = demiSpace; i < Terrain.SIZE; i = i + espace)
{
for (int j = demiSpace; j < Terrain.SIZE; j = j + espace)
{
var avg = Terrain.HeightMap[i + demiSpace, j + demiSpace] +
Terrain.HeightMap[i + demiSpace, j - demiSpace] +
Terrain.HeightMap[i - demiSpace, j + demiSpace] +
Terrain.HeightMap[i - demiSpace, j - demiSpace];
avg /= 4;
Terrain.HeightMap[i, j] = Normalize(avg + r.Next() % decalage);
}
}
此外,您永远不会调整随机变量 (decalage
),随着 espace
.
大小的减小,随机变量应该会变小
我目前正在尝试实现 Diamond Square 算法,虽然它在某种程度上可以工作,但我对 HeightMap 感到困惑。
这里是:
如您所见,正方形由较亮的值清楚地勾勒出轮廓,而低色值由较暗的值勾勒出轮廓。 我真的不明白为什么。我知道地图的尺寸确实很小,但我不认为这是预期的结果,而且我在更大尺寸的情况下得到了相同的行为。
这是我的代码:
public class TerrainBuilder
{
private Terrain Terrain = null;
private Random r = new Random();
private int espace;
public void Init(Terrain _terrain)
{
Terrain = _terrain;
espace = Terrain.SIZE - 1;
}
public void DiamondAlgoritm()
{
if (Terrain == null)
return;
//Initialization
Terrain.HeightMap[0, 0] = r.Next() % 255;
Terrain.HeightMap[0, Terrain.SIZE - 1] = r.Next() % 255;
Terrain.HeightMap[Terrain.SIZE - 1, 0] = r.Next() % 255;
Terrain.HeightMap[Terrain.SIZE - 1, Terrain.SIZE - 1] = r.Next() % 255;
//randominess
int decalage = 128;
while (espace > 1)
{
int demiSpace = espace / 2;
//diamond phase
for (int i = demiSpace; i < espace; i = i + espace)
{
for (int j = demiSpace; j < espace; j = j + espace)
{
var avg = Terrain.HeightMap[i + demiSpace, j + demiSpace] + Terrain.HeightMap[i + demiSpace, j - demiSpace] + Terrain.HeightMap[i - demiSpace, j + demiSpace] + Terrain.HeightMap[i - demiSpace, j - demiSpace];
avg /= 4;
Terrain.HeightMap[i, j] = Normalize(avg + r.Next() % decalage);
}
}
//carre phase
for (int i = 0; i < Terrain.SIZE; i += demiSpace)
{
int delay = 0;
if (i % espace == 0)
delay = demiSpace;
for (int j = delay; j < Terrain.SIZE; j += espace)
{
double somme = 0;
int n = 0;
if (i >= demiSpace)
somme = somme + Terrain.HeightMap[i - demiSpace, j];
n = n + 1;
if (i + demiSpace < Terrain.SIZE)
somme = somme + Terrain.HeightMap[i + demiSpace, j];
n = n + 1;
if (j >= demiSpace)
somme = somme + Terrain.HeightMap[i, j - demiSpace];
n = n + 1;
if (j + demiSpace < Terrain.SIZE)
somme = somme + Terrain.HeightMap[i, j + demiSpace];
n = n + 1;
Terrain.HeightMap[i, j] = Normalize(somme / n + r.Next() % decalage);
}
}
espace = demiSpace;
}
}
private double Normalize(double value)
{
return Math.Max(Math.Min(value, 255), 0);
}
}
我需要一些帮助来理解这个问题。
在菱形阶段,您不会遍历整个地图。你只计算第一个平方(等于espace
)。
像这样更改循环终止条件:
for (int i = demiSpace; i < Terrain.SIZE; i = i + espace)
{
for (int j = demiSpace; j < Terrain.SIZE; j = j + espace)
{
var avg = Terrain.HeightMap[i + demiSpace, j + demiSpace] +
Terrain.HeightMap[i + demiSpace, j - demiSpace] +
Terrain.HeightMap[i - demiSpace, j + demiSpace] +
Terrain.HeightMap[i - demiSpace, j - demiSpace];
avg /= 4;
Terrain.HeightMap[i, j] = Normalize(avg + r.Next() % decalage);
}
}
此外,您永远不会调整随机变量 (decalage
),随着 espace
.