「The Nature of Code」から風で引き寄せられる力について取り上げます。物体に風の力を適用します。Processingでプログラムを書いて、動作を確認します。動作を確認できるところがProcessingの楽しいところです。
風で引き寄せられる力
Box2DのapplyForce()メソッドを利用して、風の力を適用します。以下は、その参考例です。
//Basic example of falling rectangles //ApplyForceSimpleWind import shiffman.box2d.*; import org.jbox2d.common.*; import org.jbox2d.collision.shapes.*; import org.jbox2d.dynamics.*; Box2DProcessing box2d; ArrayList<Boundary> boundaries; ArrayList<Box> boxes; void setup(){ size(200, 200); box2d = new Box2DProcessing(this); box2d.createWorld(); box2d.setGravity(0, -20); //空のArrayListを作る boxes = new ArrayList<Box>(); boundaries = new ArrayList<Boundary>(); boundaries = new ArrayList(); boundaries.add(new Boundary(width/4,height-5,width/2-50,10)); boundaries.add(new Boundary(3*width/4,height-5,width/2-50,10)); boundaries.add(new Boundary(width-5,height/2,10,height)); boundaries.add(new Boundary(5,height/2,10,height)); } void draw(){ background(255); box2d.step(); //ボックスの追加 if(random(1) < 0.1){ Box p = new Box(random(width), 10); boxes.add(p); } //マウスがクリックされたときの処理 if(mousePressed){ for(Box b: boxes){ Vec2 wind = new Vec2(20, 0); b.applyForce(wind); } } //境界の表示 for(Boundary wall: boundaries){ wall.display(); } //ボックスの表示 for(Box b: boxes){ b.display(); } for(int i = boxes.size()-1; i >= 0; i--){ Box b = boxes.get(i); if(b.done()){ boxes.remove(i); } } fill(0); text("Click mouse to attract boxes", 20, 20); }
class Boundary{ float x; float y; float w; float h; Body b; //コンストラクタ Boundary(float x_, float y_, float w_, float h_){ x = x_; y = y_; w = w_; h = h_; //ボディの定義 BodyDef bd = new BodyDef(); bd.type = BodyType.STATIC; bd.position.set(box2d.coordPixelsToWorld(x, y)); b = box2d.createBody(bd); //ポリゴンの定義 PolygonShape sd = new PolygonShape(); float box2dW = box2d.scalarPixelsToWorld(w/2); float box2dH = box2d.scalarPixelsToWorld(h/2); sd.setAsBox(box2dW, box2dH); b.createFixture(sd, 1); } //図形の描画 void display(){ fill(0); stroke(0); rectMode(CENTER); rect(x, y, w, h); } }
class Box{ Body body; float w; float h; //コンストラクタ Box(float x, float y){ w = random(8, 16); h = w; makeBody(new Vec2(x, y), w, h); } //オブジェクトの削除 void killBody(){ box2d.destroyBody(body); } //ウィンドウから外れたかの判定 boolean done(){ Vec2 pos = box2d.getBodyPixelCoord(body); if(pos.y > height+w*h){ killBody(); return true; } return false; } //風力の適用 void applyForce(Vec2 force){ Vec2 pos = body.getWorldCenter(); body.applyForce(force, pos); } //図形の描画 void display(){ Vec2 pos = box2d.getBodyPixelCoord(body); float a = body.getAngle(); rectMode(CENTER); pushMatrix(); translate(pos.x, pos.y); rotate(-a); stroke(0); fill(127); //strokeWeight(2); rect(0, 0, w, h); popMatrix(); } void makeBody(Vec2 center, float w_, float h_){ //ボディの定義 BodyDef bd = new BodyDef(); bd.type = BodyType.DYNAMIC; bd.position.set(box2d.coordPixelsToWorld(center)); bd.angle = random(TWO_PI); body = box2d.createBody(bd); //ポリゴンの定義 PolygonShape sd = new PolygonShape(); float box2dW = box2d.scalarPixelsToWorld(w_/2); float box2dH = box2d.scalarPixelsToWorld(h_/2); sd.setAsBox(box2dW, box2dH); FixtureDef fd = new FixtureDef(); fd.shape = sd; fd.density = 1; fd.friction = 0.3; fd.restitution = 0.2; body.createFixture(fd); } }
まとめ
「The Nature of Code」から風で引き寄せられる力について取り上げました。物体に風の力を適用しました。引き続き、「The Nature of Code」の内容を勉強します。
参考書籍
※Javaの勉強にもなるので一石二鳥です。