1 package test0580;
2 
3 import ecosim.model.DefaultLocationModel;
4 import ecosim.model.LocationModel;
5 import ecosim.model.MapModel;
6 
7 
8 /**
9  * @author Ben Hutchison
10  *
11  */
12 public class DiamondSquareTerrainGenerator implements MapGenerator
13 {
14 	//number of halving recursive subdivisons to cover map
15 	int _subdivisions;
16 
17 	//both width and height = 2^_subdivisions + 1 (ie square map)
18 	int _width, _height;
19 
20 	d
21 
22 	LocationModel[][] _map;
23 
24 	/* (non-Javadoc)
25 	 * @see ecosim.model.map.MapGenerator#generateLocation(int, int, ecosim.model.MapModel)
26 	 */
generateLocation(int i, int j, MapModel mapModel)27 	public LocationModel generateLocation(int i, int j, MapModel mapModel)
28 	{
29 
30 		// TODO Auto-generated method stub
31 		return null;
32 	}
33 	/* (non-Javadoc)
34 	 * @see ecosim.model.map.MapGenerator#setSize(int, int)
35 	 */
setSize(int width, int height)36 	public void setSize(int width, int height)
37 	{
38 		_subdivisions = Math.max(ceilLogBase2(width), ceilLogBase2(height));
39 
40 		//diamond-square alg needs map size == power of 2 plus one; select next suitable size
41 		_width = powerOf2(_subdivisions) + 1;
42 		_height = powerOf2(_subdivisions) + 1;
43 
44 		_map = new LocationModel[_width][_height];
45 
46 		generateMap();
47 	}
48 
generateMap()49 	void generateMap() {
50 		int lod = _subdivisions;
51 		for (int i = 0; i < lod; ++ i) {
52 		      int q = 1 << i, r = 1 << (lod - i), s = r >> 1;
53 		      for (int j = 0; j < divisions; j += r)
54 		        for (int k = 0; k < divisions; k += r)
55 		          diamond (j, k, r, rough);
56 		      if (s > 0)
57 		        for (int j = 0; j <= divisions; j += s)
58 		          for (int k = (j + s) % r; k <= divisions; k += r)
59 		            square (j - s, k - s, r, rough);
60 		      rough *= roughness;
61 		    }
62 	}
63 
diamond(int x, int y, int side, double scale)64 	void diamond(int x, int y, int side, double scale) {
65 		if (side > 1) {
66 		      int half = side / 2;
67 		      double avg = (terrain[x][y] + terrain[x + side][y] +
68 		        terrain[x + side][y + side] + terrain[x][y + side]) * 0.25;
69 		      terrain[x + half][y + half] = avg + rnd () * scale;
70 		    }
71 
72 	}
73 
square(int x, int y, int side, double scale)74 	void square (int x, int y, int side, double scale) {
75 	    int half = side / 2;
76 	    double avg = 0.0, sum = 0.0;
77 	    if (x >= 0)
78 	    { avg += terrain[x][y + half]; sum += 1.0; }
79 	    if (y >= 0)
80 	    { avg += terrain[x + half][y]; sum += 1.0; }
81 	    if (x + side <= divisions)
82 	    { avg += terrain[x + side][y + half]; sum += 1.0; }
83 	    if (y + side <= divisions)
84 	    { avg += terrain[x + half][y + side]; sum += 1.0; }
85 	    terrain[x + half][y + half] = avg / sum + rnd () * scale;
86 	  }
87 
88 
ceilLogBase2(int value)89 	public static int ceilLogBase2(int value) {
90 		if (value <= 1)
91 			return 0;
92 		int exponent = 1;
93 		value--;
94 		while ((value = value >> 1) != 0)
95 			exponent++;
96 		return exponent;
97 	}
powerOf2(int exponent)98 	public static int powerOf2(int exponent) {
99 		int value = 1;
100 		while (exponent-- > 0)
101 			value = value << 1;
102 		return value;
103 	}
104 
105 
main(String[] args)106 	public static void main(String[] args)
107 	{
108 		System.out.println("1: "+ceilLogBase2(1));
109 		System.out.println("2: "+ceilLogBase2(2));
110 		System.out.println("3: "+ceilLogBase2(3));
111 		System.out.println("4: "+ceilLogBase2(4));
112 		System.out.println("5: "+ceilLogBase2(5));
113 		System.out.println("-3: "+ceilLogBase2(3));
114 		System.out.println("1024: "+ceilLogBase2(1024));
115 		System.out.println("1023: "+ceilLogBase2(1023));
116 		System.out.println("1025: "+ceilLogBase2(1025));
117 
118 		System.out.println("1 "+powerOf2(1));
119 		System.out.println("2 "+powerOf2(2));
120 		System.out.println("3 "+powerOf2(3));
121 	}
122 
123 }
124