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

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

 メニュー

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

Processing:オブジェクトを連結して橋を作る

「The Nature of Code」からオブジェクトを連結して橋を作ります。複数のパーティクルを連結して橋と見立てます。Processingでプログラムを書いて、動作を確認します。動作を確認できるところがProcessingの楽しいところです。

オブジェクトを連結して橋を作る

以下は、複数のパーティクルを連結して橋を作る参考例です。

//DistanceJoint
import shiffman.box2d.*;
import org.jbox2d.common.*;
import org.jbox2d.dynamics.joints.*;
import org.jbox2d.collision.shapes.*;
import org.jbox2d.collision.shapes.Shape;
import org.jbox2d.dynamics.*;
import org.jbox2d.dynamics.contacts.*;

Box2DProcessing box2d;
Bridge bridge;
ArrayList<Box> boxes;

void setup(){
  size(200, 200);
  
  box2d = new Box2DProcessing(this);
  box2d.createWorld();
  
  bridge = new Bridge(width, width/2);
  boxes = new ArrayList<Box>();
}

void draw(){
  background(255);
  box2d.step();
  
  //boxesの描画
  if(random(1) < 0.2){
    Box p = new Box(width/2, 30);
    boxes.add(p);
  }
  
  //boxesの描画
  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);
    }
  }
  
  //橋の描画
  bridge.display();
}
class Bridge{
  float totalLength;
  int numPoints;
  
  ArrayList<Particle> particles;
  
  //コンストラクタ
  Bridge(float l, int n){
    totalLength = l;
    numPoints = n;
    
    particles = new ArrayList();
    
    float len = totalLength / numPoints;
    
    for(int i = 0; i < numPoints+1; i++){
      Particle p = null;
      
      if(i == 0 || i == numPoints){  //橋の両端
        p = new Particle(i*len, height/4, 4, true);
      }else{
        p = new Particle(i*len, height/4, 4, false);
      }
      particles.add(p);
      
      if(i > 0){
        //連結処理
        DistanceJointDef djd = new DistanceJointDef();
        Particle previous = particles.get(i-1);
        djd.bodyA = previous.body;
        djd.bodyB = p.body;
        
        djd.length = box2d.scalarPixelsToWorld(len);
        djd.frequencyHz = 0;
        djd.dampingRatio = 0;
        
        DistanceJoint dj = (DistanceJoint)box2d.world.createJoint(djd);
      }
    }
  }
  
  //図形の描画
  void display(){
    for(Particle p: particles){
      p.display();
    }
  }
}
class Particle{
  Body body;
  float r;
  
  //コンストラクタ
  Particle(float x, float y, float r_, boolean fixed){
    r = r_;
    
    //ボディの定義
    BodyDef bd = new BodyDef();
    if(fixed){
      bd.type = BodyType.STATIC;
    }else{
      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);
  }
  
  void killBody(){
    box2d.destroyBody(body);
  }
  
  boolean done(){
    Vec2 pos = box2d.getBodyPixelCoord(body);
    if(pos.y > height+r*2){
      killBody();
      return true;
    }
    return false;
  }
  
  //図形の描画
  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 Box{
  
  Body body;
  float w;
  float h;
  
  //コンストラクタ
  Box(float x, float y){
    w = random(4, 16);
    h = random(4, 16);
    
    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 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_){
    
    //ポリゴンの定義
    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.5;
    
    //ボディの定義
    BodyDef bd = new BodyDef();
    bd.type = BodyType.DYNAMIC;
    bd.position.set(box2d.coordPixelsToWorld(center));
    
    body = box2d.createBody(bd);
    body.createFixture(fd);
    
    body.setLinearVelocity(new Vec2(random(-5, 5), random(2, 5)));
    body.setAngularVelocity(random(-5, 5));    
  }
}

まとめ

「The Nature of Code」からオブジェクトを連結して橋を作りました。引き続き、「The Nature of Code」の内容を勉強します。

参考書籍

Javaの勉強にもなるので一石二鳥です。

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