#include #include #include #include #include #include #define DEBUGlog(f, args...) \ ; //fprintf(stderr, "in %s: "f, __FUNCTION__, ## args) #define W_HEIGHT 480 #define W_WIDTH 640 /* N body problem */ static int NUM_BODY = 3; //static float Gravitation = 6.67e-11 ; //static float delta = 100; //static float FIELD = 2e11; static float Gravitation = 1.0f; // ? static float delta = 0.05f; // static float FIELD = 400.0f; // -100 ~ 100 static const float eps = 1.5f; typedef struct { /* star's parameter. */ float weight; float a[3]; /* acceleration */ float v[3]; /* velocity */ float r[3]; /* position */ /* for SDL. */ SDL_Rect rect; } body; body *stars_old, *stars_new; void start(void); __code initialize(int num); __code randomInit(SDL_Surface *screen, int num); __code starsInit(SDL_Surface *screen, int num); __code loop(int count, SDL_Surface *screen, int num); __code compute(int count, SDL_Surface *screen, int num); __code nextTurn(int count, SDL_Surface *screen, int num); __code moveCenter(int count, SDL_Surface *screen, int num); __code CenteringVelocity(int count, SDL_Surface *screen, int num); int main(int argc, char **argv) { int ch; while ((ch = getopt(argc, argv, "s:g:")) != -1) { switch (ch) { case 's': delta = atof(optarg); break; case 'g': Gravitation = atof(optarg); break; case '?': default: break; } } start(); return 0; } void start() { goto initialize(NUM_BODY); } __code finish(int ret) { DEBUGlog("Gravity = %e\n", Gravitation); DEBUGlog("FLT_MAX = %e\n", FLT_MAX); DEBUGlog("FLT_MAX_EXP = %d\n", FLT_MAX_EXP); DEBUGlog("FLT_MIN = %e\n", FLT_MIN); DEBUGlog("FLT_MIN_EXP = %d\n", FLT_MIN_EXP); DEBUGlog("FLT_EPSILON = %e\n", FLT_EPSILON); free(stars_old); free(stars_new); exit(ret); } __code initialize(int num) { SDL_Surface *screen; /* malloc. */ stars_old = malloc( sizeof(body)*num ); stars_new = malloc( sizeof(body)*num ); if (stars_old==NULL||stars_new==NULL){ perror("malloc"); goto finish(1); } /* SDL initialization. */ if(SDL_Init(SDL_INIT_VIDEO) < 0){ //Could we start SDL_VIDEO? fprintf(stderr,"Couldn't init SDL"); //Nope, output to stderr and quit exit(1); } screen = SDL_SetVideoMode(W_WIDTH, W_HEIGHT, 32, SDL_HWSURFACE | SDL_RESIZABLE); //Create a 640x480x32 resizable window atexit(SDL_Quit); //Now that we're enabled, make sure we cleanup goto starsInit(screen, num); } __code starsInit0(SDL_Surface *screen, int num) { int i; srandom(time(NULL)); for (i=0; i dx/dt = v * dv = a*dt => dv/dt = a * a = F/m; * F = F1 + F2 + ... + Fn * Fi = G m1m2/r^2 * */ __code compute(int count, SDL_Surface *screen, int num) { int i; /* a is accel this planet receive now. */ stars_old[count].a[0]=stars_old[count].a[1]=stars_old[count].a[2]=0.0f; DEBUGlog("count=%d\n", count); for (i=0; iformat, 0x00,0x00,0x00)); SDL_FillRect(screen, &stars_new[count].rect, SDL_MapRGB(screen->format, 0xff,0x88,0x33)); //SDL_BlitSurface(screen, &stars_old[count].rect, screen, &stars_new[count].rect); goto loop(++count, screen, num); } /* it is executed after all bodies parameter is computed. */ __code nextTurn(int count, SDL_Surface *screen, int num) { body *tmp; tmp = stars_old; stars_old = stars_new; stars_new = tmp; SDL_UpdateRect(screen, 0, 0, 0, 0); goto loop(0, screen, num); } /* +--------+-----------+ | v | | +-----------+ | | | loop | | | +-----+-----+ | | | | | +-----v-----+ | | + compute +-----+ | +-----+-----+ count++ | | | | count==num | +-----v-----+ | | nextTurn | | +-----+-----+ | | count=0 +--------+ */