// PROGRAM dla #include "TrueBASIC.h" #include "csgraphics.h" int main(); void initial(int site[][201], int *L); void grow_cluster(int site[][201], int L); void walk(int site[][201], int L, int *x, int *y, int *R0, int *N); void test(int site[][201], int L, int x, int y, double r, int *R0, int *N, char* onperimeter); int main() { int L, site[201][201]; GWopen(0); initial(site, &L); grow_cluster(site, L); GWquit(); return 0; } void initial(int site[][201], int *L) { int x, y, Itmp1_, Itmp2_; float xwin, ywin; char Stmp1_[_LBUFF_]; rnd(-1); printf("L = "); fgets(Stmp1_, _LBUFF_, stdin); sscanf(Stmp1_, "%d", L); compute_aspect_ratio((float)((*L)+2), &xwin, &ywin); GWindow(-xwin, -ywin, xwin, ywin); GWrect((float)(-(*L)-0.5), (float)(-(*L)-0.5), (float)((*L)+0.5), (float)((*L)+0.5)); for(Itmp1_ = -100; Itmp1_ <= 100; ++Itmp1_) for(Itmp2_ = -100; Itmp2_ <= 100; ++Itmp2_) site[Itmp1_ + 100][Itmp2_ + 100] = 0; // すべての格子点を初期化 for(x = -(*L); x <= (*L); ++x) for(y = -(*L); y <= (*L); ++y) GWsetpxl((float)(x), (float)(y), BLACK); GWsetpen(RED, -1, -1, -1); GWsetmrk(6, 1.0f, RED, -1, 4); GWanchor(1); } void grow_cluster(int site[][201], int L) { int N, R0, x, y; double theta; R0 = 3; // 原点から R0 の距離の位置に粒子を置く site[100][100] = 1; // 種 N = 1; // クラスターに含まれる粒子数 GWputmrk(0.0f, 0.0f); do { // 新しい粒子の初期位置をランダムに選ぶ theta = 2*pi*rnd(0); x = (int)(R0*cos(theta)); y = (int)(R0*sin(theta)); walk(site, L, &x, &y, &R0, &N); // ランダムウォーク } while(!TBkeyinput()); } void walk(int site[][201], int L, int *x, int *y, int *R0, int *N) // クラスターの周辺の点に達するか // クラスターから遠く離れすぎるまでランダムウォークを続ける { int step; double r, random; char onperimeter[_LBUFF_]; do { strcpy(onperimeter, "no"); r = sqrt((double)(*x)*(*x) + (double)(*y)*(*y)); if(r < (*R0) + 1) // クラスターの周辺の点に到達したかどうかを調べる test(site, L, *x, *y, r, R0, N, onperimeter); step = (int)(r - (*R0)) - 1; // 大きな歩幅 if(step < 1) step = 1; if(strcmp(onperimeter, "no") == 0) { random = rnd(0); if(random < 0.25) (*x) += step; else if(random < 0.5) (*x) -= step; else if(random < 0.75) (*y) += step; else (*y) -= step; } } while(!((strcmp(onperimeter, "yes") == 0) || (r > 2*(*R0)))); } void test(int site[][201], int L, int x, int y, double r, int *R0, int *N, char* onperimeter) { double sum; char Stmp1_[_LBUFF_]; sum = site[x + 100][y + 101] + site[x + 100][y + 99] + site[x + 101][y + 100] + site[x + 99][y + 100]; if(sum > 0) // 周辺の点に到達 { site[x + 100][y + 100] = 1; strcpy(onperimeter, "yes"); if(abs(x) <= L && abs(y) <= L) { GWputmrk((float)(x), (float)(y)); ++(*N); GWsetogn(0, -2); sprintf(Stmp1_, "N = %4d", (*N)); GWputtxt((float)(-L), (float)(L+1), Stmp1_); GWflush(-2); GWsetogn(0, 1); } else { GWquit(); // 箱の外 exit(0); } if(r >= (*R0) - 1) (*R0) = (int)(r+2); } }