No Description

collide.c 4.9KB

    //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> #include <math.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); break; 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); int d = 1000; //distance from galaxy to collision point int w = conf1.imgW; int h = conf1.imgH; double angleRad = 3.1415926535 * (0.5 - angle / 360); int dx = d * cos(angleRad); int dy = d * sin(angleRad); point_t pos1; pos1.x = w/2 + dx; pos1.y = h/2 - dy; point_t pos2; pos2.x = w/2 - dx; pos2.y = h/2 - dy; point_t vel1; vel1.x = -vel * cos(angleRad); vel1.y = vel * sin(angleRad); point_t vel2; vel2.x = vel * cos(angleRad); vel2.y = vel * sin(angleRad); //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; }