Sunteți pe pagina 1din 8

//

//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//
//

SSMS.C
Solar System Motion Simulator
This is an early version of the IGMS, in the first stages of development.
The simulator "engine", which is now simply in main() rather than in
a separate core function, is essentially the same as it is in future
versions of the simulator. Also remaining are the display features (zoom,
3D rotation capabilities, print-mode, tracking, etc.)
You will notice that not long into the simulation a 0.5 Msun star
(particle #10, "Wormwood" in remarks) comes careening into the Solar
System and captures Earth. Modifying the parameters of this particle
make for some interesting variations on this theme. Also, try setting
ptrack = 4 to lock on to the Earth particle to see a demonstration of
planetary retrograde motion.
The EGAVGA.BGI file must be included in the same directory as this file
for graphics to function.
Units
1 sdu
1 smu
1 stu

#include
#include
#include
#include
#include
#include
#define
#define
#define
#define
#define
#define
#define
void
void
void
void
void
void
void
void
void
void

are not
= 10^10
= 10^29
= 10^5

the same as in IGMS.


m
kg
s

<stdio.h>
<graphics.h>
<stdlib.h>
<conio.h>
<math.h>
<ctype.h>
G 0.000667
maxp 10
sccx 320
sccy 240
zinc 1.5
sinc 1.5
rinc 5 * 0.0174532

//universal gravitational constant


//maximum particles supportable
//x-coordinate of center of screen
//y-coordinate of center of screen
//zoom step factor
//shift increment
//rotation increment angle

input(void);
//finds user input and routes appropriately
drawparticles(int gorder, int style); //draw or erase all particles
pause(void);
//holds simulation during user pause
imagezoom(int zdir);
//0 = zoom in; 1 = zoom out
imageshift(int sdir);
//shifts image horizontally
changedelay(int ddir);
//increases or decreases delay
displayinfo(void);
//displays simulation statistics
clearinfo(void);
//clears displayinfo() display
printmode(void);
//special color/style for using PrintScrn
imagerotate(int rdir);
//rotates image

float t;
float timestep = 1;
int nump = maxp;
char com;
float centx = 0;
float centy = 0;
float centz = 0;
float offx = 0;
float offy = 0;
float rota = 0;

//time
//time increment
//number of particles
//user input variable
//x-coordinate of effective center of screen
//y-coordinate of effective center of screen
//z-coordinate of effective center of screen
//x-axis distance from center and tracked particle
//y-axis distance from center and tracked particle
//x-y rotation

float rotb = 0;
float rotc = 0;
float zoom = 1;
int ptrack = 1;
int exitflag = 0;
int pauseflag = 0;
int displayflag = 0;
long delay = 0;
int tracers = 1;
int particlestyle = 0;
int drawfreq = 10;

//x-z rotation
//y-z rotation
//zoom factor
//tracked particle ID
//flags exit command
//flags pause
//flags display info
//steps in timing loop delay
//flags tracers
//appearance of particles 0=point 1=cross 2=circle
//redraw particles every drawfreq timesteps

float x[maxp + 1];


float y[maxp + 1];
float z[maxp + 1];
float vx[maxp + 1];
float vy[maxp + 1];
float vz[maxp + 1];
float ax[maxp + 1];
float ay[maxp + 1];
float az[maxp + 1];
float m[maxp + 1];
int c[maxp + 1];
int c2[maxp + 1];
float gx[maxp + 1];
float gy[maxp + 1];

//x-coordinate
//y-coordinate
//z-coordinate
//x-axis velocity
//y-axis velocity
//z-axis velocity
//x-axis acceleration
//y-axis acceleration
//z-axis acceleration
//mass
//pixel color
//tracer color
//graphical x-coordinate
//graphical y-coordinate

int main(void)
{
int p1, p2;
float dx, dy, dz;
float D;
float A;
long n, a;
float maxt = 200000;

//particle IDs
//distance between particles along axes
//resultant distance between particles
//resultant acceleration
//counting variables
//auto-termination time
//increase this to make the simulation last longer

int gdriver = DETECT, gmode, errorcode;


initgraph(&gdriver, &gmode, "EGAVGA.BGI");
x[0] = y[0] = 0;
if (drawfreq < timestep) drawfreq = timestep;
if (drawfreq % (int)timestep != 0) drawfreq += abs((drawfreq % (int)timestep)
- (int)timestep);

x[1] = 0; y[1] = 0; vx[1] = 0; vy[1] = -0.00000015; m[1] = 19.89; c[1] = 1


4; c2[1] = 8; //Sun
x[2]
x[3]
x[4]
x[5]
x[6]
x[7]
x[8]
x[9]

=
=
=
=
=
=
=
=

x[1]
x[1]
x[1]
x[1]
x[1]
x[1]
x[1]
x[1]

+
+
+
+
+

5.7;
10.8;
14.9;
22.8;
77.8;
142.4;
287.2;
449.9;

m[2]
m[3]
m[4]
m[5]
m[6]
m[7]
m[8]
m[9]

=
=
=
=
=
=
=
=

0.00000330;
0.0000487;
0.00005974;
0.00000642;
0.01899;
0.00568;
0.000866;
0.00103;

c[2]
c[3]
c[4]
c[5]
c[6]
c[7]
c[8]
c[9]

=
=
=
=
=
=
=
=

13;
14;
9;
4;
7;
14;
3;
3;

//Mercury
//Venus
//Earth
//Mars
//Jupiter
//Saturn
//Uranus
//Neptune

x[10] = 57; y[10] = 760; vx[10] = 0; vy[10] = -0.022; m[10] = 10; c[10] = 15;
c2[10] = 8;
//Wormwood
for (n = 2; n < 10; n ++) //Sets up planets in circular orbits
{
vx[n] = 0; y[n] = 0; c2[n] = 8;
vy[n] = (sqrt(G * m[1] / fabs(x[n] - x[1])));
if (x[n] > x[1]) vy[n] = -vy[n];
}
for (n = 1; n <= 10; n ++) z[n] = vz[n] = 0;

t = 0;
do
{
if ((t == (long)t) && ((long)t % drawfreq == 0)) drawparticles(0, particle
style);
if (ptrack > 0) {centx = x[ptrack] + offx; centy = y[ptrack] + offy;}

/track
if ((t == (long)t) && ((long)t % drawfreq == 0)) drawparticles(1, particle
style);
if ((int)t == floor(t)); gotoxy(11,1); printf("%.0f", t);

//print time

for (p1 = 1; p1 <= nump; p1 ++)


{
ax[p1] = ay[p1] = 0;
for (p2 = 1; p2 <= nump; p2 ++)
//determine acceleration
{
if (p1 != p2)
{
dx = x[p2] - x[p1];
dy = y[p2] - y[p1];
dz = z[p2] - z[p1];
D = sqrt(pow(dx, 2) + pow(dy, 2) + pow(dz, 2));
A = G * m[p2] / pow(D, 2);
ax[p1] += dx * A / D;
ay[p1] += dy * A / D;
az[p1] += dz * A / D;
}
}
}
for (n = 1; n < delay; n ++);
for (p1 = 1; p1 <= nump; p1++)
{
vx[p1] += ax[p1] * timestep;
vy[p1] += ay[p1] * timestep;
x[p1] += vx[p1] * timestep;
y[p1] += vy[p1] * timestep;

//delay

//accelerate
//move

}
if (kbhit()) input();
if (!exitflag) t += timestep;
if (t >= maxt) exitflag = 1;
} while (!exitflag);
gotoxy(38, 1); printf("simulation terminated by user at %.0f", t);
getch();
closegraph();
return 0;
}
/*******************************************************************/
void input(void)
{
com = getch();
//gotoxy(1,2); printf("%c = %d", com, com);
if (com == 27) exitflag = 1; else exitflag = 0;
if ((com == '-') || (com == '_')) changedelay(0);
if ((com == '+') || (com == '=')) changedelay(1);
if ((com == 'i') || (com == 'I')) imagezoom(0);
if ((com == 'o') || (com == 'O')) imagezoom(1);
if (com == 72) imageshift(1);
if (com == 75) imageshift(2);
if (com == 77) imageshift(3);
if (com == 80) imageshift(4);
if ((com == ',') || (com == '<')) imagerotate(0);
if ((com == '.') || (com == '>')) imagerotate(1);
if ((com == 'l') || (com == 'L')) imagerotate(2);
if ((com == ';') || (com == ':')) imagerotate(3);
if (com == 'p')
imagerotate(4);
if ((com == '[') || (com == '{')) imagerotate(5);
if ((com == 'c') || (com == 'C')) {clearviewport(); drawparticles(1, particle
style);}
if ((com == ' ') && (!pauseflag)) pause();
if ((com == '/') || (com == '?')) {displayflag = 1; pause();}
if ((com == 't') || (com == 'T')) tracers = !tracers;
if ((com == 'a') || (com == 'A')) printmode();
return;
}
/*******************************************************************/
void drawparticles(int gorder, int style)
{
int p1;
int color;
//float offax,
//float offay,
//float offaz,
float transx0,
float transx1,
float transx2,

offbx, offcx;
offby, offcy;
offbz, offcz;
transy0, transz0;
transy1, transz1;
transy2, transz2;

for (p1 = 1; p1 <= nump; p1++)


{
if (gorder == 1)

{
transx0 = x[p1] - centx;
transy0 = y[p1] - centy;
transz0 = z[p1] - centz;
transx1 = transx0 * cos(rota) + transy0 * sin(rota);
transy1 = transy0 * cos(rota) - transx0 * sin(rota);
transx2 = transx1 * cos(rotb) + transz0 * sin(rotb);
transz1 = transz0 * cos(rotb) - transx1 * sin(rotb);
transy2 = transy1 * cos(rotc) + transz1 * sin(rotc);
//transz2 = transz1 * cos(rotc) + transy1 * sin(rotc); //not used
gx[p1] = zoom * (transx2) + sccx;
gy[p1] = zoom * (transy2) + sccy;
color = c[p1];
if (getbkcolor() == 15)
{
if (color == 15) color = 0;
//if (color == 14)) color = 6;
if (color == 7) color = 0;
}
}
if (gorder == 0) color = c2[p1];
if ((gorder == -1) || (gorder == 0) && (tracers == 0)) color = 0;
if (gorder == -2) color = 15;
//draw
if (style == 0) putpixel (gx[p1], gy[p1], color);
if (style == 1)
{
putpixel (gx[p1], gy[p1], color);
putpixel (gx[p1] + 1, gy[p1], color);
putpixel (gx[p1] - 1, gy[p1], color);
putpixel (gx[p1], gy[p1] + 1, color);
putpixel (gx[p1], gy[p1] - 1, color);
}
if ((style == 2) || (style == 3))
{
setcolor(color);
setfillstyle(1, color);
circle(gx[p1], gy[p1], 2);
if (style == 3) floodfill(gx[p1], gy[p1], color);
}
}
return;
}
/*******************************************************************/
void pause(void)
{
pauseflag = 1;
do
{
if (displayflag) displayinfo();
input();
} while ((com != ' ') && (exitflag == 0));

if ((displayflag == 1) && (exitflag == 0)) clearinfo();


if (tracers == 2) tracers = 1;
pauseflag = 0;
displayflag = 0;
return;
}
/*******************************************************************/
void imagezoom(int zdir)
{
if ((!zdir) && (zoom < 1000)) zoom *= zinc;
if ((zdir) && (zoom > 0.01)) zoom /= zinc;
clearviewport();
drawparticles(1, particlestyle);
return;
}
/*******************************************************************/
void imageshift(int sdir)
{
if (sdir == 1) offy -= sinc / zoom;
if (sdir == 2) offx -= sinc / zoom;
if (sdir == 3) offx += sinc / zoom;
if (sdir == 4) offy += sinc / zoom;
centx = x[ptrack] + offx; centy = y[ptrack] + offy;
if (tracers == 1) {tracers = 2; clearviewport();}
drawparticles(-1, particlestyle);
drawparticles(1, particlestyle);
if ((!pauseflag) && (tracers == 2)) tracers = 1;
return;
}
/*******************************************************************/
void changedelay(int ddir)
{
if (ddir)
{
if ((delay > 0) && (delay < 4000000)) delay *= 2;
if (delay == 0) delay = 100;
}
else
{
if (delay > 100) delay /= 2;
if (delay == 100) delay = 0;
}
return;
}
/*******************************************************************/
void displayinfo(void)
{
if (timestep >= 1)
{
gotoxy(1, 1); printf("
time: %.0f
", t);
gotoxy(1, 3); printf("timestep: %.0f
", timestep);
}

else
{
gotoxy(1, 1); printf("
time: %.3f
gotoxy(1, 3); printf("timestep: %.3f
}
gotoxy(1, 2); printf("
%.3f yr
gotoxy(1, 4); printf(" delay: %ld
gotoxy(1, 5); printf("
zoom: %.0f\%
gotoxy(1, 6); printf("x center: %.2f
gotoxy(1, 7); printf("y center: %.2f
gotoxy(1, 8); printf("a rotate: %.0f
gotoxy(1, 9); printf("b rotate: %.0f
gotoxy(1, 10); printf("c rotate: %.0f
gotoxy(1, 11); printf("tracking: %d
gotoxy(1, 12); printf("drawfreq: %d
return;

", t);
", timestep);
", t * 0.00031688);
", delay);
", zoom * 100);
", centx);
", centy);
", rota / 0.0174532);
", rotb / 0.0174532);
", rotc / 0.0174532);
", ptrack);
", drawfreq);

}
/*******************************************************************/
void clearinfo(void)
{
int n;
gotoxy(1,1);
for (n = 1; n <= 12; n++) printf("
\n");
return;
}
/*******************************************************************/
void printmode(void)
{
int printmodestyle;
if (!particlestyle) printmodestyle = 1;
else printmodestyle = particlestyle;
drawparticles(-1, particlestyle);
setbkcolor(15);
drawparticles(1, printmodestyle);
setpalette(15, 0);
setpalette(8, 7);
setcolor(15);
drawparticles(-2, printmodestyle);
getch();
setbkcolor(0);
setpalette(8, 56);
setpalette(15, 63);
drawparticles(-1, printmodestyle);
return;
}
/*******************************************************************/
void imagerotate(int rdir)
{
if (tracers == 1) {tracers = 2; clearviewport();}
if
if
if
if
if

(rdir
(rdir
(rdir
(rdir
(rdir

==
==
==
==
==

0)
1)
2)
3)
4)

rota
rota
rotb
rotb
rotc

+=
-=
+=
-=
+=

rinc;
rinc;
rinc;
rinc;
rinc;

if (rdir == 5) rotc -= rinc;


if (rota < -179 * 0.0174532) rota = 180 * 0.0174532;
if (rotb < -179 * 0.0174532) rotb = 180 * 0.0174532;
if (rotc < -179 * 0.0174532) rotc = 180 * 0.0174532;
if (rota > 184 * 0.0174532) rota = -175 * 0.0174532;
if (rotb > 184 * 0.0174532) rotb = -175 * 0.0174532;
if (rotc > 184 * 0.0174532) rotc = -175 * 0.0174532;
drawparticles(-1, particlestyle);
drawparticles(1, particlestyle);
return;
}

S-ar putea să vă placă și