分形地形生成问题
我正在尝试让一个简单的 1D 分形地形生成器用于 2D 游戏。但由于某种原因,它总是要么形成一座小山、一座山谷,要么形成一条平线,如线段 (x1, x2, y2) 的输出所示:
0.0 4.0 -0.02771158460407615
4.0 8.0 -0.052252824583875854
8.0 12.0 -0.07902285133059965
12.0 16.0 -0.10555908121086155
16.0 20.0 -0.14254585245303525
20.0 24.0 -0.18045065070426206
24.0 28.0 -0.22501139415695381
28.0 32.0 -0.2710783915066824
32.0 36.0 -0.329316259372778
36.0 40.0 -0.3892923247211977
40.0 44.0 -0.4553572198140616
44.0 48.0 -0.5231035764770061
48.0 52.0 -0.5959274130549632
52.0 56.0 -0.6656219786904637
56.0 60.0 -0.744915288029726
60.0 64.0 -0.8218171898484998
64.0 68.0 -0.7981756789319197
68.0 72.0 -0.7738770779295611
72.0 76.0 -0.7451672391318471
76.0 80.0 -0.7157435744314788
80.0 84.0 -0.6724228309158163
84.0 88.0 -0.6295400852776468
88.0 92.0 -0.5843134728466224
92.0 96.0 -0.5360614060509056
96.0 100.0 -0.4688005196071708
100.0 104.0 -0.4002685625504277
104.0 108.0 -0.3345027903832193
108.0 112.0 -0.26818546486875805
112.0 116.0 -0.20032715588508002
116.0 120.0 -0.1335249071978246
120.0 124.0 -0.06698448902698972
124.0 128.0 0.0
0.0 4.0 0.018955623904205618
4.0 8.0 0.04081565391393612
8.0 12.0 0.05924247389764535
12.0 16.0 0.07763715222906489
16.0 20.0 0.09633847099282224
20.0 24.0 0.11312197407020168
24.0 28.0 0.12839143489843127
28.0 32.0 0.14414813672698973
32.0 36.0 0.1274505909321103
36.0 40.0 0.10774014148758147
40.0 44.0 0.08156728603267831
44.0 48.0 0.05819330004014197
48.0 52.0 0.02490146503362223
52.0 56.0 -0.005671514173097783
56.0 60.0 -0.030944276269930564
60.0 64.0 -0.053593376577440344
64.0 68.0 -0.06844103124397849
68.0 72.0 -0.08240392823800813
72.0 76.0 -0.09384053047264221
76.0 80.0 -0.10452653202924991
80.0 84.0 -0.10675174062525229
84.0 88.0 -0.10997901222951861
88.0 92.0 -0.1120510737650679
92.0 96.0 -0.11166174606669571
96.0 100.0 -0.10035737979486
100.0 104.0 -0.08817859848319709
104.0 108.0 -0.07771753902059923
108.0 112.0 -0.07037700764073251
112.0 116.0 -0.05267698984443657
116.0 120.0 -0.033583174260327434
120.0 124.0 -0.016020212145163026
124.0 128.0 0.0
范围是从 -1 到 1。
以下是用于生成一个级别。
public void generate()
{
long seed = System.currentTimeMillis();
int numLineSegments = width/4;
Vector<LineSegment> result = new Vector<LineSegment>(numLineSegments);
result.add(new LineSegment(0, 0, width, 0, seed, 1, 1));
int currentLevel = 1;
while(result.size() < numLineSegments)
{
Iterator<LineSegment> itr = result.iterator();
Vector<LineSegment> tmp = new Vector<LineSegment>(numLineSegments);
while(itr.hasNext())
{
LineSegment l = itr.next();
if(l.level == currentLevel)
{
LineSegment[] parts = l.subdivide();
itr.remove();
tmp.add(parts[0]);
tmp.add(parts[1]);
}
}
result.clear();
Iterator<LineSegment> tmpItr = tmp.iterator();
while(tmpItr.hasNext())
{
result.add(tmpItr.next());
}
currentLevel++;
}
for(Object o : result.toArray())
{
System.err.println(((LineSegment)o).x1+" "+((LineSegment)o).x2+" "+((LineSegment)o).y2);
}
}
public class LineSegment {
public double x1;
public double y1;
public double x2;
public double y2;
private Random r;
public long seed;
public int level;
public double range;
public LineSegment(double x1, double y1, double x2, double y2, long seed, int level, double range)
{
r = new Random();
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.seed = seed;
this.level = level;
this.range = range;
}
public LineSegment[] subdivide()
{
double midpoint = (x1 + x2)/2;
LineSegment[] t = new LineSegment[2];
double rand;
if(level == 1)
rand = r.nextDouble() * 2 - 1;
else
{
rand = ((y1+y2)/2) + (r.nextDouble() * (range * 2) - range);
}
double l1x1 = x1;
double l1y1 = y1;
double l1x2 = midpoint;
double l1y2 = rand;
double l2x1 = midpoint;
double l2y1 = rand;
double l2x2 = x2;
double l2y2 = y2;
LineSegment l1 = new LineSegment(l1x1, l1y1, l1x2, l1y2, seed, level + 1, range * 0.2);
LineSegment l2 = new LineSegment(l2x1, l2y1, l2x2, l2y2, seed, level + 1, range * 0.2);
t[0] = l1;
t[1] = l2;
return t;
}
我
不确定出了什么问题,感谢您的帮助。
I'm trying to get a simple 1D fractal terrain generator to work for a 2D game. But for some reason it always either makes a hill, a valley, or a flat line, as seen in this output of the segments (x1, x2, y2):
0.0 4.0 -0.02771158460407615
4.0 8.0 -0.052252824583875854
8.0 12.0 -0.07902285133059965
12.0 16.0 -0.10555908121086155
16.0 20.0 -0.14254585245303525
20.0 24.0 -0.18045065070426206
24.0 28.0 -0.22501139415695381
28.0 32.0 -0.2710783915066824
32.0 36.0 -0.329316259372778
36.0 40.0 -0.3892923247211977
40.0 44.0 -0.4553572198140616
44.0 48.0 -0.5231035764770061
48.0 52.0 -0.5959274130549632
52.0 56.0 -0.6656219786904637
56.0 60.0 -0.744915288029726
60.0 64.0 -0.8218171898484998
64.0 68.0 -0.7981756789319197
68.0 72.0 -0.7738770779295611
72.0 76.0 -0.7451672391318471
76.0 80.0 -0.7157435744314788
80.0 84.0 -0.6724228309158163
84.0 88.0 -0.6295400852776468
88.0 92.0 -0.5843134728466224
92.0 96.0 -0.5360614060509056
96.0 100.0 -0.4688005196071708
100.0 104.0 -0.4002685625504277
104.0 108.0 -0.3345027903832193
108.0 112.0 -0.26818546486875805
112.0 116.0 -0.20032715588508002
116.0 120.0 -0.1335249071978246
120.0 124.0 -0.06698448902698972
124.0 128.0 0.0
0.0 4.0 0.018955623904205618
4.0 8.0 0.04081565391393612
8.0 12.0 0.05924247389764535
12.0 16.0 0.07763715222906489
16.0 20.0 0.09633847099282224
20.0 24.0 0.11312197407020168
24.0 28.0 0.12839143489843127
28.0 32.0 0.14414813672698973
32.0 36.0 0.1274505909321103
36.0 40.0 0.10774014148758147
40.0 44.0 0.08156728603267831
44.0 48.0 0.05819330004014197
48.0 52.0 0.02490146503362223
52.0 56.0 -0.005671514173097783
56.0 60.0 -0.030944276269930564
60.0 64.0 -0.053593376577440344
64.0 68.0 -0.06844103124397849
68.0 72.0 -0.08240392823800813
72.0 76.0 -0.09384053047264221
76.0 80.0 -0.10452653202924991
80.0 84.0 -0.10675174062525229
84.0 88.0 -0.10997901222951861
88.0 92.0 -0.1120510737650679
92.0 96.0 -0.11166174606669571
96.0 100.0 -0.10035737979486
100.0 104.0 -0.08817859848319709
104.0 108.0 -0.07771753902059923
108.0 112.0 -0.07037700764073251
112.0 116.0 -0.05267698984443657
116.0 120.0 -0.033583174260327434
120.0 124.0 -0.016020212145163026
124.0 128.0 0.0
The range is from -1 to 1.
Here is the code used to generate a level.
public void generate()
{
long seed = System.currentTimeMillis();
int numLineSegments = width/4;
Vector<LineSegment> result = new Vector<LineSegment>(numLineSegments);
result.add(new LineSegment(0, 0, width, 0, seed, 1, 1));
int currentLevel = 1;
while(result.size() < numLineSegments)
{
Iterator<LineSegment> itr = result.iterator();
Vector<LineSegment> tmp = new Vector<LineSegment>(numLineSegments);
while(itr.hasNext())
{
LineSegment l = itr.next();
if(l.level == currentLevel)
{
LineSegment[] parts = l.subdivide();
itr.remove();
tmp.add(parts[0]);
tmp.add(parts[1]);
}
}
result.clear();
Iterator<LineSegment> tmpItr = tmp.iterator();
while(tmpItr.hasNext())
{
result.add(tmpItr.next());
}
currentLevel++;
}
for(Object o : result.toArray())
{
System.err.println(((LineSegment)o).x1+" "+((LineSegment)o).x2+" "+((LineSegment)o).y2);
}
}
public class LineSegment {
public double x1;
public double y1;
public double x2;
public double y2;
private Random r;
public long seed;
public int level;
public double range;
public LineSegment(double x1, double y1, double x2, double y2, long seed, int level, double range)
{
r = new Random();
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.seed = seed;
this.level = level;
this.range = range;
}
public LineSegment[] subdivide()
{
double midpoint = (x1 + x2)/2;
LineSegment[] t = new LineSegment[2];
double rand;
if(level == 1)
rand = r.nextDouble() * 2 - 1;
else
{
rand = ((y1+y2)/2) + (r.nextDouble() * (range * 2) - range);
}
double l1x1 = x1;
double l1y1 = y1;
double l1x2 = midpoint;
double l1y2 = rand;
double l2x1 = midpoint;
double l2y1 = rand;
double l2x2 = x2;
double l2y2 = y2;
LineSegment l1 = new LineSegment(l1x1, l1y1, l1x2, l1y2, seed, level + 1, range * 0.2);
LineSegment l2 = new LineSegment(l2x1, l2y1, l2x2, l2y2, seed, level + 1, range * 0.2);
t[0] = l1;
t[1] = l2;
return t;
}
}
I'm not sure what's wrong, thanks for any help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
种子被忽略,因此生成的随机数并不是那么随机。
使用
Random
的单个实例并将其传递给细分,而不是每个段都有一个实例。编辑:
另一件事,尝试将范围减小 range*0.5 而不是 range*0.2,因为水平长度也减半。通过使用较小的因子,第一次迭代的影响过大。例如,如果第一次分割将中心点放在上方,您将得到一个山丘,因为下一次迭代太“弱”而无法创建次要山丘。
The seed gets ignored, thus the generated random numbers aren't all that random.
Use a single instance of
Random
and pass it on to subdivide instead of having one instance per segment.Edit:
Another thing, try to decrease the range by range*0.5 instead of range*0.2, since the horizontal length is also halved. By using a smaller factor the first iteration has a overly large influence. If, for example the first split puts the center point way up, you will get a single hill, since the next iterations are too 'weak' to create secondary hills.