Fisicaで扱う物体には、剛体(FBody)、弾性体(FBlob)、これらをつなぐジョイント(FJoint)が用意されている。
剛体には線分(FLine)、球(FCircle)、箱(FBox)、多角形(FPoly)がある。
FLine stick;のように線分の型をもつ変数stickを用意し、
stick = new FLine(x1, y1, x2, y2);のように作成し
world.add( stick );で追加する。
FCircle ball; ball = new FCircle(r); ball.setPosition(x,y); world.add(ball);
FBox brick; brick = new FBox(w, h) brick.setPosition(x, y); brick.setRotation( radians(th) ); world.add(brick);
new FPoly()で作成し、vertex(x,y)で頂点を追加していく。例えば、
b = new FPoly(); b.vertex(10,20); b.vertex(40,20); b.vertex(10,60); b.vertex(10,20); world.add(b);で三角形が作成される。
pend = new FCompound(); ball = new FCircle(20); ball.setPosition( 100, 100 ); thread = new FLine( 100, 0, 100, 100 ); pend.addBody( ball ); pend.addBody( thread );
new FBlob()で作成し、多角形と同様にvertex(x,y)で頂点を追加していく。球形も作れて
b = new FBlob(); b.setAsCircle(cx, cy, r);で、中心(cx,cy)、半径rの球が得られる。
bodyはいずれかの物体を表す。
| body.setVelocity( vx, vy ); | 速度を指定する。 |
| body.setPosition( x, y ); | 重心の位置を指定する。 |
| body.setDensity( d ); | 密度を指定する。(指定がなければ1) |
| body.setDamping( b ); | 抵抗力の係数(1/60秒で速度が(1-b)倍になる)を指定する。(指定がなければ0.5) |
| body.setFriction( f ); | 摩擦係数(動摩擦係数、静止摩擦係数で共通)を指定する。摩擦力は垂直抗力のf倍となる。(指定がなければ0.5) |
| body.setRestitution( e ); | 跳ね返り係数を指定する。(指定がなければ0.1) |
| body.setRotation( th ); | 傾きを指定する(単位はラジアン) |
| body.setAngularVelocity( th ); | 重心の周りの回転角速度を指定する。 |
| body.setAngularDamping( b ); | 回転抵抗力の係数(1/60秒で角速度が(1-b)倍になる)を指定する。(指定がなければ0.5) |
| body.setStatic(trueまたはfalse); | trueにすると物体は静止して動かない。(指定がなければfalse) |
| body.setRotatable(trueまたはfalse); | trueにすると物体は回転できる。(指定がなければtrue) |
| body.setGrabbable(trueまたはfalse); | trueにすると物体をマウスで動かせる。(指定がなければtrue) |
| body.setFill(r,g,b); | 塗りつぶす色を(r,g,b)にする。(指定がなければ白) |
| body.setNoFill(); | 塗りつぶさない。 |
| body.setStroke(r,g,b); | 枠線の色を(r,g,b)にする。(指定がなければ黒) |
| body.setNoStroke(); | 枠線を描かない。 |
| body.setStrokeWeight(w); | 枠線の幅をwにする。 |
| body.addForce(fx, fy); | 重心に力(fx,fy)を加える。 |
| body.addForce(fx, fy, x, y); | 位置(x,y)に力(fx,fy)を加える。 |
| body.addImpulse(ix, iy); | 重心に力積(ix,iy)を加える。 |
| body.addImpulse(ix, iy, x, y); | 位置(x,y)に力積(ix,iy)を加える。 |
| body.getX(); | x方向の位置 |
| body.getY(); | y方向の位置 |
| body.getVelocityX(); | x方向の速度位置 |
| body.getVelocityY(); | y方向の速度位置 |
| body.getMass(); | 質量 |
| body.isTouchingBody( other ) | otherと接触しているか? |
次の例は床に置かれた2つの球をシミュレートする。左の球の上でマウスをクリックすると右向きの力積が加えられる。
import fisica.*;
FWorld world;
FCircle ball1, ball2;
void setup(){
size(600,300);
Fisica.init(this);
world = new FWorld();
world.setEdges();
world.setEdgesFriction( 0 );
ball1=new FCircle(40);
ball1.setDamping( 0 );
ball1.setDensity( 2 );
ball1.setFriction( 0.1 );
ball1.setRestitution( 1 );
ball1.setPosition( 50, 274.5 );
ball1.setGrabbable( false );
ball1.setFill( 128, 255, 128 );
world.add( ball1 );
ball2=new FCircle(40);
ball2.setDamping( 0 );
ball2.setDensity( 4 );
ball2.setFriction( 0.1 );
ball2.setRestitution( 1 );
ball2.setPosition( 200, 274.5 );
ball2.setGrabbable( false );
ball2.setFill( 255, 128, 128 );
world.add( ball2 );
}
void mouseClicked(){
if( dist( mouseX, mouseY, ball1.getX(), ball1.getY() )<20 ){
ball1.addImpulse( ball1.getMass()*100, 0 );
}
}
void draw(){
background(0);
world.step();
world.draw();
}
また、上のプログラムのdraw()の部分を次のように書き換えると、2つの球が接触すると右側の球の色がしばらく(0.5秒ほど)青くなる。
int counter = 0;
void draw(){
background(0);
world.step();
if( ball1.isTouchingBody( ball2 ) ){
counter = 30;
}
if( counter>0 ){
ball1.setFill( 0, 0, 255 );
counter --;
} else {
ball1.setFill( 255 );
}
world.draw();
}
ここで、counterという変数が青く表示する時間を保持している。
if( ball1.isTouchingBody( ball2 ) ){
counter = 30;
}
の部分で2つの球が接触するとcounterを30にセットする。以降、counterは青く表示する時間をカウントダウンし、0になると白で表示するようにする。