//in order to understand this play, watch this clip:
//http://www.youtube.com/watch?v=cQGi1hXNcMM
//See? Luffy is a rubber man, rubber man, happy rubber man~~
import traer.physics.*;
import traer.animation.*;
final float NODE_SIZE = 20;
final float EDGE_LENGTH = 1;
final float EDGE_STRENGTH = 0.2;
final float SPACER_STRENGTH = 2000;
boolean token = true;
int tag = 0;
ParticleSystem physics;
Smoother3D centroid;
Particle head, body, rShoulder, rArm, rHand, lShoulder, lArm,
lHand, waist, rKnee, rLeg, lKnee, lLeg;
//float space = 10000;
//float space2 = 200;
void setup()
{
size( 800, 600 );
smooth();
frameRate( 24 );
strokeWeight( 2 );
ellipseMode( CENTER );
cursor(CROSS);
physics = new ParticleSystem( 0, 1 );
centroid = new Smoother3D( 0.8 );
centroid.setValue( 0, 0, 1.0 );
makeChar();
//addSpacersToNode();
}
void draw()
{
physics.tick( 1.0 );
if (mousePressed)
{
if (token == true)
{
tag = checkPoint();
}
move(tag);
}
if ( physics.numberOfParticles() > 1 )
updateCentroid();
background( 255 );
//translate( width/2 , height/2 );
scale( centroid.z() );
//translate( -centroid.x(), -centroid.y() );
drawNetwork();
}
void drawNetwork()
{
// draw edges
stroke( 0 );
beginShape( LINES );
for ( int i = 0; i < physics.numberOfSprings(); ++i )
{
Spring e = physics.getSpring( i );
Particle a = e.getOneEnd();
Particle b = e.getTheOtherEnd();
vertex( a.position().x(), a.position().y() );
vertex( b.position().x(), b.position().y() );
}
endShape();
// draw vertices
fill( 160 );
noStroke();
/*for ( int i = 1; i < physics.numberOfParticles(); ++i )
{
Particle v = physics.getParticle( i );
ellipse( v.position().x(), v.position().y(), NODE_SIZE, NODE_SIZE );
}*/
ellipse( body.position().x(), body.position().y(), 1.5*NODE_SIZE, 1.5*NODE_SIZE );
ellipse( waist.position().x(), waist.position().y(), NODE_SIZE, NODE_SIZE );
fill(100);
ellipse( rArm.position().x(), rArm.position().y(), NODE_SIZE, NODE_SIZE );
ellipse( lArm.position().x(), lArm.position().y(), NODE_SIZE, NODE_SIZE );
fill(0);
ellipse( rLeg.position().x(), rLeg.position().y(), NODE_SIZE, NODE_SIZE );
ellipse( lLeg.position().x(), lLeg.position().y(), NODE_SIZE, NODE_SIZE );
ellipse( rShoulder.position().x(), rShoulder.position().y(), NODE_SIZE/3, NODE_SIZE/3 );
ellipse( lShoulder.position().x(), lShoulder.position().y(), NODE_SIZE/3, NODE_SIZE/3 );
ellipse( rKnee.position().x(), rKnee.position().y(), NODE_SIZE/3, NODE_SIZE/3 );
ellipse( lKnee.position().x(), lKnee.position().y(), NODE_SIZE/3, NODE_SIZE/3 );
fill(255);
stroke(0);
ellipse(head.position().x(), head.position().y(),2*NODE_SIZE, 2*NODE_SIZE);
//ellipse(head.position().x(), head.position().y(), NODE_SIZE, NODE_SIZE);
}
void updateCentroid()
{
float
xMax = Float.NEGATIVE_INFINITY,
xMin = Float.POSITIVE_INFINITY,
yMin = Float.POSITIVE_INFINITY,
yMax = Float.NEGATIVE_INFINITY;
for ( int i = 0; i < physics.numberOfParticles(); ++i )
{
Particle p = physics.getParticle( i );
xMax = max( xMax, p.position().x() );
xMin = min( xMin, p.position().x() );
yMin = min( yMin, p.position().y() );
yMax = max( yMax, p.position().y() );
}
float deltaX = xMax-xMin;
float deltaY = yMax-yMin;
if ( deltaY > deltaX )
centroid.setTarget( xMin + 0.5*deltaX, yMin +0.5*deltaY, height/(deltaY+50) );
else
centroid.setTarget( xMin + 0.5*deltaX, yMin +0.5*deltaY, width/(deltaX+50) );
}
void addSpacersToNode()
{
for ( int i = 0; i < physics.numberOfParticles()-1; ++i )
{
for (int j=i;j
{
Particle q = physics.getParticle( i );
Particle p = physics.getParticle( j );
physics.makeAttraction( p, q, -1.5*SPACER_STRENGTH, 2 );
}
}
}
void makeChar()
{
head = physics.makeParticle(1,width/2,height/2,0);
//head.makeFixed();
//make the other parts of the body
body = physics.makeParticle(1,width/2,height/2,0);
rShoulder = physics.makeParticle(1,width/2,height/2,0);
rArm = physics.makeParticle(1,width/2,height/2,0);
//rHand = physics.makeParticle();
lShoulder = physics.makeParticle(1,width/2,height/2,0);
lArm = physics.makeParticle(1,width/2,height/2,0);
//lHand = physics.makeParticle();
waist = physics.makeParticle(1,width/2,height/2,0);
rKnee = physics.makeParticle(1,width/2,height/2,0);
rLeg = physics.makeParticle(1,width/2,height/2,0);
lKnee = physics.makeParticle(1,width/2,height/2,0);
lLeg = physics.makeParticle(1,width/2,height/2,0);
addSpacersToNode();
//make connections between parts
physics.makeSpring(head, body, 1.2*EDGE_STRENGTH, 1.2*EDGE_STRENGTH, EDGE_LENGTH);
physics.makeSpring(body, rShoulder, EDGE_STRENGTH, EDGE_STRENGTH, EDGE_LENGTH/3);
physics.makeSpring(body, lShoulder, EDGE_STRENGTH, EDGE_STRENGTH, EDGE_LENGTH/3);
physics.makeSpring(rShoulder, rArm, EDGE_STRENGTH, EDGE_STRENGTH/10, EDGE_LENGTH);
//physics.makeSpring(rArm, rHand, EDGE_STRENGTH, EDGE_STRENGTH, EDGE_LENGTH);
physics.makeSpring(lShoulder, lArm, EDGE_STRENGTH, EDGE_STRENGTH/10, EDGE_LENGTH);
//physics.makeSpring(lArm, lHand, EDGE_STRENGTH, EDGE_STRENGTH, EDGE_LENGTH);
physics.makeSpring(body, waist, 2*EDGE_STRENGTH, 2*EDGE_STRENGTH, EDGE_LENGTH);
physics.makeSpring(waist, rKnee, EDGE_STRENGTH, EDGE_STRENGTH, EDGE_LENGTH);
physics.makeSpring(rKnee, rLeg, EDGE_STRENGTH, EDGE_STRENGTH, EDGE_LENGTH);
physics.makeSpring(waist, lKnee, EDGE_STRENGTH, EDGE_STRENGTH, EDGE_LENGTH);
physics.makeSpring(lKnee, lLeg, EDGE_STRENGTH, EDGE_STRENGTH, EDGE_LENGTH);
//move parts
body.moveTo(head.position().x()+random(-1,1), head.position().y()+random(-1,1),0);
rShoulder.moveTo(body.position().x()+random(-1,1), body.position().y()+random(-1,1),0);
rArm.moveTo(rShoulder.position().x()+random(-1,1), rShoulder.position().y()+random(-1,1),0);
//rHand.moveTo(rArm.position().x()+random(-1,1), rArm.position().y()+random(-1,1),0);
lShoulder.moveTo(body.position().x()+random(-1,1), body.position().y()+random(-1,1),0);
lArm.moveTo(lShoulder.position().x()+random(-1,1), lShoulder.position().y()+random(-1,1),0);
//lHand.moveTo(lArm.position().x()+random(-1,1), lArm.position().y()+random(-1,1),0);
waist.moveTo(body.position().x()+random(-1,1), body.position().y()+random(-1,1),0);
rKnee.moveTo(waist.position().x()+random(-1,1), waist.position().y()+random(-1,1),0);
rLeg.moveTo(rKnee.position().x()+random(-1,1), rKnee.position().y()+random(-1,1),0);
lKnee.moveTo(waist.position().x()+random(-1,1), waist.position().y()+random(-1,1),0);
lLeg.moveTo(lKnee.position().x()+random(-1,1), lKnee.position().y()+random(-1,1),0);
}
//collisiton detection on border
void handleBoundaryCollisions( Particle p )
{
if ( p.position().x() < 0 || p.position().x() > width )
p.setVelocity( -2*p.velocity().x(), p.velocity().y(), 0 );
if ( p.position().y() < 0 || p.position().y() > height )
p.setVelocity( p.velocity().x(), -2*p.velocity().y(), 0 );
p.moveTo( constrain( p.position().x(), 0, width ), constrain( p.position().y(), 0, height ), 0 );
}
//check the body part
int checkPoint(){
//float N2 = NODE_SIZE * NODE_SIZE;
//println(NODE_SIZE+"+"+distance+",");
for ( int i = 0; i < physics.numberOfParticles(); ++i )
{
Particle p = physics.getParticle( i);
float distance = sqrt(sq(p.position().x()-mouseX)+sq(p.position().y()-mouseY));
if (distance < NODE_SIZE){
token = false;
return i;
//print(i);
}
//float c = p.position().x();
//print(c);
}
return 3;
//rArm.moveTo(mouseX-400, mouseY-200, 0);
//
}
//drag the char
void move(int tag)
{
Particle p = physics.getParticle(tag);
p.moveTo(mouseX, mouseY, 0);
//println(NODE_SIZE+"+"+distance+",");
//rArm.velocity().clear();
}
//reset the tag
void mouseReleased()
{
Particle p = physics.getParticle(tag);
p.setVelocity((mouseX - pmouseX), (mouseY - pmouseY), 0 );
token = true;
}
void keyPressed()
{
switch (key)
{
case ' ':
physics.setGravity(0);
case '=':
physics.setGravity(1);
case '-':
physics.setGravity(-1);
}
}