「The Nature of Code」から引き寄せる力ついて取り上げます。ある物体に複数の物体を引き寄せます。Processingでプログラムを書いて、動作を確認します。動作を確認できるところがProcessingの楽しいところです。
引き寄せる力
Box2DのapplyForce()メソッドを利用して、力を適用します。以下は、その参考例です。
//Basic example of falling rectangles //AttractionApplyForce import shiffman.box2d.*; import org.jbox2d.common.*; import org.jbox2d.collision.shapes.*; import org.jbox2d.dynamics.*; Box2DProcessing box2d; Mover[] movers = new Mover[25]; Attractor a; void setup(){ size(200, 200); box2d = new Box2DProcessing(this); box2d.createWorld(); box2d.setGravity(0, 0); //ムーバーの生成 for(int i = 0; i < movers.length; i++){ movers[i] = new Mover(random(8, 16), random(width), random(height)); } //アトラクタの生成 a = new Attractor(32, width/2, height/2); } void draw(){ background(255); box2d.step(); a.display(); for(int i = 0; i < movers.length; i++){ Vec2 force = a.attract(movers[i]); movers[i].applyForce(force); movers[i].display(); } }
class Mover{ Body body; float r; //コンストラクタ Mover(float r_, float x, float y){ r = r_; //ボディの定義 BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; bd.position = box2d.coordPixelsToWorld(x, y); body = box2d.world.createBody(bd); //形状の定義 CircleShape cs = new CircleShape(); cs.m_radius = box2d.scalarPixelsToWorld(r); FixtureDef fd = new FixtureDef(); fd.shape = cs; fd.density = 1; fd.friction = 0.3; fd.restitution = 0.5; body.createFixture(fd); body.setLinearVelocity(new Vec2(random(-5, 5), random(-5, -5))); body.setAngularVelocity(random(-1, 1)); } void applyForce(Vec2 v){ body.applyForce(v, body.getWorldCenter()); } //図形の描画 void display(){ Vec2 pos = box2d.getBodyPixelCoord(body); float a = body.getAngle(); pushMatrix(); translate(pos.x, pos.y); rotate(-a); fill(127); stroke(0); strokeWeight(2); ellipse(0, 0, r*2, r*2); line(0, 0, r, 0); popMatrix(); } }
class Attractor{ Body body; float r; //コンストラクタ Attractor(float r_, float x, float y){ r = r_; //ボディの定義 BodyDef bd = new BodyDef(); bd.type = BodyType.STATIC; bd.position = box2d.coordPixelsToWorld(x, y); body = box2d.world.createBody(bd); //形状の定義 CircleShape cs = new CircleShape(); cs.m_radius = box2d.scalarPixelsToWorld(r); body.createFixture(cs, 1); } //引力 Vec2 attract(Mover m){ float G = 100; Vec2 pos = body.getWorldCenter(); Vec2 moverPos = m.body.getWorldCenter(); Vec2 force = pos.sub(moverPos); float distance = force.length(); distance = constrain(distance, 1, 5); force.normalize(); float strength = (G * 1 * m.body.m_mass) / (distance * distance); force.mulLocal(strength); return force; } //図形の描画 void display(){ Vec2 pos = box2d.getBodyPixelCoord(body); float a = body.getAngle(); pushMatrix(); translate(pos.x, pos.y); rotate(-a); fill(175); stroke(0); strokeWeight(2); ellipse(0, 0, r*2, r*2); popMatrix(); } }
まとめ
「The Nature of Code」から引き寄せる力について取り上げました。ある物体に複数の物体を引き寄せることができました。引き続き、「The Nature of Code」の内容を勉強します。
参考書籍
※Javaの勉強にもなるので一石二鳥です。