blob: 6c37714e7745674ab3848dfefe9d62bcde7fae15 [file] [log] [blame]
package test0580;
import ecosim.model.DefaultLocationModel;
import ecosim.model.LocationModel;
import ecosim.model.MapModel;
/**
* @author Ben Hutchison
*
*/
public class DiamondSquareTerrainGenerator implements MapGenerator
{
//number of halving recursive subdivisons to cover map
int _subdivisions;
//both width and height = 2^_subdivisions + 1 (ie square map)
int _width, _height;
d
LocationModel[][] _map;
/* (non-Javadoc)
* @see ecosim.model.map.MapGenerator#generateLocation(int, int, ecosim.model.MapModel)
*/
public LocationModel generateLocation(int i, int j, MapModel mapModel)
{
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see ecosim.model.map.MapGenerator#setSize(int, int)
*/
public void setSize(int width, int height)
{
_subdivisions = Math.max(ceilLogBase2(width), ceilLogBase2(height));
//diamond-square alg needs map size == power of 2 plus one; select next suitable size
_width = powerOf2(_subdivisions) + 1;
_height = powerOf2(_subdivisions) + 1;
_map = new LocationModel[_width][_height];
generateMap();
}
void generateMap() {
int lod = _subdivisions;
for (int i = 0; i < lod; ++ i) {
int q = 1 << i, r = 1 << (lod - i), s = r >> 1;
for (int j = 0; j < divisions; j += r)
for (int k = 0; k < divisions; k += r)
diamond (j, k, r, rough);
if (s > 0)
for (int j = 0; j <= divisions; j += s)
for (int k = (j + s) % r; k <= divisions; k += r)
square (j - s, k - s, r, rough);
rough *= roughness;
}
}
void diamond(int x, int y, int side, double scale) {
if (side > 1) {
int half = side / 2;
double avg = (terrain[x][y] + terrain[x + side][y] +
terrain[x + side][y + side] + terrain[x][y + side]) * 0.25;
terrain[x + half][y + half] = avg + rnd () * scale;
}
}
void square (int x, int y, int side, double scale) {
int half = side / 2;
double avg = 0.0, sum = 0.0;
if (x >= 0)
{ avg += terrain[x][y + half]; sum += 1.0; }
if (y >= 0)
{ avg += terrain[x + half][y]; sum += 1.0; }
if (x + side <= divisions)
{ avg += terrain[x + side][y + half]; sum += 1.0; }
if (y + side <= divisions)
{ avg += terrain[x + half][y + side]; sum += 1.0; }
terrain[x + half][y + half] = avg / sum + rnd () * scale;
}
public static int ceilLogBase2(int value) {
if (value <= 1)
return 0;
int exponent = 1;
value--;
while ((value = value >> 1) != 0)
exponent++;
return exponent;
}
public static int powerOf2(int exponent) {
int value = 1;
while (exponent-- > 0)
value = value << 1;
return value;
}
public static void main(String[] args)
{
System.out.println("1: "+ceilLogBase2(1));
System.out.println("2: "+ceilLogBase2(2));
System.out.println("3: "+ceilLogBase2(3));
System.out.println("4: "+ceilLogBase2(4));
System.out.println("5: "+ceilLogBase2(5));
System.out.println("-3: "+ceilLogBase2(3));
System.out.println("1024: "+ceilLogBase2(1024));
System.out.println("1023: "+ceilLogBase2(1023));
System.out.println("1025: "+ceilLogBase2(1025));
System.out.println("1 "+powerOf2(1));
System.out.println("2 "+powerOf2(2));
System.out.println("3 "+powerOf2(3));
}
}