Last active
August 29, 2015 14:07
-
-
Save 9072997/61427a6eb4eec1378566 to your computer and use it in GitHub Desktop.
Gravity Sim
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
//#pragma warning(disable: 4996) | |
#include <stdlib.h> | |
#include <math.h> | |
#define NUMPOINTS 3 | |
#define STEPS 5000 | |
//#define G 6.673E-11 | |
#define G 5E-5 //bigger | |
#define CLOUDDIAMETER 1000 | |
#define MINMASS 1000 | |
#define MAXMASS 10000 | |
#define PROGRESS 1000 // interval | |
#define FILENAME "COM exclusive.csv" | |
struct pointMass { | |
double mass; | |
double x; // position | |
double y; | |
double vx; // velocity | |
double vy; | |
}; | |
struct point { | |
double x; | |
double y; | |
}; | |
int main(int argc, char *argv[]) { | |
FILE *fp; | |
struct pointMass point[NUMPOINTS]; | |
fp = fopen(FILENAME, "w"); | |
for (int np = 0; np < NUMPOINTS; np++) { // populate 100 point masses with data | |
struct pointMass *p; | |
p = &point[np]; | |
(*p).mass = (MINMASS + rand()) % (MAXMASS - MINMASS); | |
(*p).x = rand() % CLOUDDIAMETER; | |
(*p).y = rand() % CLOUDDIAMETER; | |
(*p).vx = 0; | |
(*p).vy = 0; | |
fprintf(fp, "X%i,Y%i,", np, np); | |
} | |
fprintf(fp, "\n"); | |
// end setup | |
for (int i = 0; i < STEPS; i++) { //foreaver ish | |
struct point scratchPoint[NUMPOINTS]; | |
if (i % PROGRESS == 0) printf("%d ", i / PROGRESS); // progress bar | |
for (int np = 0; np < NUMPOINTS; np++) { // for each point | |
double forceX; | |
double forceY; | |
double massX = 0; | |
double massY = 0; | |
double dist; | |
double force; | |
double dir; | |
struct pointMass *p; | |
struct point *sp; | |
struct pointMass com; | |
com.mass = 0; | |
p = &point[np]; | |
for (int nip = 0; nip < NUMPOINTS; nip++) { // check all influencing points | |
struct pointMass *ip; | |
ip = &point[nip]; // exerts force on p | |
if (nip == np) continue; // we don't influence ourselves (technicly the calcs would agree, so this is optional) | |
massX += (*ip).mass * (*ip).x; //http://hyperphysics.phy-astr.gsu.edu/hbase/cm.html | |
massY += (*ip).mass * (*ip).y; | |
com.mass += (*ip).mass; | |
} | |
com.x = massX / com.mass; | |
com.y = massY / com.mass; | |
dist = sqrt( | |
pow((*p).x - com.x, 2) + | |
pow((*p).y - com.y, 2) | |
); | |
force = G*(*p).mass*com.mass / pow(dist, 2); | |
dir = atan2(com.x - (*p).x, com.y - (*p).y); | |
forceX = force*cos(dir); | |
forceY = force*sin(dir); | |
//now we have forceX and forceY | |
sp = &scratchPoint[np]; | |
// update velocity (we can to this live b.c velocity dosent affecy gravity) | |
(*p).vx += forceX / (*p).mass; // f=ma a=delta v | |
(*p).vy += forceY / (*p).mass; | |
// update position (cant do this live b.c. it would affect later points) | |
(*sp).x = (*p).x + (*p).vx; | |
(*sp).y = (*p).y + (*p).vy; | |
fprintf(fp, "%f,%f,", (*sp).x, (*sp).y); | |
} | |
for (int np = 0; np < NUMPOINTS; np++) { // move scratch points to points for next time | |
struct pointMass *p; | |
struct point *sp; | |
p = &point[np]; | |
sp = &scratchPoint[np]; | |
(*p).x = (*sp).x; | |
(*p).y = (*sp).y; | |
} | |
fprintf(fp, "\n"); | |
} | |
puts("\n"); // it's just good form | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
//#pragma warning(disable: 4996) | |
#include <stdlib.h> | |
#include <math.h> | |
#define NUMPOINTS 3 | |
#define STEPS 5000 | |
//#define G 6.673E-11 | |
#define G 5E-5 //bigger | |
#define CLOUDDIAMETER 1000 | |
#define MINMASS 1000 | |
#define MAXMASS 10000 | |
#define PROGRESS 1000 // interval | |
#define FILENAME "COM inclusive.csv" | |
// future ideas http://www.sciencedirect.com/science/article/pii/S0019103513001942 | |
struct pointMass { | |
double mass; | |
double x; // position | |
double y; | |
double vx; // velocity | |
double vy; | |
}; | |
struct point { | |
double x; | |
double y; | |
}; | |
int main(int argc, char *argv[]) { | |
FILE *fp; | |
struct pointMass point[NUMPOINTS]; | |
fp = fopen(FILENAME, "w"); | |
for (int np = 0; np < NUMPOINTS; np++) { // populate 100 point masses with data | |
struct pointMass *p; | |
p = &point[np]; | |
(*p).mass = (MINMASS + rand()) % (MAXMASS - MINMASS); | |
(*p).x = rand() % CLOUDDIAMETER; | |
(*p).y = rand() % CLOUDDIAMETER; | |
(*p).vx = 0; | |
(*p).vy = 0; | |
fprintf(fp, "X%i,Y%i,", np, np); | |
} | |
fprintf(fp, "\n"); | |
// end setup | |
for (int i = 0; i < STEPS; i++) { //foreaver ish | |
struct point scratchPoint[NUMPOINTS]; | |
if (i % PROGRESS == 0) printf("%d ", i / PROGRESS); // progress bar | |
for (int np = 0; np < NUMPOINTS; np++) { // for each point | |
double forceX; | |
double forceY; | |
double massX = 0; | |
double massY = 0; | |
double dist; | |
double force; | |
double dir; | |
struct pointMass *p; | |
struct point *sp; | |
struct pointMass com; | |
com.mass = 0; | |
p = &point[np]; | |
for (int nip = 0; nip < NUMPOINTS; nip++) { // check all influencing points | |
struct pointMass *ip; | |
ip = &point[nip]; // exerts force on p | |
//disabled as per http://ccl.northwestern.edu/netlogo/models/N-Bodies | |
//if (nip == np) continue; // we don't influence ourselves (technicly the calcs would agree, so this is optional) | |
massX += (*ip).mass * (*ip).x; //http://hyperphysics.phy-astr.gsu.edu/hbase/cm.html | |
massY += (*ip).mass * (*ip).y; | |
com.mass += (*ip).mass; | |
} | |
com.x = massX / com.mass; | |
com.y = massY / com.mass; | |
dist = sqrt( | |
pow((*p).x - com.x, 2) + | |
pow((*p).y - com.y, 2) | |
); | |
force = G*(*p).mass*com.mass / pow(dist, 2); | |
dir = atan2(com.x - (*p).x, com.y - (*p).y); | |
forceX = force*cos(dir); | |
forceY = force*sin(dir); | |
//now we have forceX and forceY | |
sp = &scratchPoint[np]; | |
// update velocity (we can to this live b.c velocity dosent affecy gravity) | |
(*p).vx += forceX / (*p).mass; // f=ma a=delta v | |
(*p).vy += forceY / (*p).mass; | |
// update position (cant do this live b.c. it would affect later points) | |
(*sp).x = (*p).x + (*p).vx; | |
(*sp).y = (*p).y + (*p).vy; | |
fprintf(fp, "%f,%f,", (*sp).x, (*sp).y); | |
} | |
for (int np = 0; np < NUMPOINTS; np++) { // move scratch points to points for next time | |
struct pointMass *p; | |
struct point *sp; | |
p = &point[np]; | |
sp = &scratchPoint[np]; | |
(*p).x = (*sp).x; | |
(*p).y = (*sp).y; | |
} | |
fprintf(fp, "\n"); | |
} | |
puts("\n"); // it's just good form | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
//#pragma warning(disable: 4996) | |
#include <stdlib.h> | |
#include <math.h> | |
#define NUMPOINTS 3 | |
#define STEPS 5000 | |
//#define G 6.673E-11 | |
#define G 5E-5 //bigger | |
#define CLOUDDIAMETER 1000 | |
#define MINMASS 1000 | |
#define MAXMASS 10000 | |
#define PROGRESS 1000 // interval | |
#define FILENAME "simple.csv" | |
struct pointMass { | |
double mass; | |
double x; // position | |
double y; | |
double vx; // velocity | |
double vy; | |
}; | |
struct point { | |
double x; | |
double y; | |
}; | |
int main(int argc, char *argv[]) { | |
FILE *fp; | |
struct pointMass point[NUMPOINTS]; | |
fp = fopen(FILENAME, "w"); | |
for (int np = 0; np < NUMPOINTS; np++) { // populate 100 point masses with data | |
struct pointMass *p; | |
p = &point[np]; | |
(*p).mass = (MINMASS + rand()) % (MAXMASS - MINMASS); | |
(*p).x = rand() % CLOUDDIAMETER; | |
(*p).y = rand() % CLOUDDIAMETER; | |
(*p).vx = 0; | |
(*p).vy = 0; | |
fprintf(fp, "X%i,Y%i,", np, np); | |
} | |
fprintf(fp, "\n"); | |
// end setup | |
for (int i = 0; i < STEPS; i++) { //foreaver ish | |
struct point scratchPoint[NUMPOINTS]; | |
if (i % PROGRESS == 0) printf("%d ", i / PROGRESS); // progress bar | |
for (int np = 0; np < NUMPOINTS; np++) { // for each point | |
double forceX = 0; | |
double forceY = 0; | |
struct pointMass *p; | |
struct point *sp; | |
p = &point[np]; | |
for (int nip = 0; nip < NUMPOINTS; nip++) { // check all influencing points | |
double dist; | |
double force; | |
double dir; | |
struct pointMass *ip; | |
ip = &point[nip]; // exerts force on p | |
if (nip == np) continue; // we don't influence ourselves (technicly the calcs would agree, so this is optional) | |
dist = sqrt( | |
pow((*p).x - (*ip).x, 2) + | |
pow((*p).y - (*ip).y, 2) | |
); | |
force = G*(*p).mass*(*ip).mass / pow(dist, 2); | |
dir = atan2((*ip).x - (*p).x, (*ip).y - (*p).y); | |
forceX += force*cos(dir); | |
forceY += force*sin(dir); | |
} | |
//now we have forceX and forceY | |
sp = &scratchPoint[np]; | |
// update velocity (we can to this live b.c velocity dosent affecy gravity) | |
(*p).vx += forceX / (*p).mass; // f=ma a=delta v | |
(*p).vy += forceY / (*p).mass; | |
// update position (cant do this live b.c. it would affect later points) | |
(*sp).x = (*p).x + (*p).vx; | |
(*sp).y = (*p).y + (*p).vy; | |
fprintf(fp, "%f,%f,", (*sp).x, (*sp).y); | |
} | |
for (int np = 0; np < NUMPOINTS; np++) { // move scratch points to points for next time | |
struct pointMass *p; | |
struct point *sp; | |
p = &point[np]; | |
sp = &scratchPoint[np]; | |
(*p).x = (*sp).x; | |
(*p).y = (*sp).y; | |
} | |
fprintf(fp, "\n"); | |
} | |
puts("\n"); // it's just good form | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment