10
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Processing : パーティクル同士の衝突判定

Last updated at Posted at 2015-07-24

collide()関数の中に全てが詰まっています。

Particle.pde
class Particle
{
  PVector pos;
  PVector vel;
  float   damping;
  float   radius;
  float   startTime, lifeSpan;
  color   col;
  float   alpha;
  boolean dead;
  
  // constructor
  Particle( float _x, float _y, float _r, color _c )
  {
    pos    = new PVector( _x, _y );
    radius = _r;
    
    float strength = 0.1;
    float angle    = random( TWO_PI );
    vel            = new PVector( ( cos( angle ) * strength ), ( sin( angle ) * strength ) );
    
    damping        = 0.6;
    
    // birth time
    startTime = millis();
    
    // lifespan ( 10sec ~ 30sec )
    lifeSpan  = random( 10000, 30000 );
    
    col       = _c;
    alpha     = 255;
    dead      = false;
  }
  
  // update
  void update()
  {
    // add gravity
//    vel.y += 0.2;
//    vel.y *= 1.002;
    
    // decelerate
    vel.mult( 0.99 );
    
    // update position
    pos.add( vel );
    
    // bounce off
    if( pos.x < radius )
    {
      pos.x += abs( pos.x - radius );
      vel.x *= -damping;
    }
    else if( pos.x > ( width - radius ) )
    {
      pos.x -= ( pos.x - ( width - radius ) );
      vel.x *= -damping;
    }
    if( pos.y < radius )
    {
      pos.y += abs( pos.y - radius );
      vel.y *= -damping;
    }
    else if( pos.y > ( height - radius ) )
    {
      pos.y -= ( pos.y - ( height - radius ) );
      vel.y *= -damping;
    }
    
    // over the lifespan
    if( millis() > ( startTime + lifeSpan ) )
    {
      dead = true;
//      alpha -= ( alpha / 10 );
//      
//      if( alpha < 1 )
//      {
//        dead = true;
//      }
    }
  }
  
  // draw
  void draw()
  {
    fill( col, alpha );
    ellipse( pos.x, pos.y, ( radius * 2 ), ( radius * 2 ) );
  }
}
collisionOfParticles.pde
// ArrayList of particle
ArrayList< Particle > ps;

////////////////////////////////////////
// setup
////////////////////////////////////////
void setup()
{
  // set window size, and set renderer P2D
  size( 400, 400, P2D );
  
  // for fullscreen ( command + shift + R )
//  size( displayWidth, displayHeight, P2D );
  
  // enable resizing the window
  frame.setResizable( true );
  
  // enable smoothing
  smooth();
  
  // set color mode HSB
  colorMode( HSB, 255 );
  
  background( 255 );
  
  // create instance of ArrayList
  ps = new ArrayList< Particle >();
}


////////////////////////////////////////
// draw
////////////////////////////////////////
void draw()
{
  background( 255 );
  noStroke();
  
  // add a particle
  if( mousePressed )
  {
    ps.add( new Particle( mouseX, mouseY, random( 4, 10 ), color( ( frameCount * 0.1 ) % 255,  120, 255 ) ) );
  }
  
  // update particle position
  for( Particle p : ps )
  {
    p.update();
  }
  
  // collision of particles
  collide();
  
  // remove and draw particles
  for( int i = ( ps.size() - 1 ); i >= 0; --i )
  {
    Particle p = ps.get( i );
    
    if( p.dead )
    {
      ps.remove( i );
    }
    
    p.draw();
  }
}




////////////////////////////////////////
// collide
////////////////////////////////////////
void collide()
{
  for( int i = 0; i < ps.size(); ++i )
  {
    for( int j = ( i + 1 ); j < ps.size(); ++j )
    {
      Particle p1 = ps.get( i );
      Particle p2 = ps.get( j );
      
      // vector from p1 to p2
      PVector diff   = PVector.sub( p2.pos, p1.pos );
      
      // distance from p1 to p2
      float dist     = diff.mag();
      
      // correct distance
      float shortest = ( p1.radius + p2.radius );
      
      if( dist < shortest )
      {
        diff.normalize();
        diff.mult( ( shortest - dist ) * 0.5 );
        
        PVector v1 = diff.get();
        PVector v2 = PVector.mult( diff.get(), -1 );
        
        // move to the correct position
        p1.pos.add( v2 );
        p2.pos.add( v1 );
        
        // scale down the velocity
        float vScale = 0.4;
        PVector vv1  = PVector.mult( v1.get(), vScale );
        PVector vv2  = PVector.mult( v2.get(), vScale );
        
        // add velocity
        p1.vel.add( vv2 );
        p2.vel.add( vv1 );
      }
    }
  }
}




////////////////////////////////////////
// mousePressed
////////////////////////////////////////
void mousePressed()
{
  
}


////////////////////////////////////////
// keyPressed
////////////////////////////////////////
void keyPressed()
{
  if( key == ' ' )
  {
    // clear particles
    ps.clear();
  }
}

gravityを有効にすると荒ぶってしまうのはどうしてだろう。。

10
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?