
๐ main.c
#include <stdio.h>
#include <string.h>
#include <math.h>
typedef struct
{
const char *name;
double gravity;
} CelestialBody;
#define INITIAL_VELOCITY 20.0
#define TIME_STEP 0.01
void run_simulation(double v0, double dt, double g, const char *filename)
{
FILE *fp = fopen(filename, "w");
if (fp == NULL)
{
fprintf(stderr, "Error: Could not open file %s\n", filename);
return;
}
fprintf(fp, "Time (s),Position (m)\n");
double t = 0.0;
double y_initial = 0.0;
double y = 0.0;
while (1)
{
y = y_initial + v0 * t - 0.5 * g * t * t;
if (y < 0.0)
{
y = 0.0;
fprintf(fp, "%.6f,%.6f\n", t, y);
break;
}
fprintf(fp, "%.6f,%.6f\n", t, y);
t += dt;
if (t > (2.0 * v0 / g) + 1.0)
{
break;
}
}
fclose(fp);
printf("-> Simulation results for %s (G=%.2f) saved to %s\n",
filename, g, filename);
}
int main()
{
CelestialBody bodies[] = {
{"Earth", 9.80665},
{"Moon", 1.62},
{"Mars", 3.71},
{"Jupiter", 24.79},
{"Neptune", 11.15},
{"Sun", 274.0}};
int num_bodies = sizeof(bodies) / sizeof(bodies[0]);
char filename_buffer[256];
printf("Starting Gravity Simulation for %d bodies (V0=%.1fm/s, dT=%.2fs):\n",
num_bodies, INITIAL_VELOCITY, TIME_STEP);
printf("------------------------------------------------------------------\n");
for (int i = 0; i < num_bodies; i++)
{
snprintf(filename_buffer, sizeof(filename_buffer), "%s_data.csv", bodies[i].name);
run_simulation(INITIAL_VELOCITY, TIME_STEP, bodies[i].gravity, filename_buffer);
}
printf("------------------------------------------------------------------\n");
printf("All simulations completed successfully. Check the generated CSV files.\n");
return 0;
}
๐ p5.js
let tables = {};
let planets = [
{ name: "Sun", file: "Sun_data.csv", color: "#FFD700" },
{ name: "Jupiter", file: "Jupiter_data.csv", color: "#D2691E" },
{ name: "Neptune", file: "Neptune_data.csv", color: "#4169E1" },
{ name: "Earth", file: "Earth_data.csv", color: "#32CD32" },
{ name: "Mars", file: "Mars_data.csv", color: "#FF4500" },
{ name: "Moon", file: "Moon_data.csv", color: "#C0C0C0" },
];
let maxTime = 0;
let maxPos = 0;
let dataPoints = [];
let currentIndex = 0;
function preload() {
for (let p of planets) {
tables[p.name] = loadTable(p.file, "csv", "header");
}
}
function setup() {
createCanvas(1000, 600);
frameRate(60);
for (let p of planets) {
let table = tables[p.name];
let rows = table.getRows();
let pData = [];
for (let r of rows) {
let t = r.getNum("Time (s)");
let y = r.getNum("Position (m)");
pData.push({ t: t, y: y });
if (t > maxTime) maxTime = t;
if (y > maxPos) maxPos = y;
}
dataPoints.push({ meta: p, data: pData });
}
maxPos *= 1.1;
textSize(14);
}
function draw() {
background(30);
stroke(255);
line(50, height - 50, width - 50, height - 50);
line(50, height - 50, 50, 50);
noStroke();
fill(255);
text(`Max Height: ${maxPos.toFixed(1)}m`, 60, 40);
text(`Max Duration: ${maxTime.toFixed(1)}s`, width - 150, height - 30);
for (let i = 0; i < dataPoints.length; i++) {
let planet = dataPoints[i];
let path = planet.data;
stroke(planet.meta.color);
strokeWeight(2);
noFill();
beginShape();
let drawLimit = min(currentIndex, path.length - 1);
for (let j = 0; j <= drawLimit; j++) {
let sx = map(path[j].t, 0, maxTime, 50, width - 50);
let sy = map(path[j].y, 0, maxPos, height - 50, 50);
vertex(sx, sy);
if (j === drawLimit) {
push();
fill(planet.meta.color);
noStroke();
ellipse(sx, sy, 8, 8);
text(planet.meta.name, sx + 10, sy);
pop();
}
}
endShape();
}
currentIndex += 5;
let longestData = 0;
for (let p of dataPoints) longestData = max(longestData, p.data.length);
if (currentIndex > longestData + 100) {
noLoop();
}
}