所以我一直在尝试使用 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,但它们也被吸引到了角落。