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を有効にすると荒ぶってしまうのはどうしてだろう。。