元Webデザイナー兼コーダーの備忘録

ウェブデザインやプログラミング、ブログのカスタマイズなどについてアウトプットしています。

 メニュー

» HTML入門のまとめはこちらです。

Processing:風で引き寄せられる力

「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の勉強にもなるので一石二鳥です。

» HTML入門のまとめはこちらです。