Advertisement
granada

Gravity simulator

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