Little things
This commit is contained in:
+16
-12
@@ -12,24 +12,28 @@ std::string vec3_to_string(const glm::vec3& v) {
|
|||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
CelestialBody::CelestialBody(double mass, const glm::dvec3& position, const glm::dvec3& velocity)
|
CelestialBody::CelestialBody(double mass, const glm::dvec3& position, const glm::dvec3& velocity, double radius)
|
||||||
: mass(mass), position(position), velocity(velocity), acceleration(0.0f) {}
|
: mass(mass), position(position), velocity(velocity), acceleration(0.0f) {}
|
||||||
|
|
||||||
void CelestialBody::update(double dt) {
|
void CelestialBody::update(double dt) {
|
||||||
if (glm::any(glm::isnan(velocity)) || glm::any(glm::isinf(velocity))) {
|
// Runge-Kutta 4th order method
|
||||||
std::cout << "Warning: Invalid velocity detected: " << vec3_to_string(velocity) << std::endl;
|
glm::dvec3 k1v = acceleration * dt;
|
||||||
velocity = glm::vec3(0.0f);
|
glm::dvec3 k1r = velocity * dt;
|
||||||
}
|
|
||||||
|
|
||||||
velocity += acceleration * dt;
|
glm::dvec3 k2v = acceleration * dt;
|
||||||
position += velocity * dt;
|
glm::dvec3 k2r = (velocity + k1v * 0.5) * dt;
|
||||||
|
|
||||||
if (glm::any(glm::isnan(position)) || glm::any(glm::isinf(position))) {
|
glm::dvec3 k3v = acceleration * dt;
|
||||||
std::cout << "Warning: Invalid position detected: " << vec3_to_string(position) << std::endl;
|
glm::dvec3 k3r = (velocity + k2v * 0.5) * dt;
|
||||||
position = glm::vec3(0.0f);
|
|
||||||
}
|
glm::dvec3 k4v = acceleration * dt;
|
||||||
|
glm::dvec3 k4r = (velocity + k3v) * dt;
|
||||||
|
|
||||||
|
velocity += (k1v + 2.0 * k2v + 2.0 * k3v + k4v) / 6.0;
|
||||||
|
position += (k1r + 2.0 * k2r + 2.0 * k3r + k4r) / 6.0;
|
||||||
|
|
||||||
|
acceleration = glm::dvec3(0.0);
|
||||||
|
|
||||||
acceleration = glm::vec3(0.0f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CelestialBody::applyForce(const glm::dvec3& force) {
|
void CelestialBody::applyForce(const glm::dvec3& force) {
|
||||||
|
|||||||
+3
-1
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
class CelestialBody {
|
class CelestialBody {
|
||||||
public:
|
public:
|
||||||
CelestialBody(double mass, const glm::dvec3& position, const glm::dvec3& velocity);
|
CelestialBody(double mass, const glm::dvec3& position, const glm::dvec3& velocity, double radius);
|
||||||
|
|
||||||
void update(double dt);
|
void update(double dt);
|
||||||
void applyForce(const glm::dvec3& force);
|
void applyForce(const glm::dvec3& force);
|
||||||
@@ -21,6 +21,7 @@ public:
|
|||||||
[[nodiscard]] glm::dvec3 getVelocity() const { return velocity; }
|
[[nodiscard]] glm::dvec3 getVelocity() const { return velocity; }
|
||||||
void addToTrajectory(const glm::dvec3& position);
|
void addToTrajectory(const glm::dvec3& position);
|
||||||
const std::vector<glm::dvec3>& getTrajectory() const { return trajectory; }
|
const std::vector<glm::dvec3>& getTrajectory() const { return trajectory; }
|
||||||
|
double getRadius() const { return radius; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double mass;
|
double mass;
|
||||||
@@ -29,5 +30,6 @@ private:
|
|||||||
glm::dvec3 acceleration;
|
glm::dvec3 acceleration;
|
||||||
std::vector<glm::dvec3> trajectory;
|
std::vector<glm::dvec3> trajectory;
|
||||||
static const size_t MAX_TRAJECTORY_POINTS = 1000;
|
static const size_t MAX_TRAJECTORY_POINTS = 1000;
|
||||||
|
double radius;
|
||||||
};
|
};
|
||||||
#endif //GRAVITY_CELESTIALBODY_H
|
#endif //GRAVITY_CELESTIALBODY_H
|
||||||
|
|||||||
+10
-24
@@ -2,12 +2,9 @@
|
|||||||
// Created by Quinta on 7/12/2024.
|
// Created by Quinta on 7/12/2024.
|
||||||
//
|
//
|
||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
Renderer::Renderer(int width, int height)
|
Renderer::Renderer(int width, int height)
|
||||||
: cameraPos(3e11f, 2e11f, 3e11f),
|
: cameraPos(3e11f, 2e11f, 3e11f),
|
||||||
@@ -65,7 +62,7 @@ void Renderer::render(const Simulator& simulator) {
|
|||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
gluPerspective(45.0, 1600.0 / 1200.0, 1e9, 1e13);
|
gluPerspective(45.0, 1600.0 / 1200.0, 1e8, 1e14);
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
@@ -90,13 +87,9 @@ void Renderer::render(const Simulator& simulator) {
|
|||||||
minMass = std::min(minMass, body.getMass());
|
minMass = std::min(minMass, body.getMass());
|
||||||
}
|
}
|
||||||
|
|
||||||
//std::cout << "Camera position: " << cameraPos.x << ", " << cameraPos.y << ", " << cameraPos.z << std::endl;
|
|
||||||
//std::cout << "Camera front: " << cameraFront.x << ", " << cameraFront.y << ", " << cameraFront.z << std::endl;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < bodies.size(); ++i) {
|
for (size_t i = 0; i < bodies.size(); ++i) {
|
||||||
const auto& body = bodies[i];
|
const auto& body = bodies[i];
|
||||||
glm::dvec3 pos = body.getPosition();
|
glm::dvec3 pos = body.getPosition();
|
||||||
//std::cout << "Body " << i << " position: " << pos.x << ", " << pos.y << ", " << pos.z << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the log range
|
// Calculate the log range
|
||||||
@@ -117,19 +110,6 @@ void Renderer::render(const Simulator& simulator) {
|
|||||||
glm::dvec3 pos = body.getPosition();
|
glm::dvec3 pos = body.getPosition();
|
||||||
glm::vec3 renderPos(static_cast<float>(pos.x), static_cast<float>(pos.y), static_cast<float>(pos.z));
|
glm::vec3 renderPos(static_cast<float>(pos.x), static_cast<float>(pos.y), static_cast<float>(pos.z));
|
||||||
|
|
||||||
// std::cout << "Rendering body " << i << " (";
|
|
||||||
// switch(i) {
|
|
||||||
// case 0: std::cout << "Sun"; break;
|
|
||||||
// case 1: std::cout << "Mercury"; break;
|
|
||||||
// case 2: std::cout << "Venus"; break;
|
|
||||||
// case 3: std::cout << "Earth"; break;
|
|
||||||
// case 4: std::cout << "Mars"; break;
|
|
||||||
// default: std::cout << "Unknown"; break;
|
|
||||||
// }
|
|
||||||
// std::cout << ") at position ("
|
|
||||||
// << pos.x << ", " << pos.y << ", " << pos.z
|
|
||||||
// << ") with scale " << scaleFactor << std::endl;
|
|
||||||
|
|
||||||
// Set color based on body index
|
// Set color based on body index
|
||||||
switch(i) {
|
switch(i) {
|
||||||
case 0: glColor3f(1.0f, 1.0f, 0.0f); break; // Sun: Yellow
|
case 0: glColor3f(1.0f, 1.0f, 0.0f); break; // Sun: Yellow
|
||||||
@@ -137,6 +117,12 @@ void Renderer::render(const Simulator& simulator) {
|
|||||||
case 2: glColor3f(0.9f, 0.7f, 0.4f); break; // Venus: Light Orange
|
case 2: glColor3f(0.9f, 0.7f, 0.4f); break; // Venus: Light Orange
|
||||||
case 3: glColor3f(0.0f, 0.5f, 1.0f); break; // Earth: Blue
|
case 3: glColor3f(0.0f, 0.5f, 1.0f); break; // Earth: Blue
|
||||||
case 4: glColor3f(1.0f, 0.0f, 0.0f); break; // Mars: Red
|
case 4: glColor3f(1.0f, 0.0f, 0.0f); break; // Mars: Red
|
||||||
|
case 5: glColor3f(0.8f, 0.6f, 0.2f); break; // Jupiter: Light Brown
|
||||||
|
case 6: glColor3f(0.9f, 0.9f, 0.7f); break; // Saturn: Light Yellow
|
||||||
|
case 7: glColor3f(0.0f, 0.5f, 0.5f); break; // Uranus: Cyan
|
||||||
|
case 8: glColor3f(0.0f, 0.0f, 1.0f); break; // Neptune: Dark Blue
|
||||||
|
case 9: glColor3f(0.5f, 0.5f, 0.5f); break; // Pluto: Gray
|
||||||
|
|
||||||
default: glColor3f(1.0f, 1.0f, 1.0f); break; // White for any additional bodies
|
default: glColor3f(1.0f, 1.0f, 1.0f); break; // White for any additional bodies
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,8 +257,8 @@ float Renderer::calculateGravityFieldStrength(const glm::vec3& point, const std:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::drawGrid(const Simulator& simulator) {
|
void Renderer::drawGrid(const Simulator& simulator) {
|
||||||
const float gridSize = 5e11f;
|
const float gridSize = 5e13f;
|
||||||
const int gridLines = 20;
|
const int gridLines = 80;
|
||||||
const float lineSpacing = gridSize / gridLines;
|
const float lineSpacing = gridSize / gridLines;
|
||||||
|
|
||||||
glBegin(GL_LINES);
|
glBegin(GL_LINES);
|
||||||
@@ -311,7 +297,7 @@ void Renderer::drawTrajectories(const std::vector<CelestialBody>& bodies) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::processInput() {
|
void Renderer::processInput() {
|
||||||
float cameraSpeed = this->cameraSpeed;
|
float cameraSpeed = this->cameraSpeed * 1e1f;
|
||||||
|
|
||||||
glm::vec3 front(cameraFront.x, 0, cameraFront.z);
|
glm::vec3 front(cameraFront.x, 0, cameraFront.z);
|
||||||
front = glm::normalize(front);
|
front = glm::normalize(front);
|
||||||
|
|||||||
+44
-2
@@ -35,6 +35,9 @@ void Simulator::update(double dt) {
|
|||||||
bodies[i].update(dt);
|
bodies[i].update(dt);
|
||||||
bodies[i].addToTrajectory(bodies[i].getPosition());
|
bodies[i].addToTrajectory(bodies[i].getPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for collisions
|
||||||
|
checkCollisions();
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::dvec3 Simulator::calculateGravitationalForce(const CelestialBody& body1, const CelestialBody& body2) {
|
glm::dvec3 Simulator::calculateGravitationalForce(const CelestialBody& body1, const CelestialBody& body2) {
|
||||||
@@ -52,10 +55,49 @@ glm::dvec3 Simulator::calculateGravitationalForce(const CelestialBody& body1, co
|
|||||||
double forceMagnitude = G * (body1.getMass() * body2.getMass()) / (distance * distance);
|
double forceMagnitude = G * (body1.getMass() * body2.getMass()) / (distance * distance);
|
||||||
|
|
||||||
if (std::isnan(forceMagnitude) || std::isinf(forceMagnitude)) {
|
if (std::isnan(forceMagnitude) || std::isinf(forceMagnitude)) {
|
||||||
std::cout << "Warning: Invalid force magnitude calculated. Distance: " << distance
|
|
||||||
<< ", Masses: " << body1.getMass() << ", " << body2.getMass() << std::endl;
|
|
||||||
return glm::dvec3(0.0);
|
return glm::dvec3(0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return glm::normalize(direction) * forceMagnitude;
|
return glm::normalize(direction) * forceMagnitude;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Simulator::handleCollision(CelestialBody& body1, CelestialBody& body2) {
|
||||||
|
double totalMass = body1.getMass() + body2.getMass();
|
||||||
|
|
||||||
|
// Calculate center of mass position
|
||||||
|
glm::dvec3 newPosition = (body1.getPosition() * body1.getMass() + body2.getPosition() * body2.getMass()) / totalMass;
|
||||||
|
|
||||||
|
// Calculate new velocity (momentum conservation)
|
||||||
|
glm::dvec3 newVelocity = (body1.getVelocity() * body1.getMass() + body2.getVelocity() * body2.getMass()) / totalMass;
|
||||||
|
|
||||||
|
// Calculate new radius (assuming constant density)
|
||||||
|
double newRadius = std::pow(std::pow(body1.getRadius(), 3) + std::pow(body2.getRadius(), 3), 1.0/3.0);
|
||||||
|
|
||||||
|
// Create new body
|
||||||
|
CelestialBody newBody(totalMass, newPosition, newVelocity, newRadius);
|
||||||
|
|
||||||
|
// Replace body1 with the new body
|
||||||
|
body1 = newBody;
|
||||||
|
|
||||||
|
// Remove body2
|
||||||
|
auto it = std::find_if(bodies.begin(), bodies.end(), [&body2](const CelestialBody& b) {
|
||||||
|
return &b == &body2;
|
||||||
|
});
|
||||||
|
if (it != bodies.end()) {
|
||||||
|
bodies.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Simulator::checkCollisions() {
|
||||||
|
for (size_t i = 0; i < bodies.size(); ++i) {
|
||||||
|
for (size_t j = i + 1; j < bodies.size(); ++j) {
|
||||||
|
CelestialBody& body1 = bodies[i];
|
||||||
|
CelestialBody& body2 = bodies[j];
|
||||||
|
glm::dvec3 distanceVec = body1.getPosition() - body2.getPosition();
|
||||||
|
double distance = glm::length(distanceVec);
|
||||||
|
if (distance < (body1.getRadius() + body2.getRadius())) {
|
||||||
|
handleCollision(body1, body2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -21,5 +21,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
std::vector<CelestialBody> bodies;
|
std::vector<CelestialBody> bodies;
|
||||||
const float G = 6.67430e-11f; // Gravitational constant
|
const float G = 6.67430e-11f; // Gravitational constant
|
||||||
|
void checkCollisions();
|
||||||
|
void handleCollision(CelestialBody& body1, CelestialBody& body2);
|
||||||
};
|
};
|
||||||
#endif //GRAVITY_SIMULATOR_H
|
#endif //GRAVITY_SIMULATOR_H
|
||||||
|
|||||||
@@ -6,24 +6,58 @@
|
|||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
glm::dvec3 calculateOrbitalVelocity(double centralMass, double distance) {
|
||||||
|
const double G = 6.67430e-11;
|
||||||
|
double speed = std::sqrt(G * centralMass / distance);
|
||||||
|
return glm::dvec3(0, speed, 0); // Assuming orbit in the XZ plane
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
Simulator simulator;
|
Simulator simulator;
|
||||||
Renderer renderer(1600, 1200);
|
Renderer renderer(1600, 1200);
|
||||||
|
|
||||||
// Sun (at the center)
|
double sunMass = 1.989e30;
|
||||||
simulator.addBody(CelestialBody(1.989e30f, glm::dvec3(0, 0, 0), glm::dvec3(0, 0, 0)));
|
|
||||||
|
|
||||||
// Mercury
|
// Sun (at the center)
|
||||||
simulator.addBody(CelestialBody(3.285e23f, glm::dvec3(57.9e9f, 0, 0), glm::dvec3(0, 47.36e3f, 0)));
|
simulator.addBody(CelestialBody(sunMass, glm::dvec3(0, 0, 0), glm::dvec3(0, 0, 0), 6.96e8));
|
||||||
|
|
||||||
// Venus
|
// Mercury
|
||||||
simulator.addBody(CelestialBody(4.867e24f, glm::dvec3(108.2e9f, 0, 0), glm::dvec3(0, 35.02e3f, 0)));
|
double mercuryDist = 57.9e9;
|
||||||
|
simulator.addBody(CelestialBody(3.285e23, glm::dvec3(mercuryDist, 0, 0), calculateOrbitalVelocity(sunMass, mercuryDist), 2.44e6));
|
||||||
|
|
||||||
|
// Venus
|
||||||
|
double venusDist = 108.2e9;
|
||||||
|
simulator.addBody(CelestialBody(4.867e24, glm::dvec3(venusDist, 0, 0), calculateOrbitalVelocity(sunMass, venusDist), 6.05e6));
|
||||||
|
|
||||||
|
// Earth
|
||||||
|
double earthDist = 149.6e9;
|
||||||
|
simulator.addBody(CelestialBody(5.972e24, glm::dvec3(earthDist, 0, 0), calculateOrbitalVelocity(sunMass, earthDist), 6.37e6));
|
||||||
|
|
||||||
|
// Mars
|
||||||
|
double marsDist = 227.9e9;
|
||||||
|
simulator.addBody(CelestialBody(6.39e23, glm::dvec3(marsDist, 0, 0), calculateOrbitalVelocity(sunMass, marsDist), 3.39e6));
|
||||||
|
|
||||||
|
// Jupiter
|
||||||
|
double jupiterDist = 778.5e9;
|
||||||
|
simulator.addBody(CelestialBody(1.898e27, glm::dvec3(jupiterDist, 0, 0), calculateOrbitalVelocity(sunMass, jupiterDist), 69.91e6));
|
||||||
|
|
||||||
|
// Saturn
|
||||||
|
double saturnDist = 1.429e12;
|
||||||
|
simulator.addBody(CelestialBody(5.683e26, glm::dvec3(saturnDist, 0, 0), calculateOrbitalVelocity(sunMass, saturnDist), 58.23e6));
|
||||||
|
|
||||||
|
// Uranus
|
||||||
|
double uranusDist = 2.871e12;
|
||||||
|
simulator.addBody(CelestialBody(8.681e25, glm::dvec3(uranusDist, 0, 0), calculateOrbitalVelocity(sunMass, uranusDist ), 25.36e6));
|
||||||
|
|
||||||
|
// Neptune
|
||||||
|
double neptuneDist = 4.495e12;
|
||||||
|
simulator.addBody(CelestialBody(1.024e26, glm::dvec3(neptuneDist, 0, 0), calculateOrbitalVelocity(sunMass, neptuneDist), 24.62e6));
|
||||||
|
|
||||||
|
// Pluto
|
||||||
|
double plutoDist = 5.906e12;
|
||||||
|
simulator.addBody(CelestialBody(1.309e22, glm::dvec3(plutoDist, 0, 0), calculateOrbitalVelocity(sunMass, plutoDist), 1.18e6));
|
||||||
|
|
||||||
// Earth
|
|
||||||
simulator.addBody(CelestialBody(5.972e24f, glm::dvec3(149.6e9f, 0, 0), glm::dvec3(0, 29.78e3f, 0)));
|
|
||||||
|
|
||||||
// Mars
|
|
||||||
simulator.addBody(CelestialBody(6.39e23f, glm::dvec3(227.9e9f, 0, 0), glm::dvec3(0, 24.07e3f, 0)));
|
|
||||||
|
|
||||||
const float dt = 3600.0f; // Time step of 1 hour
|
const float dt = 3600.0f; // Time step of 1 hour
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user