### problem with gravity

im trying to make a program that simulates gravity as if your mouse pointer was a large object, and particles were gravitating around it. but when i run it, it crashes instantly, and i can't figure out why. i am relatively new to c++.

 ``123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195`` ``````#include #include #include #include #include #include using namespace std; //set important variables int screenWidth = 640; int screenHeight = 480; int mouseX = screenWidth / 2; int mouseY = screenHeight / 2; //class for the mouse pointer that everything gravitates around class foci { public: int x, y; //x and y coordinates double mass; //mass of the object foci(int X, int Y, int Mass); void move(); //track mouse movement and move object to that location }; foci::foci(int X, int Y, int Mass) { x = X; y = Y; mass = Mass; } void foci::move() { x = mouseX; y = mouseY; } //particles class particle { public: int x, y, mass; //x and y locations, and mass float xvel, yvel, xacc, yacc, distance, theta, gravForce; //speed, acceleration, distance from foci, angle between foci and particle, and the force of gravity Uint32 color; //color of the particle particle(int X, int Y, float Xvel, float Yvel,int Mass, Uint32 Color); void calcDistance(foci b); //calculate distance from foci void calcGravForce(foci a); //calculate the gravitational force foci has on particle void calcTheta(foci c); //calculate the angle between foci and particle void calcAcceleration(); //calculate the acceleration of the particle void calcVelocity(); //calculate the velocity of the particle void move(); //move the particle void show(); //show the particle }; particle::particle(int X, int Y, float Xvel, float Yvel,int Mass, Uint32 Color) { x = X; y = Y; xvel = Xvel; yvel = Yvel; mass = Mass; color = Color; } void particle::calcDistance(foci b) { distance = hypot((b.x - x), (b.y - y)); } void particle::calcGravForce(foci a) { gravForce = ((a.mass * mass) / (distance * distance)); //ignored gravitational constant(assumed its 1, for simplicity sake) } void particle::calcTheta(foci c) { theta = atan2((c.y - y), (c.x - x)); } void particle::calcAcceleration() { //A = F/M xacc = (gravForce * cos(theta))/mass; yacc = (gravForce * sin(theta))/mass; } void particle::calcVelocity() { //Vf(velocity final) = A*time(which is each frame) - Vi(velocity initial) xvel = xacc - xvel; yvel = yacc - yvel; } void particle::move() { //move the particle x += xvel; y += yvel; //check boundaries if(x == 0) xvel = xvel * -1; if(y == 0) yvel = yvel * -1; if(y > screenHeight) yvel = yvel * -1; if(x > screenWidth) xvel = xvel * -1; } void particle::show() { //show the particle Uint8* pixels=(Uint8*)SDL_GetVideoSurface()->pixels; Uint8* pixel=pixels+(int)y*SDL_GetVideoSurface()->pitch+(int)x; *pixel=color; } int main (int argc, char** argv) { //initialize SDL_Init(SDL_INIT_EVERYTHING); SDL_Surface* screen; screen = SDL_SetVideoMode(screenWidth, screenHeight, 8, SDL_SWSURFACE); Uint32 start; //seed random # generator srand(time(NULL)); const int FPS = 30; bool running = true; //max particles on screen int maxParticles = 5000; //make the mouse pointer foci foci Luna(screenWidth / 2, screenHeight, 999); //make the vector vector particles; //fill the vector for(int i = 0; i < maxParticles; ++i) particles.push_back(new particle((rand()%screenWidth) - 5, (rand()%screenHeight) - 5, 0, 0, 100, SDL_MapRGB(screen->format, rand()%255, rand()%255, rand()%255))); while(running) { start = SDL_GetTicks(); SDL_Event event; while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_QUIT: running = false; break; case SDL_MOUSEMOTION: mouseX = event.motion.x; mouseY = event.motion.y; } } //check mouse pointer location Luna.move(); //make screen black SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB(screen->format, 0, 0, 0)); for(int j = 0; j < maxParticles; ++j) { //make all the calculations for the variables and move the particles particles[j]->calcDistance(Luna); particles[j]->calcGravForce(Luna); particles[j]->calcTheta(Luna); particles[j]->calcAcceleration(); particles[j]->calcVelocity(); particles[j]->move(); particles[j]->show(); } SDL_Flip(screen); //regulate fps if(1000/FPS>SDL_GetTicks()-start) SDL_Delay(1000/FPS-(SDL_GetTicks()-start)); } SDL_Quit(); return 0; }``````
I would suggest perhaps adding a break to line 163.
Last edited on
Is that necessary Smac?

Um tatsu, would an arrow key controlled cursor be easier to handle? And what if particles spawn on each other?
\$ gdb a.out
> run
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401432 in particle::show (this=0x71aff0) at foo.cpp:117
117 *pixel=color;

> print pixel
\$1 = (Uint8 *) 0x77ee09 <Address 0x77ee09 out of bounds>

Also, you are leaking memory with your `particles' vector. ¿is there a good reason to use dynamic allocation there?
Last edited on
ne555,
as i said, im new to c++, the only way i learned to make something hold all the particles was to make the vector in that way. i was also told before that my way of printing the pixels to the screen was not the best, but i have never found a better way to do it. any help would be appreciated. also, i use codeblocks, which babys me very much in terms of error finding lol, so I cant understand the error message you posted. sorry X(

greenleaf800073,
i think that setting the x and y to the mouses x and y was pretty easy in itself, but if it would cause any disturbance to the program then i could easily make it keyboard controlled

thanks everyone :)
 ``1234567`` ``````void particle::show() { //show the particle Uint8* pixels=(Uint8*)SDL_GetVideoSurface()->pixels; Uint8* pixel=pixels+(int)y*SDL_GetVideoSurface()->pitch+(int)x; *pixel=color; }``````
The values of `x' and `y' are referring to a point that it is outside the screen.
You try to access something that you don't own, producing the crash.

 ``1234567`` `````` vector particles; //holding objects instead of pointers //fill the vector for(int i = 0; i < maxParticles; ++i) particles.push_back(particle(/**/)); particles[j].calcDistance(Luna); //accessing ``````
When the vector goes out of scope (the function ends), all the particles will be destroyed.
I was playing a little.
 ``123456`` ``````void particle::show() { if(x<0 or y<0 or x>=screenWidth or y>=screenHeight) //out of bounds return; //... }``````
so you can see it.

It looks awful. I found two mistakes
 ``1234567891011121314`` ``````void particle::calcVelocity() { //Vf(velocity final) = A*time(which is each frame) - Vi(velocity initial) //nope, A = (Vf-Vi)/t so Vf = A*t + Vi xvel += xacc; yvel += yacc; } //particles class particle { public: /*int*/double x, y;``````
The force is really small, by using integers for the coordinates, you'll have artifacts in the movements.
Of course, you'll need integers in `show()' as you use pointer arithmetic.

Another thing, `cos(theta)' is equivalent to `(f.x-x)/distance' where `f' is the foci
Can you use scroll wheel or up and down buttons to alter gravity?

and colored particles would be beautiful
Thanks ne555, I'll try it next time I can get to my computer. And I can't believe I got the formula wrong X(

And greenleaf, I could possibly use the scroll wheel, but I want to get this working first lol, and the particles are colored. The color is randomly generated :)
yay
Topic archived. No new replies allowed.