即使我使用了正确的公式,为什么我的重力模拟中的粒子不能正常工作?

问题描述 投票:0回答:0

所以我一直在尝试使用 sdl2 和 c++ 进行粒子重力模拟,但即使我使用了正确的公式并且一直在尝试解决这个问题很多时间都是一样的。粒子被吸引到屏幕的右上角,如果我增加引力常数的值,它似乎会自行修复,但如果我这样做,一切都会变得非常快,我是初学者,因此无法理解可能会发生什么造成这个。这是我的代码 -

#include "SDL.h"
#undef main
#include <iostream>
#include <vector>
#include <cmath>
#include <random>
double Gravity = 1;
const int NumberOfParticles = 100;
bool isRunning = true;
int ParticleIndex = 0;
int MouseX = NULL;
int MouseY = NULL;
//References
int  DistanceY;
int x;
int y;
int ScreenHeight = 700;
int ScreenWidth = 700;
Uint32 TicksCounter;
double DeltaTime;

double  DistanceX;
//
double InverseDistance;
//
double Distance;
double Force;
double ForceY;
double ForceX;


struct Particle {
    double Mass[NumberOfParticles];
    double AX[NumberOfParticles];
    double AY[NumberOfParticles];
    SDL_Rect Particle[NumberOfParticles];
};
Particle Particles;
Particle OO;
int main() {
    //Setup
    SDL_Window* GameWindow = SDL_CreateWindow("Gravity Simulation.", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, ScreenWidth, ScreenWidth, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_RENDERER_PRESENTVSYNC);
    SDL_Renderer* Renderer = SDL_CreateRenderer(GameWindow, -1, 0);
    SDL_Event Event;
    SDL_Surface* WindowSurface = SDL_GetWindowSurface(GameWindow);
    //GameLoop
    while (isRunning) {
        srand(time(0));
        //Calculate DeltaTime
        DeltaTime = (SDL_GetTicks() - TicksCounter) / 1000.0;
        TicksCounter = SDL_GetTicks();
        std::cout << "DeltaTime : " << DeltaTime << std::endl;
        SDL_GetMouseState(&MouseX, &MouseY);
        while (SDL_PollEvent(&Event)) {
            if (Event.type == SDL_QUIT) {
                isRunning = false;
            }
            if (Event.type == SDL_KEYDOWN) {
                //Keyboard Inputs
            }
            if (Event.type == SDL_MOUSEBUTTONDOWN) {
                //Mouse Inputs
                if (Event.button.button == SDL_BUTTON_LEFT) {
                    //Add Particle
                    Particles.Particle[ParticleIndex].x = MouseX;
                    Particles.Particle[ParticleIndex].y = MouseY;
                    Particles.Particle[ParticleIndex].w = 5;
                    Particles.Particle[ParticleIndex].h = 5;
                    Particles.Mass[ParticleIndex] = 10 + rand() & 10;
                    ParticleIndex++;

                }
                if (Event.button.button == SDL_BUTTON_RIGHT) {
                    //Add Particle
                    Particles.Particle[ParticleIndex].x = MouseX;
                    Particles.Particle[ParticleIndex].y = MouseY;
                    Particles.Particle[ParticleIndex].w = 25;
                    Particles.Particle[ParticleIndex].h = 25;
                    Particles.Mass[ParticleIndex] = 1000;
                    ParticleIndex++;
                }

            }
        }
    
        for (y = 0; y < ParticleIndex; y++) {
            for (x = 0; x < ParticleIndex; x++) {
                if (x != y) {
                    DistanceX = Particles.Particle[x].x - Particles.Particle[y].x;
                    DistanceY = Particles.Particle[x].y - Particles.Particle[y].y;
                    Distance = std::sqrt(DistanceX * DistanceX + DistanceY * DistanceY + 1);
                    InverseDistance = 1.0 / Distance;
                        //Calculat Forces
                    std::cout << "Particle Index :" << ParticleIndex << std::endl;
                    //Calculate Gravity 
                        std::cout << "Mass :" << Particles.Mass[x] << std::endl << "Distance :" << Distance << std::endl;
                        Force = ((Gravity * (Particles.Mass[x] * Particles.Mass[y])) / (Distance * Distance)) ;
                        Particles.AX[y] += (Force * DistanceX / Particles.Mass[x]) * DeltaTime;
                        Particles.AY[y] += (Force * DistanceY / Particles.Mass[x]) * DeltaTime ;
                }
            }
        }
        for (y = 0; y < ParticleIndex; y++) {
            Particles.Particle[y].x += Particles.AX[y];
            Particles.Particle[y].y += Particles.AY[y];
        }
        //Rendering
        SDL_SetRenderDrawColor(Renderer, 255, 255, 255, 255);
        SDL_RenderClear(Renderer);
        SDL_SetRenderDrawColor(Renderer, 0, 0, 0, 255);
        for (y = 0; y < ParticleIndex; ++y) {
            SDL_RenderFillRect(Renderer, &Particles.Particle[y]);
        }
        SDL_RenderPresent(Renderer);
    }
}

我尝试使用其他公式(来自其他人的 github),认为其他粒子的初始位置可能在 0,0(右上角),以检查其他粒子是否因此而去那里我把粒子的数量设为 2,但它们也被吸引到了角落。

c++ simulation physics sdl-2 gravity
© www.soinside.com 2019 - 2024. All rights reserved.