00001
00002
00003 #include <iostream>
00004 #include <fstream>
00005 #include <stdlib.h>
00006 #include <algorithm>
00007 #include <sstream>
00008 #include <valarray>
00009 #include <time.h>
00010 #include <math.h>
00011 #include "r250.h"
00012 #include "grid.h"
00013
00014
00016 float RandG(int, int) {return float(dr250());}
00017
00019 bool operator<(const xyC& a, const xyC& b)
00020 {
00021 return a.height < b.height;
00022 };
00023
00028 std::string itoa(int value) {
00029
00030 enum { kMaxDigits = 35 };
00031
00032 std::string buf;
00033
00034 buf.reserve( kMaxDigits );
00035
00036 int quotient = value;
00037
00038
00039 do {
00040 buf += "0123456789"[ std::abs(quotient%10) ];
00041 quotient /= 10;
00042 } while ( quotient );
00043
00044
00045 if ( value < 0) buf += '-';
00046
00047 std::reverse( buf.begin(), buf.end() );
00048 return buf;
00049 }
00050
00051
00052 TGrid::TGrid (void)
00053 {
00054 time_t currentTime;
00055 int seed = time(¤tTime);
00056
00057 r250_init(29);
00058
00059 clearArrays();
00060 }
00061
00062 TGrid::~TGrid ()
00063 {
00064
00065 }
00066
00067
00068 void TGrid::clearArrays(void)
00069 {
00070 for (int x=0; x<=N; x++)
00071 for (int y=0; y<=N; y++)
00072 {
00073 CellArray[x][y]=0;
00074 CellArrayF[x][y]=0;
00075 CellArrayL[x][y]=0;
00076 CellCount[x][y].Position=0;
00077 CellCount[x][y].NCellsAll=0;
00078 }
00079 }
00080
00081 inline float TGrid::f3 (float delta, float x0, float x1, float x2)
00082 {
00083 return(x0+x1+x2)/3.+delta*RandG (0,1);
00084 }
00085
00086 inline float TGrid::f4 (float delta, float x0, float x1, float x2, float x3)
00087 {
00088 return(x0+x1+x2+x3)/4.+delta*RandG (0,1);
00089 }
00090
00091 void TGrid::createMountain (int Iterations,int Sigma,float Hurst,bool Addition)
00092 {
00093
00094 float delta=Sigma;
00095 CellArrayF[0][0]=delta*RandG (0,1);
00096 CellArrayF[0][N]=delta*RandG (0,1);
00097 CellArrayF[N][0]=delta*RandG (0,1);
00098 CellArrayF[N][N]=delta*RandG (0,1);
00099 int D=N;
00100 int d=N/2;
00101
00102 for (int stage=1; stage<=Iterations; stage++)
00103 {
00104 delta=delta*pow(0.5,0.5*Hurst);
00105
00106 for (int x=d; x<=(N-d);x+=D)
00107 for (int y=d; y<=(N-d);y+=D)
00108 CellArrayF[x][y]=f4(delta,CellArrayF[x+d][y+d],CellArrayF[x+d][y-d],CellArrayF[x-d][y+d],CellArrayF[x-d][y-d]);
00109
00110
00111 if (Addition==true)
00112 {
00113 for (int x=0; x<=N; x+=D)
00114 for (int y=0; y<=N; y+=D)
00115 CellArrayF[x][y]+= delta*RandG (0,1);
00116 }
00117
00118
00119 delta *= pow(0.5,0.5*Hurst);
00120
00121
00122 for (int x=d; x<=(N-d); x+=D)
00123 {
00124 CellArrayF[x][0]=f3(delta,CellArrayF[x+d][0],CellArrayF[x-d][0],CellArrayF[x][d]);
00125 CellArrayF[x][N]=f3(delta,CellArrayF[x+d][N],CellArrayF[x-d][N],CellArrayF[x][N-d]);
00126 CellArrayF[0][x]=f3(delta,CellArrayF[0][x+d],CellArrayF[0][x-d],CellArrayF[d][x]);
00127 CellArrayF[N][x]=f3(delta,CellArrayF[N][x+d],CellArrayF[N][x-d],CellArrayF[N-d][x]);
00128 }
00129
00130
00131 for (int x=d; x<=(N-d);x+=D)
00132 for (int y=D; y<=(N-d);y+=D)
00133 CellArrayF[x][y]=f4(delta,CellArrayF[x][y+d],CellArrayF[x][y-d],CellArrayF[x+d][y],CellArrayF[x-d][y]);
00134
00135 for (int x=D; x<=(N-d);x+=D)
00136 for (int y=d; y<=(N-d);y+=D)
00137 CellArrayF[x][y]=f4(delta,CellArrayF[x][y+d],CellArrayF[x][y-d],CellArrayF[x+d][y],CellArrayF[x-d][y]);
00138
00139
00140 if (Addition==true)
00141 {
00142 for (int x=0; x<=N; x+=D)
00143 for (int y=0; y<=N; y+=D)
00144 CellArrayF[x][y]+= delta*RandG (0,1);
00145
00146 for (int x=d; x<=(N-d); x+=D)
00147 for (int y=d; y<=(N-d); y+=D)
00148 CellArrayF[x][y]+= delta*RandG (0,1);
00149 }
00150 D=D/2;
00151 d=d/2;
00152 }
00153 }
00154
00155
00156 void TGrid::createWadi (float Grad, bool Parabel)
00157 {
00158 int Center=N/2;
00159 int DiffY;
00160 float gradient = Grad?tan(Grad/360.*2*3.14159):0.0;
00161
00162 if (Parabel==false)
00163 {
00164 for (int x=0;x<=N;x++)
00165 for (int y=0;y<=N;y++)
00166 {
00167 DiffY = Center-y;
00168
00169
00170 CellArrayL [x][y]= (-gradient*26 + abs(DiffY)*gradient)*5;
00171 if (abs(DiffY)<=25)
00172 { CellArrayL [x][y]=0.0;
00173 CellCount [x][y].Position='W';
00174 }
00175 if (Grad)
00176 {
00177 if (CellArrayL [x][y]>=100)
00178 { CellArrayL [x][y] =100;
00179 CellCount [x][y].Position='P';
00180 }
00181 if (DiffY>25 && CellArrayL [x][y]<100) CellCount [x][y].Position='N';
00182 if (DiffY<-25 && CellArrayL [x][y]<100) CellCount [x][y].Position='S';
00183 }
00184 else
00185 {
00186 if (DiffY>133) CellCount [x][y].Position='P';
00187 else if (DiffY>25) CellCount [x][y].Position='N';
00188 else if (DiffY>=-25) CellCount [x][y].Position='W';
00189 else if (DiffY>-134) CellCount [x][y].Position='S';
00190 else CellCount [x][y].Position='P';
00191 }
00192 }
00193
00194
00195 float* MemArrayL = new float [(N+1)*(N+1)];
00196 int smoother = 10;
00197 float counter = 0.0;
00198
00199 for (int x=0;x<=N;x++)
00200 for (int y=smoother;y<=N-smoother;y++)
00201 {
00202
00203 counter=0;
00204 for (int iz=-smoother; iz<=smoother; iz++)
00205 counter+= CellArrayL[x][y+iz];
00206
00207
00208 MemArrayL[x*(N+1)+y] = (1.0/(2.0*smoother+1.0))*counter;
00209 }
00210
00211 for (int x=0;x<=N;x++)
00212 for (int y=smoother;y<=N-smoother;y++)
00213 CellArrayL[x][y]=MemArrayL[x*(N+1)+y];
00214
00215 delete(MemArrayL);
00216 }
00217
00218
00219 else if (Parabel==true)
00220 {
00221 for (int x=0;x<=N;x++)
00222 for (int y=0;y<=N;y++)
00223 {
00224 DiffY = Center == y ? 1 : Center - y;
00225 CellArrayL [x][y]=(gradient/-100.0)*(DiffY*DiffY);
00226 }
00227 }
00228
00229 }
00230
00231
00232
00233 void TGrid::calculateElevation ()
00234 {
00235
00236 float sum_elevation = 0.0;
00237 for(int i = N/2-150; i<N/2+150; i++)
00238 for(int j = N/2-150; j<N/2+150; j++)
00239 sum_elevation += CellArrayF [i][j];
00240
00241
00242 for(int i = 0; i<=N; i++)
00243 for(int j = 0; j<=N; j++)
00244 CellArrayF [i][j] -= sum_elevation/float(300*300);
00245
00246
00247 for (int i=0;i<=N;i++)
00248 for (int j=0;j<=N;j++)
00249 CellArray [i][j] = CellArrayL [i][j] + CellArrayF [i][j];
00250
00251
00252 float* MemArray = new float [(N+1)*(N+1)];
00253 int smoother = 2;
00254 float counter;
00255
00256 for (int x=0; x<=N;x++)
00257 for (int y=0; y<=N;y++)
00258 {
00259 int a=0;
00260
00261 counter=0;
00262 for (int iz = -smoother; iz<= smoother; iz++)
00263 for (int is = -smoother; is<= smoother; is++)
00264 counter += CellArray[x+is][y+iz];
00265
00266
00267 MemArray[x*(N+1)+y]=(1.0/((2.0*smoother+1.0)*(2.0*smoother+1.0)))*counter;
00268 }
00269
00270 for (int x=smoother;x<=N-smoother;x++)
00271 for (int y=smoother;y<=N-smoother;y++)
00272 CellArray[x][y]=MemArray[x*(N+1)+y];
00273
00274 delete MemArray;
00275
00276 }
00277
00278
00279
00280 float flowinfo::getTotalContributing (flowinfo* receivingCell)
00281 {
00282 if (checked == false)
00283 {
00284 for (int c=0; c<contributing; c++)
00285 if (receivingCell != nbsFrom[c])
00286 total += nbsFrom[c]->getTotalContributing(this);
00287 checked = true;
00288 }
00289 return total*share;
00290 }
00291
00292
00293
00294 void flowinfo::setInflow (flowinfo* pCell)
00295 { nbsFrom[contributing++] = pCell;
00296 }
00297
00298
00299 void TGrid::countHigherCellsGIS (void)
00300 {
00301
00302
00303 float maxHeight = CellArray[N/2][N/2];
00304 float minHeight = CellArray[N/2][N/2];
00305 for (int x=0; x<=N; x++)
00306 for (int y=0; y<=N; y++)
00307 {
00308 maxHeight = CellArray[x][y]>maxHeight?CellArray[x][y]:maxHeight;
00309 minHeight = CellArray[x][y]<minHeight?CellArray[x][y]:minHeight;
00310 }
00311
00312 const float smalldiff = (maxHeight-minHeight)/100.0;
00313
00314
00315
00316 for (int x=0; x<=N; x++)
00317 for (int y=0; y<=N; y++)
00318 {
00319 float a[8];
00320 int nnbs = 0;
00321 flowinfo* myCell[8];
00322
00324 for (int i=-1; i<=1; i++)
00325 for (int j=-1; j<=1; j++)
00326 { if (x+i < 0 || x+i > N)
00327 continue;
00328 if ( y+j < 0 || y+j > N)
00329 continue;
00330 if (!i && !j)
00331 continue;
00332
00333
00334
00335
00336
00337
00338 float ak = CellArray[x+i][y+j]-CellArray[x][y];
00339 float gk = sqrt(i*i + j*j);
00340 if (ak) a[nnbs] = atan(gk/ak);
00341 else a[nnbs] = -3.14159/2.0;
00342 myCell[nnbs] = &dir[x+i][y+j];
00343
00344 nnbs++;
00345 }
00346
00348 float aMin = 0;
00349 int ties=-1;
00350 flowinfo* nbsTo[4];
00351 for (int n=0; n<nnbs; n++)
00352 { if (a[n]<aMin)
00353 { aMin=a[n];
00354 ties=0;
00355 nbsTo[ties] = myCell[n];
00356 }
00357 else if (a[n] == aMin)
00358 { ties++;
00359 nbsTo[ties] = myCell[n];
00360 }
00361 }
00362
00363
00364 for (int t=0; t<ties+1; t++)
00365 if (nbsTo[t] != &dir[x][y])
00366 nbsTo[t]->setInflow(&dir[x][y]);
00367
00368 if(ties>-1) dir[x][y].setShare(1.0/float(ties+1));
00369 }
00370
00371
00372
00373
00374 xyC* pDir = new xyC[(N+1)*(N+1)];
00375 for (int x=0; x<=N; x++)
00376 for (int y=0; y<=N; y++)
00377 {
00378 pDir[x*(N+1)+y].col = x;
00379 pDir[x*(N+1)+y].row = y;
00380 pDir[x*(N+1)+y].height = CellArray[x][y];
00381 }
00382
00383 std::sort(pDir, pDir+(N+1)*(N+1));
00384
00385
00387 for (long w=(N+1)*(N+1)-1; w>=0; w--)
00388 {
00389 int x = pDir[w].col; int y = pDir[w].row;
00390 float TC = dir[x][y].getTotalContributing(&dir[x][y]);
00391 CellCount [x][y].NCellsAll = TC<1.0?1.0:TC;
00392 }
00393 delete(pDir);
00394
00395 }
00396
00397
00398
00399 void TGrid::outputTestVariable(void)
00400 {
00401 char* fn = "TestVariable.txt";
00402 std::ofstream Ausgabe;
00403 Ausgabe.open(fn);
00404 for (int i=0;i<=N; i++)
00405 { for (int j=0; j<=N; j++)
00406 {
00407 Ausgabe<< CellArrayF[i][j];
00408 if (j<N) Ausgabe << "\t";
00409 }
00410 if (i<N) Ausgabe << std::endl;
00411 }
00412
00413 Ausgabe.close();
00414 }
00415
00416
00417 void TGrid::outputElevation(void)
00418 {
00419 char* fn = "Elevation.txt";
00420 std::ofstream Ausgabe;
00421 Ausgabe.open(fn);
00422 for (int i=0;i<=N; i++)
00423 { for (int j=0; j<=N; j++)
00424 {
00425 Ausgabe<< CellArray[i][j];
00426 if (j<N) Ausgabe << "\t";
00427 }
00428 if (i<N) Ausgabe << std::endl;
00429 }
00430
00431 Ausgabe.close();
00432 }
00433
00434
00435 void TGrid::outputContributing(void)
00436 {
00437 char* fn = "Contributing.txt";
00438 std::ofstream Ausgabe;
00439 Ausgabe.open(fn);
00440 for (int i=0;i<=N; i++)
00441 { for (int j=0; j<=N; j++)
00442 {
00443 Ausgabe << (CellCount[i][j]).NCellsAll;
00444 if (j<N) Ausgabe << "\t";
00445 }
00446 if (i<N) Ausgabe << std::endl;
00447 }
00448 Ausgabe.close();
00449 }
00450
00451
00452 void TGrid::writeFile(float slope, int r)
00453 {
00454 std::string filename = "Wadiscape_slope_";
00455 std::string tag = ".txt";
00456 filename += itoa(int(slope)) ;
00457 filename += "_";
00458 filename += itoa(r);
00459 filename += tag;
00460
00461 int center=N/2;
00462
00463 std::ofstream DataFile;
00464 DataFile.open(filename.c_str()) ;
00465 if (!DataFile)
00466 {
00467
00468 std::cerr<<"Die Ausgabedatei konnte nicht erfolgreich"
00469 " geˆffnet werden."<< std::endl;
00470 exit(0);
00471 }
00472 int xx = 150;
00473 for (int i=center-xx;i<center+xx;i++)
00474 {
00475 for (int j=center-xx;j<center+xx;j++)
00476 {
00477 DataFile<<i-(center-xx)<< "\t" << j-(center-xx)<< "\t"<< CellArray[i][j]<<"\t";
00478 DataFile<<CellCount[i][j].Position<<"\t";
00479 DataFile<<CellCount[i][j].NCellsAll<<"\t";
00480 DataFile<<slope;
00481 DataFile<<"\n";
00482 }
00483 }
00484 DataFile.close ();
00485
00486 }
00487
00488
00489