|
|
878d83 |
|
|
|
878d83 |
|
|
|
878d83 |
typedef struct {
|
|
|
878d83 |
HMap *hmap;
|
|
|
878d83 |
HMap *wmap;
|
|
|
878d83 |
} Water;
|
|
|
878d83 |
|
|
|
878d83 |
|
|
|
878d83 |
|
|
|
878d83 |
void waterInit(Water *w, HMap *hmap, HMap *wmap) {
|
|
|
878d83 |
w->hmap = hmap;
|
|
|
878d83 |
w->wmap = wmap;
|
|
|
878d83 |
for(int i = 0; i < HMAP_SIZE; ++i)
|
|
|
878d83 |
for(int j = 0; j < HMAP_SIZE; ++j)
|
|
|
878d83 |
w->wmap->map[i][j] = w->hmap->map[i][j];
|
|
|
878d83 |
}
|
|
|
878d83 |
|
|
|
878d83 |
|
|
|
878d83 |
void waterRain(Water *w, double k) {
|
|
|
878d83 |
for(int i = 0; i < HMAP_SIZE; ++i)
|
|
|
878d83 |
for(int j = 0; j < HMAP_SIZE; ++j)
|
|
|
878d83 |
w->wmap->map[i][j] += k;
|
|
|
878d83 |
}
|
|
|
878d83 |
|
|
|
878d83 |
|
|
|
878d83 |
void waterFall(Water *w, double wk, double hk) {
|
|
|
878d83 |
static const int di[4] = { -1, 1, 0, 0 };
|
|
|
878d83 |
static const int dj[4] = { 0, 0, -1, 1 };
|
|
|
878d83 |
|
|
|
878d83 |
hmapCopy(w->hmap);
|
|
|
878d83 |
hmapCopy(w->wmap);
|
|
|
878d83 |
for(int i = 0; i < HMAP_SIZE; ++i) {
|
|
|
878d83 |
for(int j = 0; j < HMAP_SIZE; ++j) {
|
|
|
878d83 |
double dz = w->wmap->old[i][j] - w->hmap->old[i][j];
|
|
|
878d83 |
dz *= 0.25;
|
|
|
878d83 |
if (dz > 0) {
|
|
|
878d83 |
double sum = 0;
|
|
|
878d83 |
double v[4] = {};
|
|
|
878d83 |
for(int k = 0; k < 4; ++k) {
|
|
|
878d83 |
int ii = ((i+di[k]) + HMAP_SIZE)%HMAP_SIZE;
|
|
|
878d83 |
int jj = ((j+dj[k]) + HMAP_SIZE)%HMAP_SIZE;
|
|
|
878d83 |
double vv = w->wmap->old[i][j] - w->wmap->old[ii][jj];
|
|
|
878d83 |
if (vv < 0) vv = 0;
|
|
|
878d83 |
//vv = vv*vv*vv;
|
|
|
878d83 |
v[k] = vv;
|
|
|
878d83 |
sum += vv;
|
|
|
878d83 |
}
|
|
|
878d83 |
double s = wk*sum;
|
|
|
878d83 |
if (s > dz) s = dz;
|
|
|
878d83 |
if (sum > 1e-10) {
|
|
|
878d83 |
for(int k = 0; k < 4; ++k) {
|
|
|
878d83 |
int ii = ((i+di[k]) + HMAP_SIZE)%HMAP_SIZE;
|
|
|
878d83 |
int jj = ((j+dj[k]) + HMAP_SIZE)%HMAP_SIZE;
|
|
|
878d83 |
double vv = v[k]/sum*s;
|
|
|
878d83 |
w->wmap->map[ii][jj] += v[k]/sum*s;
|
|
|
878d83 |
w->wmap->map[i][j] -= vv;
|
|
|
878d83 |
double dh = w->hmap->old[i][j] - w->hmap->map[ii][jj];
|
|
|
878d83 |
dh *= 0.25;
|
|
|
878d83 |
if (dh > 0) {
|
|
|
878d83 |
vv = vv*hk;
|
|
|
878d83 |
if (vv > dh) vv = dh;
|
|
|
878d83 |
w->hmap->map[ii][jj] += vv;
|
|
|
878d83 |
w->hmap->map[i][j] -= vv;
|
|
|
878d83 |
}
|
|
|
878d83 |
}
|
|
|
878d83 |
}
|
|
|
878d83 |
}
|
|
|
878d83 |
}
|
|
|
878d83 |
}
|
|
|
878d83 |
}
|
|
|
878d83 |
|
|
|
878d83 |
|
|
|
878d83 |
double waterEvaporation(Water *w, double k) {
|
|
|
878d83 |
double sum;
|
|
|
878d83 |
for(int i = 0; i < HMAP_SIZE; ++i) {
|
|
|
878d83 |
for(int j = 0; j < HMAP_SIZE; ++j) {
|
|
|
878d83 |
double dz = w->wmap->map[i][j] - w->hmap->map[i][j];
|
|
|
878d83 |
if (dz < 0) dz = 0;
|
|
|
878d83 |
if (dz > k) dz = k;
|
|
|
878d83 |
sum += dz;
|
|
|
878d83 |
w->wmap->map[i][j] -= dz;
|
|
|
878d83 |
}
|
|
|
878d83 |
}
|
|
|
878d83 |
return sum;
|
|
|
878d83 |
}
|
|
|
878d83 |
|
|
|
878d83 |
|
|
|
878d83 |
void waterCycle(Water *w, double fallK, double erosionK, double evaK) {
|
|
|
878d83 |
double sum = waterEvaporation(w, evaK);
|
|
|
878d83 |
waterRain(w, sum/(HMAP_SIZE*HMAP_SIZE));
|
|
|
878d83 |
for(int i = 0; i < 10; ++i) {
|
|
|
878d83 |
waterFall(w, fallK/10, erosionK/10);
|
|
|
878d83 |
printf(".");
|
|
|
878d83 |
fflush(stdout);
|
|
|
878d83 |
}
|
|
|
878d83 |
printf("\n");
|
|
|
878d83 |
}
|