2010-06-20 2 views
1

Я пытаюсь получить простой генератор фрактальной фракции 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; 
} 

}

Я не уверен, что это не так, спасибо за любую помощь.

ответ

3

Семя игнорируется, поэтому сгенерированные случайные числа не являются случайными.

Используйте один экземпляр Random и передайте его для разбивки вместо одного экземпляра на сегмент.

Edit:

Другое дело, попробуйте уменьшить диапазон от диапазона * 0,5 вместо диапазона * 0,2, так как также вдвое горизонтальная длина. При использовании меньшего коэффициента первая итерация имеет слишком большое влияние. Если, например, первый раскол ставит точку центра вверх, вы получите единственный холм, так как следующие итерации слишком слабы для создания вторичных холмов.

+0

Семя, выбранное нулевым конструктором «Случайный», достаточно, но постоянное семя может быть полезно для тестирования. – trashgod

+0

Кажется работать, я буду работать над кодом рендеринга и посмотреть, как он выглядит. – phpscriptcoder

+0

@trashgod это действительно так. Проблема была неправильным фактором. Но по-прежнему неплохо использовать многие «случайные» экземпляры. – Stefan

Смежные вопросы