Commit e3a7b92e authored by Stephen D's avatar Stephen D
Browse files

Added engine for simulating collision between galaxies

parent 31204b40
galaxysim: main.c qdbmp.c qdbmp.h
gcc -o galaxysim main.c qdbmp.c -lm -fopenmp
collide: collide.c
gcc -o collide collide.c
//Takes 2 galaxies as input.
//Sets them up so that they will collide with each other.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
//types that we need
//TODO: put these in their own file
typedef struct RigidMass
{
long mass;
double vx, vy;
double x, y;
double dvx, dvy;
double tick_time;
} RigidMass_t;
typedef struct config
{
int nStars;
int imgW, imgH;
int savePeriod;
int iteration;
char saveFile[255];
} config_t;
typedef struct point
{
double x;
double y;
} point_t;
void loadGalaxy(char *filename, config_t *conf, RigidMass_t **stars)
{
FILE *fp;
fp = fopen(filename, "r");
//read config first
fread(conf, sizeof(config_t), 1, fp);
//read stars next
*stars = malloc(sizeof(RigidMass_t) * conf->nStars);
fread(*stars, sizeof(RigidMass_t), conf->nStars, fp);
//don't forget to close!
fclose(fp);
}
//calculates the position of the center of mass of the galaxy
//IMPORTANT: THIS FUNCTION ASSUMES ALL STARS HAVE THE SAME MASS!
point_t calculateCoM(RigidMass_t *stars, int nStars)
{
double totalX = 0;
double totalY = 0;
for(int i = 0; i < nStars; i++)
{
totalX += stars[i].x;
totalY += stars[i].y;
}
point_t out;
out.x = totalX / nStars;
out.y = totalY / nStars;
return out;
}
//calculates the velocity of the center of mass of a galaxy
//IMPORTANT: THIS FUNCTION ASSUMES ALL STARS HAVE THE SAME MASS!
point_t calculateCoV(RigidMass_t *stars, int nStars)
{
double totalVx = 0;
double totalVy = 0;
for(int i = 0; i < nStars; i++)
{
totalVx += stars[i].vx;
totalVy += stars[i].vy;
}
point_t out;
out.x = totalVx / nStars;
out.y = totalVy / nStars;
return out;
}
//Shifts a galaxy by a certain x, y, vx, and vy.
//IMPORTANT: THIS FUNCTION ASSUMES ALL STARS HAVE THE SAME MASS!
void shiftGalaxy(RigidMass_t *stars, int nStars, double dx, double dy, double dvx, double dvy)
{
for(int i = 0; i < nStars; i++)
{
stars[i].x += dx;
stars[i].y += dy;
stars[i].vx += dvx;
stars[i].vy += dvy;
}
}
void saveGalaxy(RigidMass_t *stars1, RigidMass_t *stars2,
int n1, int n2,
config_t conf1, char* filename)
{
RigidMass_t *all;
all = malloc(sizeof(RigidMass_t) * (n1 + n2));
memcpy(all, stars1, sizeof(RigidMass_t) * n1); //copy stars1 to all
memcpy(&all[n1], stars2, sizeof(RigidMass_t) * n2); //stars2 to all
conf1.nStars = n1 + n2;
conf1.iteration = 0;
FILE *fp;
fp = fopen(filename, "w");
fwrite(&conf1, sizeof(config_t), 1, fp);
fwrite(all, sizeof(RigidMass_t), n1 + n2, fp);
fclose(fp);
}
void prnHelp(char *name)
{
printf("Usage: %s [OPTIONS] SOURCE1 SOURCE2 DEST\r\n", name);
printf("Available options:\r\n");
printf("d ANG\t - Angle of collision (degrees)\r\n");
printf("v VEL\t - Velocity of collision\r\n");
exit(1);
}
//too lazy for arrays when there's only two elements in each one
config_t conf1, conf2;
RigidMass_t *stars1;
RigidMass_t *stars2;
int main(int argc, char **argv)
{
printf("\t\tStephen's Gravitational Engine\r\n");
printf("\t\t\tCollision catalyzer\r\n");
printf("\t\t\twww.scd31.com\r\n");
double vel = 10; //velocity of both galaxies. (One galaxy will be vel/2)
double angle = 90; //angle of the collision (degrees)
int success = 0;
char c;
//do not process the last 3 arguments. those are the filenames
while((c = getopt(argc - 3, argv, "d:v:")) != -1)
{
success = 1;
switch(c)
{
case 'd':
angle = atoi(optarg);
break;
case 'v':
vel = atoi(optarg);
default:
prnHelp(argv[0]);
}
}
if(0) //temporary
{
prnHelp(argv[0]);
}
//at this point, we know we can start working on the problem
printf("Loading %s...\r\n", argv[argc - 3]);
loadGalaxy(argv[argc - 3], &conf1, &stars1);
printf("Loading %s...\r\n", argv[argc - 2]);
loadGalaxy(argv[argc - 2], &conf2, &stars2);
//THESE SHOULD BE CALCULATED!
//Hardcoded only temporarily!
/*point_t pos1; pos1.x = -500; pos1.y = -500;
point_t pos2; pos2.x = 1500; pos2.y = -500;
point_t vel1; vel1.x = 10; vel1.y = 10;
point_t vel2; vel2.x = -10; vel2.y = 10;*/
point_t pos1; pos1.x = 250; pos1.y = 250;
point_t pos2; pos2.x = 750; pos2.y = 750;
point_t vel1;
point_t vel2;
//Galaxy 1
point_t c1 = calculateCoM(stars1, conf1.nStars);
point_t v1 = calculateCoV(stars1, conf1.nStars);
printf("Galaxy 1 is at %f,%f moving at %f,%f\r\n", c1.x, c1.y, v1.x, v1.y);
shiftGalaxy(stars1, conf1.nStars,
pos1.x - c1.x, pos1.y - c1.y,
vel1.x - v1.x, vel1.y - v1.y);
//Galaxy 2
//I regret not using arrays
point_t c2 = calculateCoM(stars2, conf2.nStars);
point_t v2 = calculateCoV(stars2, conf2.nStars);
printf("Galaxy 2 is at %f,%f moving at %f,%f\r\n", c2.x, c2.y, v2.x, v2.y);
shiftGalaxy(stars2, conf2.nStars,
pos2.x - c2.x, pos2.y - c2.y,
vel2.x - v2.x, vel2.y - v2.y);
saveGalaxy(stars1, stars2,
conf1.nStars, conf2.nStars,
conf1, argv[argc - 1]);
return 0;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment