Advertisement
granada

Gravity simulator

Nov 22nd, 2012
3,717
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.94 KB | None | 0 0
  1. /*
  2.  * gravity_simulator.cpp
  3.  *
  4.  * Started by Curcudel Eugen
  5.  *
  6.  * Many functions and others added by
  7.  * Bruno Tiago Mittang, Renan Samuel da Silva <UDESC>
  8.  *
  9.  * The focus of this program is to simulate the gravity across many particles.
  10.  * Particle behavior in this program will not be as it should be in a real situation,
  11.  * due to computational and algorithm limitations(and lazyness).
  12.  *
  13.  * I found the program at http://pastebin.com/SU5KG8TE
  14.  *
  15.  * This program is free software; you can redistribute it and/or modify
  16.  * it under the terms of the GNU General Public License as published by
  17.  * the Free Software Foundation; either version 2 of the License, or
  18.  * (at your option) any later version.
  19.  *
  20.  * This program is distributed in the hope that it will be useful,
  21.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  23.  * GNU General Public License for more details.
  24.  *
  25.  * You should have received a copy of the GNU General Public License
  26.  * along with this program; if not, write to the Free Software
  27.  * Foundation, Inc., 51 Franiklin Street, Fifth Floor, Boston,
  28.  * MA 02110-1301, USA.
  29.  *
  30.  */
  31.  
  32. #include <GL/glut.h>
  33. #include <vector>
  34. #include <cmath>
  35. #include <cstdlib>
  36. #include <cstdio>
  37.  
  38. #define screen_x 1024
  39. #define screen_y 768
  40.  
  41. struct Particle {
  42.     float x;
  43.     float y;
  44.     float r;
  45.     float vx;
  46.     float vy;
  47.     float m;
  48.     float color[3];
  49. };
  50.  
  51. struct Line {
  52.     float x1;
  53.     float y1;
  54.     float x2;
  55.     float y2;
  56. } line;
  57.  
  58. void timer(int = 0);
  59. void display();
  60. void mouse(int, int, int, int);
  61. void mouseMotion(int, int);
  62. void add_particle(float, float = 0, float = 0);
  63. void remove_particles();
  64. void keyboard(unsigned char, int, int);
  65. void load();
  66. void save();
  67.  
  68. int mouse_x, mouse_y, WIN,
  69.     mode=2,
  70.     crit_mass=1,
  71.     MAX_MASS=50000;
  72. float cnst_elastic=0.75;
  73. double z=0.0;
  74. bool PRESSED_LEFT = false, PRESSED_RIGHT = false,
  75.     PRESSED_MIDDLE = false, SPEED_PARTICLES = false;
  76.  
  77. std::vector<Particle> particles;
  78.  
  79. int main(int argc, char **argv)
  80. {
  81.     glutInit(&argc, argv);
  82.     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
  83.     glutInitWindowSize(screen_x, screen_y);
  84.     glutInitWindowPosition(50, 50);
  85.     WIN = glutCreateWindow("Ultimate Gravity Simulator from the darkest depths of ûdun");
  86.  
  87.     glClearColor(0, 0, 0, 1);
  88.     glMatrixMode(GL_PROJECTION);
  89.     glLoadIdentity();
  90.     glOrtho(-screen_x/2, screen_x/2, screen_y/2, -screen_y/2,0, 1);
  91.    
  92.     glutDisplayFunc(display);
  93.     glutMouseFunc(mouse);
  94.     glutMotionFunc(mouseMotion);
  95.     glutKeyboardFunc(keyboard);
  96.     timer();
  97.    
  98.     glutMainLoop();
  99.     return 0;
  100. }
  101.  
  102. void timer(int){
  103.     display();
  104.     if(PRESSED_LEFT && !SPEED_PARTICLES)
  105.     {
  106.         add_particle(5000);
  107.         PRESSED_LEFT = false;
  108.     }
  109.  
  110.     if(PRESSED_RIGHT)
  111.     {
  112.         int x=mouse_x;
  113.         int y=mouse_y;
  114.         for(int i=0;i<250;i++){
  115.             mouse_x=rand()%250-125 + x;
  116.             mouse_y=rand()%250-125 + y;
  117.             add_particle(rand()%500+250);
  118.         }
  119.         PRESSED_RIGHT = false;
  120.     }
  121.  
  122.     if(PRESSED_MIDDLE)
  123.         remove_particles();
  124.  
  125.     for(int i = 0; i < particles.size(); i++){
  126.         Particle &p = particles[i];
  127.         bool not_fall = true;
  128.         float tm,ax,ay;
  129.         int id;
  130.         for(int j = 0; j < particles.size(); j++)
  131.         {
  132.             if(j==i)
  133.                 continue;
  134.  
  135.             const Particle &p1 = particles[j];
  136.  
  137.             float d = sqrt((p1.x - p.x)*(p1.x - p.x) + (p1.y - p.y)*(p1.y - p.y));
  138.  
  139.             if(d > (p1.r+p.r))
  140.             {
  141.                 p.vx += 0.01 * p1.m / (d*d) * (p1.x - p.x)/d;
  142.                 p.vy += 0.01 * p1.m / (d*d) * (p1.y - p.y)/d;
  143.             }
  144.             else{
  145.                 not_fall = false;
  146.                 tm=p1.m+p.m;
  147.                 id=j;
  148.                 ax=p1.vx;
  149.                 ay=p1.vy;
  150.             }
  151.         }
  152.        
  153.         if(mode==1){
  154.             if(p.x<-screen_x/2){
  155.                 p.x=screen_x/2;
  156.             }else if(p.x>screen_x/2){
  157.                 p.x=-screen_x/2;
  158.             }
  159.            
  160.             if(p.y<-screen_y/2){
  161.                 p.y=screen_y/2;
  162.             }else if(p.x>screen_y/2){
  163.                 p.y=-screen_y/2;
  164.             }
  165.         }else if(mode==2){
  166.             if(p.x+p.vx<-screen_x/2 || p.x+p.vx>screen_x/2){
  167.                 p.vx*=(cnst_elastic)*-1;
  168.                 p.vy*=(cnst_elastic);
  169.             }
  170.            
  171.             if(p.y+p.vy<-screen_y/2 || p.y+p.vy>screen_y/2){
  172.                 p.vx*=(cnst_elastic);
  173.                 p.vy*=(cnst_elastic)*-1;
  174.             }
  175.         }
  176.        
  177.         if(not_fall){
  178.             p.x += p.vx;
  179.             p.y += p.vy;
  180.         }else{
  181.             float x,y,r;
  182.                 mouse_x=p.x;
  183.                 mouse_y=p.y;
  184.                 ax+=p.vx;
  185.                 ay+=p.vy;
  186.             if(i>id){
  187.                 particles.erase(particles.begin()+id);
  188.                 particles.erase(particles.begin()+i-1);
  189.             }else
  190.             {
  191.                 particles.erase(particles.begin()+id);
  192.                 particles.erase(particles.begin()+i);
  193.             }
  194.             add_particle(tm,ax,ay);
  195.         }
  196.        
  197.         if(crit_mass==1){
  198.             for(int i=0;i<particles.size();i++){
  199.                 if(particles[i].m>MAX_MASS){
  200.                      int n=25,rmin=15,rmax=20,vel=125;
  201.                      int p=particles[i].m;
  202.                      p/=(n*10);
  203.                      int x=particles[i].x;
  204.                      int y=particles[i].y;
  205.                      particles.erase(particles.begin()+i);
  206.                      for(int i=0;i<n;i++){
  207.                          mouse_x=x+((rand()/RAND_MAX)*(rmax-rmin)+rmin)*cos(i*M_PI/(n/2));
  208.                          mouse_y=y+((rand()/RAND_MAX)*(rmax-rmin)+rmin)*sin(i*M_PI/(n/2));
  209.                          add_particle(p,vel*cos(i*M_PI/(n/2)),vel*sin(i*M_PI/(n/2)));
  210.                          add_particle(p,vel*cos(i*M_PI/(n/2)),vel*sin(i*M_PI/(n/2)));
  211.                     }
  212.                 }
  213.             }
  214.         }
  215.     }
  216.     glutTimerFunc(1, timer, 0);
  217. }
  218.  
  219. void display(){
  220.     glClear(GL_COLOR_BUFFER_BIT);
  221.  
  222.     //~ glColor3f(0, 0, 1);
  223.     //~ glBegin(GL_LINES);
  224.         //~ glVertex2f(line.x1, line.y1);
  225.         //~ glVertex2f(line.x2, line.y2);
  226.     //~ glEnd();
  227.  
  228.     for(int i = 0; i < particles.size(); i++){
  229.         Particle &p = particles[i];
  230.         glColor3f(p.color[0], p.color[1], p.color[2]);
  231.         glBegin(GL_POLYGON);
  232.         for(float a = 0; a < 2*M_PI; a+=0.25)
  233.             glVertex2f(p.r*cos(a) + p.x, p.r*sin(a) + p.y);
  234.         glEnd();
  235.     }
  236.  
  237.     glFlush();
  238.     glutSwapBuffers();
  239. }
  240.  
  241. void mouse(int button, int state, int x, int y){
  242.     mouse_x = x - screen_x/2;
  243.     mouse_y = y - screen_y/2;
  244.  
  245.     if(SPEED_PARTICLES){
  246.         if(line.x2 != 0 && line.y2 != 0 && state == GLUT_UP && PRESSED_LEFT)
  247.             add_particle(100,line.x1 - line.x2, line.y1 - line.y2);
  248.         else{
  249.             line.x1 = line.x2 = mouse_x;
  250.             line.y1 = line.y2 = mouse_y;
  251.         }
  252.     }
  253.  
  254.     if(button == GLUT_LEFT_BUTTON)
  255.         PRESSED_LEFT = state == GLUT_DOWN;
  256.     else if(button == GLUT_RIGHT_BUTTON)
  257.         PRESSED_RIGHT = state == GLUT_DOWN;
  258.     else if(button == GLUT_MIDDLE_BUTTON)
  259.         PRESSED_MIDDLE = state == GLUT_DOWN;
  260. }
  261.  
  262. void mouseMotion(int x, int y){
  263.     mouse_x = x - screen_x/2;
  264.     mouse_y = y - screen_y/2;
  265.  
  266.     if(SPEED_PARTICLES && PRESSED_LEFT){
  267.         line.x2 = mouse_x;
  268.         line.y2 = mouse_y;
  269.     }
  270. }
  271.  
  272. void add_particle(float m,float vx, float vy){
  273.     Particle p;
  274.     p.x = mouse_x;
  275.     p.y = mouse_y;
  276.     p.vx = vx / 30;
  277.     p.vy = vy / 30;
  278.     p.m = m;
  279.     p.r = pow((p.m/M_PI),0.175);
  280.    
  281.     p.color[0] = 1.0;
  282.     p.color[1] = 1.0-p.m*1/MAX_MASS;
  283.     p.color[2] = 0.0;
  284.    
  285.     particles.push_back(p);
  286.  
  287.     if(line.x1 != 0)
  288.         line.x1 = line.x2 = line.y1 = line.y2 = 0;
  289. }
  290.  
  291. void remove_particles(){
  292.     for(int j=0;j<5;j++){
  293.         for(int i = 0; i < particles.size(); i++)
  294.             particles.pop_back();
  295.     }
  296. }
  297.  
  298. void save(){
  299.     FILE *file=fopen("save.dat","wb");
  300.     Particle p;
  301.     for(int i=0;i<particles.size();i++){
  302.         p=particles[i];
  303.         fwrite(&p,sizeof(p),1,file);
  304.     }
  305.     fclose(file);
  306. }
  307.  
  308. void load(){
  309.     FILE *file=fopen("save.dat","rb");
  310.     Particle p;
  311.     remove_particles();
  312.     while(!feof(file)){
  313.         fread(&p,sizeof(p),1,file);
  314.         if(!feof(file)){
  315.             particles.push_back(p);
  316.         }
  317.     }
  318.     fclose(file);
  319. }
  320.  
  321. void keyboard(unsigned char key, int x, int y){
  322.     int num=    25;
  323.     int num2=   25;
  324.     switch(key){
  325.         case 'g':
  326.             save();
  327.             break;
  328.         case 'h':
  329.             load();
  330.             break;
  331.         case 's':
  332.             SPEED_PARTICLES = !SPEED_PARTICLES;
  333.             break;
  334.         case 'c':
  335.             remove_particles();
  336.             remove_particles();
  337.             remove_particles();
  338.             remove_particles();
  339.             remove_particles();
  340.             remove_particles();
  341.             break;
  342.         case 'r':
  343.             for(int i=0;i<250;i++){
  344.                  mouse_x=rand()%screen_x-screen_x/2;
  345.                  mouse_y=rand()%screen_y-screen_y/2;
  346.                  add_particle(rand()%50+1);
  347.             }
  348.             break;
  349.         case 'd':
  350.             for(int i=0;i<particles.size();i++){
  351.                  particles[i].vx=0;
  352.                  particles[i].vy=0;
  353.             }
  354.             break;
  355.         case '9':
  356.             for(y=-50;y<50;y+=5){
  357.                 mouse_x=-100;
  358.                 mouse_y=y;
  359.                 add_particle(1);
  360.                
  361.                 mouse_x=0;
  362.                 add_particle(1);
  363.                
  364.                 mouse_y/=2;
  365.                 mouse_y+=50;
  366.                 add_particle(1);
  367.                
  368.                 mouse_x=100;
  369.                 mouse_y-=10;
  370.                 add_particle(1);
  371.             }
  372.            
  373.             for(x=0;x<20;x++){
  374.                 mouse_x=90+x;
  375.                 mouse_y=20;
  376.                 add_particle(1);
  377.             }
  378.            
  379.             for(x=-100;x<-30;x+=5){
  380.                 mouse_y=50;
  381.                 mouse_x=x;
  382.                 add_particle(1);
  383.             }
  384.            
  385.             for(int i=0;i<180;i+=5){
  386.                 mouse_x=25*sin(i*M_PI/180)+0;
  387.                 mouse_y=25*cos(i*M_PI/180)-25;
  388.                 add_particle(1);
  389.                
  390.                 mouse_x=50*sin(-i*M_PI/180)+100;
  391.                 mouse_y=50*cos(i*M_PI/180);
  392.                 add_particle(1);
  393.             }
  394.            
  395.            
  396.             break;
  397.         case '8':
  398.             {
  399.                 for(int y=-50;y<50;y+=5){
  400.                     mouse_x=-100;
  401.                     mouse_y=y;
  402.                     add_particle(1);
  403.                    
  404.                     mouse_x=-150;
  405.                     add_particle(1);
  406.                    
  407.                     mouse_x=-80;
  408.                     add_particle(1);
  409.                    
  410.                     mouse_x=-10;
  411.                     add_particle(1);
  412.                    
  413.                     mouse_x=40;
  414.                     add_particle(1);
  415.                    
  416.                     mouse_x=60;
  417.                     add_particle(1);
  418.                    
  419.                     mouse_x=110;
  420.                     add_particle(1);
  421.                 }
  422.                
  423.                 for(int i=0;i<180;i+=10){
  424.                     mouse_x=25*cos(i*M_PI/180)-125;
  425.                     mouse_y=25*sin(i*M_PI/180)+50;
  426.                     add_particle(1);
  427.                    
  428.                     mouse_x+=140;
  429.                     add_particle(1);
  430.                    
  431.                     mouse_x=50*sin(i*M_PI/180)-80;
  432.                     mouse_y=50*cos(i*M_PI/180);
  433.                     add_particle(1);
  434.                 }
  435.                
  436.                 int num_of_particles=25;
  437.                 int xmin=60,
  438.                     xmax=110;
  439.                 int ymin=-50,
  440.                     ymax=50;
  441.                 int dx=(xmax-xmin)/num_of_particles;
  442.                 int dy=(ymax-ymin)/num_of_particles;
  443.                
  444.                 for(int i=0;i<num_of_particles;i++){
  445.                     mouse_x=xmin+(dx*i);
  446.                     mouse_y=ymin+(dy*i);
  447.                     add_particle(1);
  448.                 }
  449.             }
  450.             break;
  451.         case '7':
  452.             {
  453.                 int radius=35;
  454.                 mouse_x=0;
  455.                 mouse_y=0;
  456.                 add_particle(5000);
  457.                
  458.                 mouse_x=-radius;
  459.                 add_particle(25,0,mouse_x);
  460.                
  461.                 mouse_x=radius;
  462.                 add_particle(25,0,mouse_x);
  463.                
  464.                 mouse_x=0;
  465.                 mouse_y=-radius;
  466.                 add_particle(25,-mouse_y,0);
  467.                
  468.                 mouse_y=radius;
  469.                 add_particle(25,-mouse_y,0);
  470.             }
  471.             break;// the rules
  472.         case '6':
  473.             {
  474.                 float r=250;
  475.                 for(int i=0;i<1000;i++,r-=0.25){
  476.                     mouse_x=r*sin((i*360/125)*M_PI/180);
  477.                     mouse_y=r*cos((i*360/125)*M_PI/180);
  478.                     add_particle(5);
  479.                 }
  480.             }
  481.             break;
  482.         case '5':
  483.             for(int i=0,r=100;i<250;i++){
  484.                 mouse_x=r*sin((i*360/250)*M_PI/180);
  485.                 mouse_y=r*cos((i*360/250)*M_PI/180);
  486.                 add_particle(1);
  487.             }
  488.            
  489.             for(int i=0,r=75;i<125;i++){
  490.                 mouse_x=r*cos((i*360/250)*M_PI/180);
  491.                 mouse_y=r*sin((i*360/250)*M_PI/180);
  492.                 add_particle(1);
  493.             }
  494.            
  495.             for(int i=0,r=25;i<25;i++){
  496.                 mouse_x=r*sin((i*360/25)*M_PI/180);
  497.                 mouse_y=r*cos((i*360/25)*M_PI/180);
  498.                 mouse_x+=25;
  499.                 mouse_y-=25;
  500.                 add_particle(1);
  501.             }
  502.            
  503.             for(int i=0,r=25;i<25;i++){
  504.                 mouse_x=r*sin((i*360/25)*M_PI/180);
  505.                 mouse_y=r*cos((i*360/25)*M_PI/180);
  506.                 mouse_x-=25;
  507.                 mouse_y-=25;
  508.                 add_particle(1);
  509.             }
  510.            
  511.             break;
  512.         case '4':
  513.             for(int r=10;r<100;r+=10){
  514.                 for(int i=0;i<25;i++){
  515.                     mouse_x=r*sin((i*360/25)*M_PI/180);
  516.                     mouse_y=r*cos((i*360/25)*M_PI/180);
  517.                     add_particle(5);
  518.                 }
  519.             }
  520.             break;//a leg
  521.         case '3':
  522.             for(int i=0,r=100;i<100;i++){
  523.                 mouse_x=r*sin((i*360/100)*M_PI/180);
  524.                 mouse_y=r*cos((i*360/100)*M_PI/180);
  525.                 add_particle(1);
  526.             }
  527.             break;//a leg
  528.         case '2':
  529.             for(int ix=0;ix<num;ix++){
  530.                  mouse_x=ix*(screen_x/num)-screen_x/2;
  531.                  for(int iy=0;iy<num2;iy++){
  532.                      mouse_y=iy*(screen_y/num2)-screen_y/2;
  533.                      add_particle(25);//,mouse_y*0.05,mouse_x*0.05);
  534.                  }
  535.             }
  536.             break;
  537.         case '1':
  538.             for(int ix=0;ix<num*2;ix++){
  539.                  mouse_x=ix*(screen_x/(num*2))-screen_x/2;
  540.                  mouse_y=0;
  541.                  add_particle(25,0,mouse_x*0.025);
  542.             }
  543.             break;
  544.         case ' ':
  545.             z+=0.0025;
  546.             mouse_x=-screen_x/2;
  547.             mouse_y=0;
  548.             add_particle(500,250,sin(z*180/M_PI)*250);
  549.             mouse_x=screen_x/2;
  550.             add_particle(500,-250,sin(z*180/M_PI)*-250);
  551.             break;
  552.         case 27:
  553.         case 'q':
  554.             remove_particles();
  555.             glutDestroyWindow(WIN);
  556.             exit(0);
  557.             break;
  558.     }
  559. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement