Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
10
Help us understand the problem. What is going on with this article?
@watabo_shi

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

More than 5 years have passed since last update.

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
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
10
Help us understand the problem. What is going on with this article?