• fullscreen
• Boundary.pde
• Box.pde
• build.pde
• gui.pde
• UPhysicsBox2D03.pde
• ```// The Nature of Code
// <http://www.shiffman.net/teaching/nature>
// Spring 2010
// PBox2D example

// A fixed boundary class (now incorporates angle)

class Boundary {

// A boundary is a simple rectangle with x,y,width,and height
float x;
float y;
float w;
float h;
// But we also have to make a body for box2d to know about it
Body b;

Boundary(float x_,float y_, float w_, float h_, float angle) {
x = x_;
y = y_;
w = w_;
h = h_;

// Figure out the box2d coordinates
float box2dW = box2d.scalarPixelsToWorld(w/2);
float box2dH = box2d.scalarPixelsToWorld(h/2);
Vec2 center = new Vec2(x,y);

// Define the polygon
PolygonDef sd = new PolygonDef();
sd.setAsBox(box2dW, box2dH);
sd.density = 0;    // No density means it won't move!
sd.friction = 0.3f;

// Create the body
BodyDef bd = new BodyDef();
bd.position.set(box2d.coordPixelsToWorld(center));
bd.angle = angle;
b = box2d.createBody(bd);
b.createShape(sd);
}

// Draw the boundary, if it were at an angle we'd have to do something fancier
void display() {
fill(0);
rectMode(CENTER);

float a = b.getAngle();

pushMatrix();
translate(x,y);
rotate(-a);
rect(0,0,w,h);
popMatrix();
}

}

```
```// The Nature of Code
// <http://www.shiffman.net/teaching/nature>
// Spring 2010
// PBox2D example

// A rectangular box
class Box  {

// We need to keep track of a Body and a width and height
Body body;
float w;
float h;
int col;

int notMovedCnt;
Vec2 pos,lastPos;

// Constructor
Box(float x, float y,float ww,float hh) {
w = ww;
h = hh;
// Add the box to the box2d world
makeBody(new Vec2(x,y),w,h);

col=UColorTool.interpolate(random(1),"FF0099","FF6600");
}

// This function removes the particle from the box2d world
void killBody() {
box2d.destroyBody(body);
}

// Is the particle ready for deletion?
boolean done() {
// Let's find the screen position of the particle
if(lastPos!=null && dist(lastPos.x,lastPos.y,pos.x,pos.y)<0.1)
notMovedCnt++;
else notMovedCnt=0;

// Does it not move? Kill if we've deleted <5 this frame
if (notMovedCnt>100 && deletedThisFrame<5) {
deletedThisFrame++;
killBody();
return true;
}

if (pos.y > height+w) {
killBody();
return true;
}

return false;
}

// Drawing the box
void display() {
// We look at each body and get its screen position
lastPos=pos;
pos = box2d.getBodyPixelCoord(body);
// Get its angle of rotation
float a = body.getAngle();

if(drawTrails) {
stroke(col, 50);
if(lastPos!=null) line(pos.x,pos.y,
lastPos.x,lastPos.y);
noFill();
ellipse(pos.x,pos.y,w,w);
return;
}

rectMode(CENTER);
pushMatrix();
translate(pos.x,pos.y);
rotate(-a);
fill(col);
stroke(0);
ellipse(0,0,w,w);
popMatrix();
}

// This function adds the rectangle to the box2d world
void makeBody(Vec2 center, float w_, float h_) {

// Define a polygon (this is what we use for a rectangle)
PolygonDef sd = new PolygonDef();
CircleDef cd= new CircleDef();

float box2dW = box2d.scalarPixelsToWorld(w_/2);
float box2dH = box2d.scalarPixelsToWorld(h_/2);
sd.setAsBox(box2dW, box2dH);

// Parameters that affect physics
cd.density = 1.0f;
cd.friction = 0.3f;
cd.restitution = 0.5f;

// Define the body and make it from the shape
BodyDef bd = new BodyDef();
bd.position.set(box2d.coordPixelsToWorld(center));

body = box2d.createBody(bd);
body.createShape(cd);
body.setMassFromShapes();

// Give it some initial random velocity
body.setLinearVelocity(new Vec2(random(-5,5),random(2,5)));
body.setAngularVelocity(random(-5,5));

}

}

```
```void buildBoundaries() {
boundaries = new ArrayList<Boundary>();

w=step;

float nx=(int)((float)width/w);
float ny=(int)((float)height/w);
float xd=(float)width/nx;
float yd=(float)height/ny;

float angle=0,lastAngle,diff;
for(float y=0; y<ny; y++) {
for(float x=0; x<nx; x++) {

// make sure an angle doesn't repeat immediately
lastAngle=angle;
do {
angle=60*(int)random(6);
diff=abs(angle-lastAngle);
//        println(x+" "+y+" "+diff +" "+((180-diff)<10));
} while(diff<10 || (180-diff)<10);

}
}
}

```
```USimpleGUI gui;

void initGUI() {
gui=new USimpleGUI(this);

step=100;
gui.setLayout(false);
}

public void reinit() {
trailFrameCnt=0;

box2d = new PBox2D(this);
box2d.createWorld();
// We are setting a custom gravity
box2d.setGravity(0, -25);

boxes = new ArrayList<Box>();

buildBoundaries();
}
```
```/**
* UPhysicsBox2D03.pde - Marius Watz, 2012
* http://workshop.evolutionzone.com
*
* Creates a maze of boundaries for particles to
* bounce off. Has semi-smart logic for detecting and
* removing stuck elements.
*
* Code for Boundary and Box are taken from Daniel
* Shiffman's "Boxes" demo, with some modifications.
*
*/

import controlP5.*;
import unlekker.util.*;

import pbox2d.*;
import org.jbox2d.collision.shapes.*;
import org.jbox2d.common.*;
import org.jbox2d.dynamics.*;

// Box2D instance
PBox2D box2d;
ArrayList<Boundary> boundaries;
ArrayList<Box> boxes;

public float step,w; // step size of barrier grid
public float nx,ny; // resolution of barrier grid

long lastDropped;
int deletedThisFrame=0;

public boolean drawTrails=false;
int trailFrameCnt=0;

void setup() {
size(800,600);

smooth();

initGUI();
reinit();
}

void draw() {
// update box2d
box2d.step();

// used to make sure we only kill one static piece
// per frame
deletedThisFrame=0;

if(!drawTrails || trailFrameCnt==0) {
// draw everything normally
background(255);
// show boundaries
for (Boundary wall: boundaries) {
wall.display();
}
}

if(drawTrails) trailFrameCnt++;
else trailFrameCnt=0;

// draw boxes
for (Box b: boxes) {
b.display();
}

// handle continous mousePressed
if(mousePressed) mousePressed();

rectMode(CORNER);
gui.draw();
}

// once they are "done" (i.e. they are off screen),
// boxes can be deleted

// note that we are deleting elements as we go, so the
// value of boxes.size()will change on the fly
for (int i = 0; i<boxes.size(); i++) {
Box b = boxes.get(i);
if (b.done()) boxes.remove(b);
}

// reset notMovedCnt if an element has been deleted
if(deletedThisFrame>0)
for(Box b:boxes) b.notMovedCnt=0;
}

void mousePressed() {
if(gui.isMouseOver()) return;

// 30 msec time constraint on dropping new elements
if((millis()-lastDropped)>30) {
float r=step*random(1,5)/10;
Box p = new Box(mouseX,mouseY,r,r);
lastDropped=millis();
}
}

```

### tweaks (0)

This sketch is running as Java applet, exported from Processing.

4