Как моделировать гравитацию в моделировании солнечной системы C ++ SFML?C++

Программы на C++. Форум разработчиков
Anonymous
Как моделировать гравитацию в моделировании солнечной системы C ++ SFML?

Сообщение Anonymous »

Я пытаюсь написать моделирование солнечной системы в C ++ с помощью SFML. До сих пор я получил планеты на экране вместе с солнцем и написал код, чтобы заставить планеты на орбиту вокруг Солнца: < /p>

Код: Выделить всё

#include "SFML/Graphics.hpp";

#include ;
#include ;
#include ;
#include ;

const double G = 6.67430e-11; // Gravitational constant

class CelestialBody {
public:
sf::CircleShape shape;
sf::Vector2f position;
sf::Vector2f velocity;
float mass;

CelestialBody(float radius, float mass, sf::Vector2f position, sf::Vector2f velocity, sf::Color color)
: mass(mass), position(position), velocity(velocity) {
shape.setRadius(radius);
shape.setOrigin(radius, radius);
shape.setPosition(position);
shape.setFillColor(color);
}

std::vector path;

// Update this in your CelestialBody::update method
void update(float dt) {
position += velocity * dt;
shape.setPosition(position);
path.push_back(position); // Store the new position
}
};

void applyGravity(CelestialBody& a, CelestialBody& b, float dt) {
sf::Vector2f direction = b.position - a.position;
float distance = sqrt(direction.x * direction.x + direction.y * direction.y);
if (distance == 0) return; // Avoid division by zero
float force = (G * a.mass * b.mass) / (distance * distance);
sf::Vector2f normalizedDirection = direction / distance;
sf::Vector2f accelerationA = force / a.mass * normalizedDirection;
a.velocity += accelerationA * dt;
}

sf::VertexArray createStarField(int numStars, int width, int height) {
sf::VertexArray stars(sf::Points, numStars);
for (int i = 0; i < numStars;  ++i) {
stars[i].position = sf::Vector2f(rand() % width - width / 2, rand() % height - height / 2);
stars[i].color = sf::Color::White;
}
return stars;
}

int main() {
const int window_width = sf::VideoMode::getDesktopMode().width;
const int window_height = sf::VideoMode::getDesktopMode().height;

sf::RenderWindow window(sf::VideoMode(window_width, window_height), "C++ Solar System");

// Create a view
sf::View view(sf::FloatRect(0, 0, window_width, window_height));

// Scaling factors
float radiusScale = 1.0f / 1000000.0f;
float distanceScale = 1.0f / 1000000.0f;
float massScale = 1e11 / 1e24;

// Create solar system
CelestialBody sun(45.0f, 1.989e30 * massScale, sf::Vector2f(window_width / 2, window_height / 2), sf::Vector2f(0, 0), sf::Color(239, 142, 56));

// MERCURY
float mercuryDistance = 57.9e6 * distanceScale;
float mercuryVelocity = sqrt(G * (1.989e30 * massScale) / mercuryDistance);
CelestialBody mercury(2.440, 3.30e23 * massScale, sf::Vector2f(window_width / 2, window_height / 2 - mercuryDistance), sf::Vector2f(mercuryVelocity, 0), sf::Color(183, 184, 185));

// VENUS
float venusDistance = 108.2e6 * distanceScale;
float venusVelocity = sqrt(G * (1.989e30 * massScale) / venusDistance);
CelestialBody venus(6.052, 4.87e24 * massScale, sf::Vector2f(window_width / 2, window_height / 2 - venusDistance), sf::Vector2f(venusVelocity, 0), sf::Color(255, 198, 73));

// EARTH
float earthDistance = 149.6e6 * distanceScale;
float earthVelocity = sqrt(G * (1.989e30 * massScale) / earthDistance);
CelestialBody earth(6.371, 5.972e24 * massScale, sf::Vector2f(window_width / 2, window_height / 2 - earthDistance), sf::Vector2f(earthVelocity, 0), sf::Color(26, 40, 90));

// MARS
float marsDistance = 227.9e6 * distanceScale;
float marsVelocity = sqrt(G * (1.989e30 * massScale) / marsDistance);
CelestialBody mars(3.390, 0.642e24 * massScale, sf::Vector2f(window_width / 2, window_height / 2 - marsDistance), sf::Vector2f(marsVelocity, 0), sf::Color(156, 46, 53));

// JUPITER
float jupiterDistance = 778.5e6 * distanceScale;
float jupiterVelocity = sqrt(G * (1.989e30 * massScale) / jupiterDistance);
CelestialBody jupiter(69.911, 1898e24 * massScale, sf::Vector2f(window_width / 2, window_height / 2 - jupiterDistance), sf::Vector2f(jupiterVelocity, 0), sf::Color(106, 81, 119));

// SATURN
float saturnDistance = 1433.5e6 * distanceScale;
float saturnVelocity = sqrt(G * (1.989e30 * massScale) / saturnDistance);
CelestialBody saturn(58.232, 568e24 * massScale, sf::Vector2f(window_width / 2, window_height / 2 - saturnDistance), sf::Vector2f(saturnVelocity, 0), sf::Color(250, 229, 191));

// URANUS
float uranusDistance = 2872.5e6 * distanceScale;
float uranusVelocity = sqrt(G * (1.989e30 * massScale) / uranusDistance);
CelestialBody uranus(25.362, 86.8e24 * massScale, sf::Vector2f(window_width / 2, window_height / 2 - uranusDistance), sf::Vector2f(uranusVelocity, 0), sf::Color(178, 214, 219));

// Neptune
float neptuneDistance = 4495.1e6 * distanceScale;
float neptuneVelocity = sqrt(G * (1.989e30 * massScale) / neptuneDistance);
CelestialBody neptune(24.622, 102e24 * massScale, sf::Vector2f(window_width / 2, window_height / 2 - neptuneDistance), sf::Vector2f(neptuneVelocity, 0), sf::Color(41, 144, 181));

// Draw Star Field
sf::VertexArray stars = createStarField(1000000, window_width * 10, window_height * 10);

sf::Clock clock;
float timeScale = 0.3141592650f;

// run the program as long as the window is open
while (window.isOpen())
{
// check all the window's events that were triggered since the last iteration of the loop
sf::Event event;
while (window.pollEvent(event))
{
// "close requested" event: we close the window
if (event.type == sf::Event::Closed)
window.close();

// Handle zoom in and zoom out
if (event.type == sf::Event::MouseWheelScrolled) {
if (event.mouseWheelScroll.delta > 0) {
view.zoom(0.9f); // Zoom in
}
else {
view.zoom(1.1f);  // Zoom out
}
}
}

float dt = clock.restart().asSeconds() * timeScale;

// Apply gravity
applyGravity(mercury, sun, dt);
applyGravity(venus, sun, dt);
applyGravity(earth, sun, dt);
applyGravity(mars, sun, dt);
applyGravity(jupiter, sun, dt);
applyGravity(saturn, sun, dt);
applyGravity(uranus, sun, dt);
applyGravity(neptune, sun, dt);

// Update positions
sun.update(dt);
mercury.update(dt);
venus.update(dt);
earth.update(dt);
mars.update(dt);
jupiter.update(dt);
saturn.update(dt);
uranus.update(dt);
neptune.update(dt);

// Apply the view
window.setView(view);

window.clear();

for (auto& planet : { mercury, venus, earth, mars, jupiter, saturn, uranus, neptune }) {
sf::VertexArray pathLine(sf::LinesStrip, planet.path.size());
for (size_t i = 0; i < planet.path.size(); ++i) {
pathLine[i].position = planet.path[i];
}
window.draw(pathLine);
}

window.draw(sun.shape);
window.draw(mercury.shape);
window.draw(venus.shape);
window.draw(earth.shape);
window.draw(mars.shape);
window.draw(jupiter.shape);
window.draw(saturn.shape);
window.draw(uranus.shape);
window.draw(neptune.shape);

window.display();
}

return 0;
}
Однако планеты постепенно удаляются или приближаются к Солнцу. Понятия не имею, в чем дело.
Может ли кто-нибудь помочь мне исправить эту ошибку?
Вот изображение того, что происходит с одной из планет (Меркурий) через некоторое время:
Изображение

Как вы можете видеть, путь, который проходит Меркурий, становится толще по мере того, как он удаляется от Солнца с течением времени.

Подробнее здесь: https://stackoverflow.com/questions/789 ... simulation

Вернуться в «C++»