Hi,
I’m looking for some kind of ChainShape or similar that I can update the position of manually to act as a moving boundary for dynamic objects. They should collide but not respond to forces.
I’m trying to make a simulation with a bunch of small objects and a “floor” to hold them, and the ability to rotate the gravity vector and have the “floor” rotate with it. Ultimately to deploy on a device with an IMU so it can sense the real world down and assign it to the gravity vector.
I have the simulation working with a static boundary at the floor and I can update the gravity vector. I also have the below sketch to figure out where the new floor should go, and that works. It gives me a line made of 3 vertices.
I’m struggling to work out what kind of box2d body to use for those boundaries. I can’t find a way to update the position of a ChainShape once it’s initialized.
Thanks in advance!
PVector down = new PVector(0, 1);
float angle;
ArrayList<alLine> boundaries = new ArrayList<alLine>();
PVector corner = new PVector();
PVector p1 = new PVector();
PVector p2 = new PVector();
Wall wall1;
Wall wall2;
void setup() {
size(800, 800);
background(0);
stroke(255);
strokeWeight(10);
boundaries.add(new alLine(0, 0, width, 0));
boundaries.add(new alLine(width, 0, width, height));
boundaries.add(new alLine(width, height, 0, height));
boundaries.add(new alLine(0, height, 0, 0));
wall1 = new Wall(new PVector(), new PVector());
wall2 = new Wall(new PVector(), new PVector());
}
void draw() {
background(0);
stroke(255);
angle = map(mouseX, 0, width, 0, TWO_PI);
down = PVector.fromAngle(angle);
text(down.x, width/2-60, height/2-20);
text(down.y, width/2, height/2-20);
text(angle, width/2, height/2 -60);
magLine(new PVector(width/2, height/2), down, 50);
for (alLine a : boundaries) {
PVector i = isIntersecting(a, down);
PVector j = isIntersecting(a, PVector.fromAngle(angle-TWO_PI/8));
if (j != null) {
p1 = j;
}
PVector k = isIntersecting(a, PVector.fromAngle(angle+TWO_PI/8));
if (k != null) {
p2 = k;
}
}
wall1.set(p1, corner);
wall2.set(corner, p2);
if (angle > 0 && angle < PI/2) {
point(width, height);
corner.set(width, height);
}
if (angle > HALF_PI && angle < PI) {
point(0, height);
corner.set(0, height);
}
if (angle > PI && angle < PI * 1.5) {
point(0, 0);
corner.set(0, 0);
}
if (angle > PI*1.5 && angle < TAU) {
point(width, 0);
corner.set(width, 0);
}
if (angle == 0) {
p1.set(width, 0);
corner.set(width, height/2);
p2.set(width, height);
}
if (angle == HALF_PI) {
p1.set(width, height);
corner.set(width/2, height);
p2.set(0, height);
}
if (angle == PI) {
p1.set(0, height);
corner.set(0, height/2);
p2.set(0, 0);
}
if (angle == 1.5*PI) {
p1.set(0, 0);
corner.set(width/2, 0);
p2.set(width, 0);
}
textAlign(CENTER);
text("move mouse", width/2, 50);
wall1.draw();
wall2.draw();
stroke(255,0,0);
vPoint(p1);
vPoint(p2);
vPoint(corner);
}
void magLine(PVector pos, PVector dir, float mag) {
pushMatrix();
translate(pos.x, pos.y);
line(0, 0, dir.x*mag, dir.y*mag);
popMatrix();
}
PVector isIntersecting(alLine wl, PVector down) {
float x1 = wl.pos1.x; // rename variables to match those of algorithm aka Dan Schiffman
float y1 = wl.pos1.y; // for convenience
float x2 = wl.pos2.x;
float y2 = wl.pos2.y;
float x3 = width/2;
float y3 = height/2;
float x4 = width/2 + down.x;
float y4 = height/2 + down.y;
float den = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
if (den == 0) {
return null;
} else {
float t = ((x1 -x3) * (y3 - y4) - (y1 - y3) * (x3 - x4)) / den;
float u = -((x1 - x2) * (y1 -y3) - (y1 - y2) * (x1 - x3)) / den;
if (t > 0 && t < 1 && u > 0) { // intersection found
PVector impact = new PVector();
impact.x = x1 + t * (x2 - x1);
impact.y = y1 + t * (y2 - y1);
return impact;
} else {
return null;
}
}
}
void vLine(PVector p1, PVector p2) {
line(p1.x, p1.y, p2.x, p2.y);
}
void vPoint(PVector p){
point(p.x, p.y);
}
class alLine {
PVector pos1 = new PVector();
PVector pos2 = new PVector();
alLine(float x1, float y1, float x2, float y2) {
pos1.x = x1;
pos1.y = y1;
pos2.x = x2;
pos2.y = y2;
}
void draw() {
line(pos1.x, pos1.y, pos2.x, pos2.y);
}
}
class Wall {
PVector pos1 = new PVector();
PVector pos2 = new PVector();
Wall(PVector _pos1, PVector _pos2) {
pos1 = _pos1;
pos2 = _pos2;
}
void draw() {
vLine(pos1, pos2 );
}
void set(PVector _pos1, PVector _pos2){
pos1 = _pos1;
pos2 = _pos2;
}
}