Advertisement
GuessGen

Gravity Simulation in C++ with OpenGL

Jul 8th, 2012
15,633
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.00 KB | None | 0 0
  1. /*##############################################
  2. ##                                            ##
  3. ##  Program: Gravity simulation               ##
  4. ##  Author: Curcudel Eugen (GuessGen)         ##
  5. ##  E-mail: CurcudelEugen@gmail.com           ##
  6. ##  WebSite: http://GuessGen.wordpress.com    ##
  7. ##                                            ##
  8. ##############################################*/
  9.  
  10. #include <GL/glut.h>
  11. #include <vector>
  12. #include <cmath>
  13.  
  14. struct Particle {
  15.     float x;
  16.     float y;
  17.     float r;
  18.     float vx;
  19.     float vy;
  20.     float m;
  21.     float color[3];
  22. };
  23.  
  24. struct Line {
  25.     float x1;
  26.     float y1;
  27.     float x2;
  28.     float y2;
  29. } line;
  30.  
  31. void timer(int = 0);
  32. void display();
  33. void mouse(int, int, int, int);
  34. void mouseMotion(int, int);
  35. void addParticle(float, float, bool = true, float = 0, float = 0);
  36. void removeParticles();
  37. void keyboard(unsigned char, int, int);
  38.  
  39. int Mx, My, WIN;
  40. bool PRESSED_LEFT = false, PRESSED_RIGHT = false,
  41.      PRESSED_MIDDLE = false, SPEED_PARTICLES = false;
  42.  
  43. std::vector<Particle> particles;
  44.  
  45. int main(int argc, char **argv)
  46. {
  47.     Particle p;
  48.     //initial centered Huge mass particle
  49.     p.x = 0;
  50.     p.y = 0;
  51.     p.vx = p.vy = 0;
  52.     p.m = 10000;
  53.     p.r = 10;
  54.     p.color[0] = 1;
  55.     p.color[1] = 1;
  56.     p.color[2] = 0;
  57.     particles.push_back(p);
  58.  
  59.     glutInit(&argc, argv);
  60.     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
  61.     glutInitWindowSize(500, 500);
  62.     glutInitWindowPosition(50, 50);
  63.     WIN = glutCreateWindow("Gravity");
  64.  
  65.     glClearColor(0, 0, 0, 1);
  66.     glMatrixMode(GL_PROJECTION);
  67.     glLoadIdentity();
  68.     glOrtho(-250.0, 250.0, 250.0, -250.0, 0, 1);
  69.    
  70.     glutDisplayFunc(display);
  71.     glutMouseFunc(mouse);
  72.     glutMotionFunc(mouseMotion);
  73.     glutKeyboardFunc(keyboard);
  74.     timer();
  75.    
  76.     glutMainLoop();
  77.     return 0;
  78. }
  79.  
  80. void timer(int)
  81. {
  82.     display();
  83.     if(PRESSED_LEFT && !SPEED_PARTICLES)
  84.     {
  85.         addParticle(10, 3); //add tiny particle
  86.         PRESSED_LEFT = false;
  87.     }
  88.  
  89.     if(PRESSED_RIGHT)
  90.     {
  91.         addParticle(10000, 10, 0); //add huge particle
  92.         PRESSED_RIGHT = false;
  93.     }
  94.  
  95.     if(PRESSED_MIDDLE)
  96.         removeParticles(); //remove all particles
  97.  
  98.     for(int i = 0; i < particles.size(); i++)
  99.     {
  100.         Particle &p = particles[i];
  101.         bool not_fall = true;
  102.         for(int j = 0; j < particles.size(); j++)
  103.         {
  104.             if(j == i || p.m >= 10000) // we consider the 10000 as infinit (big mass) so this particles won't move
  105.                 continue;
  106.  
  107.             const Particle &p1 = particles[j];
  108.  
  109.             float d = sqrt((p1.x - p.x)*(p1.x - p.x) + (p1.y - p.y)*(p1.y - p.y));
  110.  
  111.             if(d > p1.r)
  112.             {
  113.                 p.vx += 0.03 * p1.m / (d*d) * (p1.x - p.x)/d; //f = ma => a = f/m
  114.                 p.vy += 0.03 * p1.m / (d*d) * (p1.y - p.y)/d;
  115.             }
  116.             else
  117.                 not_fall = false;
  118.         }
  119.  
  120.         if(not_fall)   
  121.         {
  122.             p.x += p.vx;
  123.             p.y += p.vy;
  124.         }
  125.         else
  126.             particles.erase(particles.begin()+i);
  127.     }
  128.  
  129.     glutTimerFunc(1, timer, 0);
  130. }
  131.  
  132. void display()
  133. {
  134.     glClear(GL_COLOR_BUFFER_BIT);
  135.  
  136.     //draw the drag line
  137.     glColor3f(0, 0, 1);
  138.     glBegin(GL_LINES);
  139.         glVertex2f(line.x1, line.y1);
  140.         glVertex2f(line.x2, line.y2);
  141.     glEnd();
  142.  
  143.     //draw particles
  144.     for(int i = 0; i < particles.size(); i++)
  145.     {
  146.         Particle &p = particles[i];
  147.         glColor3f(p.color[0], p.color[1], p.color[2]);
  148.         glBegin(GL_POLYGON);
  149.         for(float a = 0; a < 2*M_PI; a+=0.2)
  150.             glVertex2f(p.r*cos(a) + p.x, p.r*sin(a) + p.y);
  151.         glEnd();   
  152.     }
  153.  
  154.     glFlush();
  155.     glutSwapBuffers();
  156. }
  157.  
  158. void mouse(int button, int state, int x, int y)
  159. {
  160.     //set the coordinates
  161.     Mx = x - 250;
  162.     My = y - 250;
  163.  
  164.     //add speed particles by line draging
  165.     if(SPEED_PARTICLES)
  166.     {
  167.         if(line.x2 != 0 && line.y2 != 0 && state == GLUT_UP && PRESSED_LEFT)
  168.             addParticle(100, 5, 1, line.x1 - line.x2, line.y1 - line.y2); //add a speed particle
  169.         else
  170.         {
  171.             line.x1 = line.x2 = Mx;
  172.             line.y1 = line.y2 = My;
  173.         }
  174.     }
  175.  
  176.     //check which button is pressed
  177.     if(button == GLUT_LEFT_BUTTON)
  178.         PRESSED_LEFT = state == GLUT_DOWN;
  179.     else if(button == GLUT_RIGHT_BUTTON)
  180.         PRESSED_RIGHT = state == GLUT_DOWN;
  181.     else if(button == GLUT_MIDDLE_BUTTON)
  182.         PRESSED_MIDDLE = state == GLUT_DOWN;
  183. }
  184.  
  185. void mouseMotion(int x, int y)
  186. {
  187.     Mx = x - 250;
  188.     My = y - 250;  
  189.  
  190.     //end of line with draging
  191.     if(SPEED_PARTICLES && PRESSED_LEFT)
  192.     {
  193.         line.x2 = Mx;
  194.         line.y2 = My;
  195.     }
  196. }
  197.  
  198. void addParticle(float m, float r, bool randColor, float vx, float vy)
  199. {
  200.     Particle p;
  201.     p.x = Mx;
  202.     p.y = My;
  203.     p.vx = vx / 30; // /30 in case it is a speed particle,
  204.     p.vy = vy / 30; // slow down the speed a little
  205.     p.m = m;
  206.     p.r = r;
  207.     if(randColor)
  208.     {
  209.         p.color[0] = rand()%200 / 200.0;
  210.         p.color[1] = rand()%200 / 200.0;
  211.         p.color[2] = rand()%200 / 200.0;
  212.     }
  213.     else // if is huge particle make it yellow
  214.     {
  215.         p.color[0] = 1;
  216.         p.color[1] = 1;
  217.         p.color[2] = 0;
  218.     }
  219.     particles.push_back(p);
  220.  
  221.     if(line.x1 != 0)
  222.         line.x1 = line.x2 = line.y1 = line.y2 = 0; 
  223. }
  224.  
  225. void removeParticles()
  226. {
  227.     for(int i = 0; i < particles.size(); i++)
  228.         particles.pop_back();
  229. }
  230.  
  231. void keyboard(unsigned char key, int x, int y)
  232. {
  233.     switch(key)
  234.     {
  235.         case 's':
  236.             SPEED_PARTICLES = !SPEED_PARTICLES;
  237.             break; 
  238.         case 27:
  239.             removeParticles();
  240.             glutDestroyWindow(WIN);
  241.             exit(0);
  242.             break;
  243.     }
  244. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement