Noite de Processing Software Arte e Sistema de Partículas 27 set 2016

De Garoa Hacker Clube
Revisão de 16h44min de 28 de setembro de 2016 por Introscopia (discussão | contribs) (Criou página com 'Abaixo encontra-se o resultado do workshop que ocorreu no dia 27 de Setembro de 2016 sobre Software Arte e Sistemas de Partículas. Ao longo do processo exploramos algumas id...')
(dif) ← Edição anterior | Revisão atual (dif) | Versão posterior → (dif)
Ir para navegação Ir para pesquisar

Abaixo encontra-se o resultado do workshop que ocorreu no dia 27 de Setembro de 2016 sobre Software Arte e Sistemas de Partículas.

Ao longo do processo exploramos algumas ideias separadas, que se encontram comentadas. Em especial no metodo run() da classe Body, tem algumas opções interessantes que podem ser habilitadas ou des- com o uso das duas barras (//).


   ArrayList<Body> bodies;     //Lista de corpos.
   float G;                    //constante gravitacional.
   float mm;                   //massa do mouse
   PVector mouse;              //posicao do mouse convertida em PVector para facilitar.
   int bmode = 0;              //estilo: 0: sem rastro. 1: rastro curto. 2: rastro permanente.
   
   void setup(){
     fullScreen();
     
     G = 8;
     mm = 30;
     
     bodies = new ArrayList();
     
     //inicializacao com 20 corpos aleatoriamente posicionados.
     for( int i = 0; i < 20; i++ ){
       bodies.add( new Body( random( width ), random( height ), random(2, 8) ) );
     }
     
     /* 
     inicializacao com dois corpos onde o segundo esta em orbita circular ao redor do primeiro.
     para que a simulacao rode corretamente o corpo 0 nao pode rodar seu metodo run() dentro do draw(), apenas o display().
     bodies.add( new Body( width/2f, height/2f, 50 ) );
     bodies.add( new Body( (width/2f) - 300, height/2f, 5 ) );
     bodies.get(1).vel = new PVector( 0, -sqrt( G*(50/300.0) ) ); 
     */
     noStroke();
     background(0);
   }
   
   void draw(){
     if(bmode == 0 ) background(0);
     else if( bmode == 1 ){
       fill( 0, 10 );
       rect( 0, 0, width, height );
       fill(255);
     }
     
     mouse = new PVector( mouseX, mouseY );
   
     for( int i = 0; i < bodies.size(); i++ ){
       for( int j = i+1; j < bodies.size(); j++ ){
         bodies.get(i).gravitate( bodies.get(j) );
       }
     }
   
     for( int i = 0; i < bodies.size(); i++ ) bodies.get(i).run();
     
   }
   
   class Body{                     //classe que define um corpo do sistema.
     float mass;
     PVector pos, vel, acc;
     Body(float x, float y, float m){
       mass = m;
       pos = new PVector( x, y );
       //vel = new PVector( random( -2, 2), random(-2, 2) ); //inicializacao das bolas com velocidades aleatorias.
       vel = new PVector();
       acc = new PVector();
     }
     void gravitate( Body b ){
       float f = G * (mass * b.mass) / sq( pos.dist(b.pos) ); // forca
       float a = atan2( b.pos.y - pos.y, b.pos.x - pos.x );   // direcao (angulo em radianos)
       float g = f/mass;                                      // aceleracao
       acc.add( new PVector( g*cos(a), g*sin(a) ) );
       g = f/b.mass;
       b.acc.add( new PVector( g*cos(a+PI), g*sin(a+PI) ) );
     }
     void gravitate_to_mouse(){
       float f = G * (mass * mm) / sq( pos.dist(mouse) );
       float a = atan2( mouseY - pos.y, mouseX - pos.x );
       acc.add( new PVector( f*cos(a), f*sin(a) ) );
     }
     void constrain_velocity( float max ){
       vel.setMag( constrain( vel.mag(), 0, max ) );
     }
     void wrap_around(){
       if( pos.x > width ){
         pos.x -= width;
       }    
       else if ( pos.x < 0 ){
         pos.x = width+pos.x;
       }
       if( pos.y > height ){
         pos.y -= height;
       }
       else if( pos.y < 0 ){
         pos.y = height+pos.y;
       }
     }
     void run(){
       //vel.y += 0.005;                    // Exemplo de gravidade simples (para baixo)
       //vel.setMag( 0.99 * vel.mag() );    // Exemplo onde os corpos desaceleram.
       gravitate_to_mouse();              // inclui o mouse como uma massa dentro do sistema.
       constrain_velocity( 6 );           // aplica um valor maximo para a velocidade, que ajuda a evitar que as massas escapem.
       wrap_around();                     // faz com que os corpos reaparecam na tela pelo lado oposto àquele pelo qual escaparam.(para os nerds de geometria: isso torna o espaco, topologicamente, em um toróide )
       
       vel.add(acc);
       pos.add(vel);
       display();
       acc = new PVector();
     }
     void display(){
       ellipse( pos.x, pos.y, mass, mass );
     }
   }
   
   void keyPressed(){ 
     if( key == 'b' || key == 'B' ){       // aperte 'b' para alterar o estilo de rastro.
       if( bmode == 2 ) bmode = 0;
       else bmode++;
     }
   }