'----------------------------------------------------------
'Listing 6 'Global cluster'
#include <graphics.h>
#include <stdlib.h> //rand,random,randomize
#include <math.h> //sqrt
#include <stdio.h> //sprintf
#include <conio.h> //kbhit,getch
float c[60],x[60],y[60],z[60],dc[60]; //colr, posn & distance
float vx[60], vy[60], vz[60], vi[60]; //velocity comps & vel
float far dsq[60][60], a[60][60]; //dist. sqrd & accel. i to j
float far ax[60][60], ay[60][60], az[60][60]; // x/y/z accels
float atx[60], aty[60], atz[60]; // x/y/z comps of total accel
float xm = 480, ym = 240; //x & y mean position
float eyexr=400, eyexl =240, eyey =0, eyez =-600; //eyes' posn
float xl, xr, yb, zf, df = 1000, vf = 300, maxd = 500;
float g = 1, ti=.01; //gravity, time interval
int n, m, r, i, j, ns = 60, nr, rm;
float tx, tvx, ty, tvy, tz, tvz, xd, yd, zd, d;
char msg[40]; //for formatting screen printing
void setscreen(); //Declare VGA 640x480 setup procedure
void main() { //main module
setscreen(); randomize(); //set VGA and randomise on timer
for (i = 0; i < ns; i++) { //allocate posns and vels
c[i] = i % 15 + 1; //individual star colour
x[i] = rand() % 160 - 80; y[i] = rand() % 160 - 80;
z[i] = rand() % 160 - 80;//ie. in x/y/z range +-80/+-80/+-80
dc[i]=sqrt(x[i]*x[i]+y[i]*y[i]+z[i]*z[i]);//dist from centre
if(dc[i] < 20) dc[i] = 20; //avoid excess veloc. at centre
rm = int(df / sqrt(dc[i])); //random number maximum
vx[i] = (float(random(rm) -rm/2))/ vf; //ie. velocity comps
vy[i] = (float(random(rm) -rm/2))/ vf; //...in range +-rm/2
vz[i] = (float(random(rm) -rm/2))/ vf;
}
do { r++; //start of outer program loop
cleardevice(); //each time, clear screen and zero totals
nr = 0; tx = 0; tvx = 0; ty = 0; tvy = 0; tz = 0; tvz = 0;
for (i = 0; i < ns; i++) { //get 'creep' of central group
if (dc[i] < maxd) { //if star was still in range to maxd...
dc[i] =sqrt(x[i]*x[i] +y[i]*y[i]+ z[i]*z[i]); //check again
if (dc[i] < maxd) { nr++; //count number STILL in range
setcolor(c[i]); //set star colour & plot velocity versus..
circle (dc[i], 130 -vi[i]*100, 3);//..distance with circle
tx += x[i]; ty += y[i]; tz += z[i]; //total dist & vel...
tvx += vx[i]; tvy += vy[i]; tvz += vz[i]; //...comps of nr
} //end of if (dc <... ie. STILL in range
} //end of if (dc <... ie. previously in range
} //end of for (i = 0;...
setcolor (15); line (320, 0, 320, 380); //draw background
line (0, 30, 640, 30); line (0, 130, 640, 130);
line (0, 380, 640, 380); rectangle (0, 0, 639, 479);
line (maxd, 40, maxd, 120);
sprintf(msg, "Run %d, %d stars left", r, nr);
outtextxy(140, 10, msg);
sprintf(msg, "distance maxd"); outtextxy(maxd-70, 70, msg);
sprintf(msg, "velocity = 1");
outtextxy(530, 20, msg); outtextxy(530, 370, msg);
sprintf(msg, "velocity = 0");
outtextxy(530, 120, msg); outtextxy(530, 470, msg);
sprintf(msg, "M"); outtextxy(325, 200, msg);
sprintf(msg, "I"); outtextxy(325, 220, msg);
sprintf(msg, "R"); outtextxy(325, 240, msg);
outtextxy(325, 260, msg); outtextxy(325, 300, msg);
sprintf(msg, "O"); outtextxy (325, 280, msg);
tx /= nr; ty /= nr; tz /= nr; //average position of nr
tvx /= nr; tvy /= nr; tvz /= nr; //average velocity of nr
for (i = 0; i < ns; i++) { //adjust only stars...
if (dc[i] < maxd) { //...still in range...
x[i] -= tx; y[i] -= ty; z[i] -= tz; //...for position...
vx[i] -= tvx; vy[i] -= tvy; vz[i] -= tvz; //...and velocity
} //end of if (dc <... ie. STILL in range
} //end of for (i = 0;....
for (n = 0; n < 640; n++) { //inner loop - 640 units of time
if (kbhit()) n = 641; //any key escapes inner & outer loops
for (m = 0; m < 100; m++) { //innermost loop, 100 x ti(.01)
for (i = 0; i < ns - 1; i++) { //for each star ...
if (dc[i] < maxd) { //...still in range...
for (j = i+1; j < ns; j++) { //...with all higher...
if (dc[j] < maxd) { //...numbered stars still in range
xd=x[j]-x[i]; yd=y[j]-y[i]; zd=z[j]-z[i];// x/y/z diffs
dsq[i][j]= xd*xd + yd*yd + zd*zd;//separation dist sqrd
if(dsq[i][j] < .1) dsq[i][j] = .1; //stop excess accels
d = sqrt(dsq[i][j]);//separation distance between i & j
a[i][j] = g / dsq[i][j]; //gravity accel of i towards j
ax[i][j] = a[i][j] * xd / d; //x comp of i towards j...
ax[j][i] = -ax[i][j];//...and j to i (equal & opposite)
ay[i][j] = a[i][j] * yd / d; //y comp of i towards j...
ay[j][i] = -ay[i][j];//...and j to i (equal & opposite)
az[i][j] = a[i][j] * zd / d; //z comp of i towards j...
az[j][i] = -az[i][j];//...and j to i (equal & opposite)
} // end of if (dc[j] < maxd)
} //end for (j = i+1;...
} // end of if (dc[i] < maxd)
} //end for (i = 0;...
for (i = 0; i < ns; i++) { //now process every star...
if (dc[i] < maxd) { //..still in range...
atx[i] = 0; aty[i] = 0; atz[i] = 0;//zero the total accel
for (j = 0; j < ns; j++) { //add accel towards all...
if (dc[j] < maxd) { //...OTHER stars still in range...
if (i != j ) { atx[i] += ax[i][j]; //cumul. x accel
aty[i] += ay[i][j]; //cumul. y accel
atz[i] += az[i][j]; //cumul. z accel
} //end of if (i != j ) ie. NOT towards self
} // end of if (dc[j] < maxd) ie. OTHER star
} //end for (j = 0; j < ns;
vx[i] += atx[i] * ti; //adjust x velocity comp. of i
x[i] += vx[i] * ti; //adjust x position comp. of i
vy[i] += aty[i] * ti; //adjust y velocity comp. of i
y[i] += vy[i] * ti; //adjust y position comp. of i
vz[i] += atz[i] * ti; //adjust z velocity comp. of i
z[i] += vz[i] * ti; //adjust z position comp. of i
} // end of if (dc[i] < maxd) ie. every star
} //end for (i = 0; i < ns...
} //end of for (m = 1;... innermost loop 100 x ti
for (i = 0; i < ns; i++) { //now stereo plot each star
if (dc[i] < maxd) { //..still in range...
zf = eyez / (eyez - z[i]); //z factor for perspective
xr = eyexr +(x[i]+xm -eyexr) * zf;//screen x for right eye
xl = eyexl +(x[i]+xm -eyexl) * zf; //screen x for left eye
yb = eyey + (y[i]+ym -eyey) * zf; //screen y for both eyes
if (xr > 320) putpixel(xr, yb, c[i]);//plot right eye view
if (xl > 320) putpixel(640-xl, yb, c[i]);//left - mirrored
vi[i] =sqrt(vx[i]*vx[i] +vy[i]*vy[i] +vz[i]*vz[i]);//veloc
putpixel (n, 480 - vi[i] * 100, c[i]); //veloc versus time
} // end of if (dc[i] < maxd)
} //end for (i = 0; i < ns ie. stars in range plotted
} //end of for (n = 0;... inner loop (640 x unit time)
} while(n < 641); //end do {... outer loop
closegraph();//shut down graphics when escaped from outer loop
}; //end main() //program ends
void setscreen(void){ //define procedure to get graphics screen
int gdriver = VGA, gmode=VGAHI, errorcode; //set VGA 640x480
if(registerfarbgidriver(EGAVGA_driver_far)<0) exit(1);//driver
initgraph(&gdriver, &gmode, "..//bgi"); //initialize graphics
errorcode = graphresult(); //read result of initialization
if (errorcode != grOk) //if an error occurred
{ printf("Graphics error; %s\n", grapherrormsg(errorcode));
printf("Press any key to halt;"); getch();
exit(1); } //return with error code
}; //end setscreen()
Click to download DSTARS6.ZIP for source listing
and executable version of this program.
|