We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I'm working on some code that should be able able to do a relaxation on a bunch of rectangles.
This is the idea / what I have:
A box has prismatic joints connected with a CircleShape:
Those joints have a motor force so the CircleShapes start moving away from the box:
After a while the start touching the side pushing the box away:
Then around this time the box is where I wan't it since the length on the left is equal to the length on the right and the same for top and down. (I say length in this case, but force might be a better description).
Now it goes wrong, the box keeps moving:
It goes to the corner:
And after that It goes back in the opposite direction (and so on back and forth):
What I wonder, why doesn't it wiggle in the center? (caused by equal forces on the opposite side).
(this part of the question is also here but none of the places about box2d seem to be very active). (http://stackoverflow.com/questions/31386566/box2d-relaxation-approach)
To continue:
I made a bare bones example that is slightly simpler then the sketch that produced the images above.
If only horizontal it works fine (with 1 box)
But with both horizontal and vertical it goes to this position:
Does someone know why it behaves like this and how I can prevent it?
If you change the 2 in: for (int i = 0; i < 2; i++) { // change 2 to 4 to have vertical joints
to 4 then you get vertical joints as well.
I really hope someone can help cause this is for a really great project.
package box2dTests;
import org.jbox2d.callbacks.DebugDraw;
import org.jbox2d.collision.shapes.ChainShape;
import org.jbox2d.collision.shapes.CircleShape;
import org.jbox2d.collision.shapes.PolygonShape;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyDef;
import org.jbox2d.dynamics.BodyType;
import org.jbox2d.dynamics.FixtureDef;
import org.jbox2d.dynamics.joints.DistanceJoint;
import org.jbox2d.dynamics.joints.DistanceJointDef;
import org.jbox2d.dynamics.joints.PrismaticJointDef;
import processing.core.PApplet;
import shiffman.box2d.Box2DProcessing;
import java.util.ArrayList;
/**
* Created by doekewartena on 7/14/15.
*/
public class RelaxBareBones extends PApplet {
public static void main(String[] args) {
PApplet.main("box2dTests.RelaxBareBones", args);
}
Box2DProcessing box2d;
Box2dP5DebugDraw debugDraw;
ArrayList<DistanceJoint> distanceJoints = new ArrayList<>();
public void settings() {
size(600, 600);
}
public void setup() {
box2d = new Box2DProcessing(this);
box2d.createWorld();
box2d.setGravity(0, 0);
debugDraw = new Box2dP5DebugDraw();
debugDraw.box2d = box2d;
debugDraw.g = g;
debugDraw.setFlags(
DebugDraw.e_shapeBit +
DebugDraw.e_jointBit
//DebugDraw.e_aabbBit
//DebugDraw.e_pairBit +
//DebugDraw.e_centerOfMassBit +
//DebugDraw.e_dynamicTreeBit +
//DebugDraw.e_wireframeDrawingBit
);
box2d.world.setDebugDraw(debugDraw);
createBoundary();
createTest(width / 3, height / 3);
// next is 2 of them
//createTest(width - width / 3, height / 3 + 20);
}
void createBoundary() {
BodyDef bd = new BodyDef();
Body body = box2d.world.createBody(bd);
ChainShape chainShape = new ChainShape();
Vec2[] vec2s = createVec2Arr(
10, 10,
width - 10, 10,
width - 10, height - 10,
10, height - 10);
chainShape.createLoop(vec2s, vec2s.length);
// 0 is default density
body.createFixture(chainShape, 0);
}
void createTest(float x, float y) {
// first the box
Body theBox;
{
BodyDef bd = new BodyDef();
bd.setType(BodyType.DYNAMIC);
bd.setFixedRotation(true);
bd.setPosition(box2d.coordPixelsToWorld(x, y));
Body body = box2d.createBody(bd);
PolygonShape ps = new PolygonShape();
float box2dW = box2d.scalarPixelsToWorld(100 / 2);
float box2dH = box2d.scalarPixelsToWorld(50 / 2);
ps.setAsBox(box2dW, box2dH);
FixtureDef fd = new FixtureDef();
fd.setDensity(1);
fd.setFriction(0);
fd.setRestitution(0);
fd.setShape(ps);
body.createFixture(fd);
theBox = body;
}
// now we want to have 2 distance joints, one
// on the left and one on the right
// the should push out to keep the box in the
// center of the screen
// to keep them horizontal we create a prismatic joint
for (int i = 0; i < 2; i++) { // change 2 to 4 to have vertical joints
int xDir, yDir;
if (i == 0) {
xDir = -1;
yDir = 0;
}
else if (i == 1) {
xDir = 1;
yDir = 0;
}
else if (i == 2) {
xDir = 0;
yDir = -1;
}
else { // (i == 3)
xDir = 0;
yDir = 1;
}
// fist we need a shape to connect the joint to
BodyDef bd = new BodyDef();
bd.setType(BodyType.DYNAMIC);
bd.setFixedRotation(true);
bd.setPosition(box2d.coordPixelsToWorld(x + (100 * xDir), y + (100 * yDir)));
Body body = box2d.createBody(bd);
CircleShape cs = new CircleShape();
cs.setRadius(box2d.scalarPixelsToWorld(10));
FixtureDef fd = new FixtureDef();
fd.setDensity(1);
fd.setFriction(0);
fd.setRestitution(0);
fd.setShape(cs);
body.createFixture(fd);
// now the prismatic joint for the direction
PrismaticJointDef pjd = new PrismaticJointDef();
pjd.bodyA = theBox;
pjd.bodyB = body;
pjd.collideConnected = true;
pjd.localAxisA.set(xDir, -yDir).normalize();
box2d.createJoint(pjd);
// a distance joint that we will use to tweak it's length
DistanceJointDef djd = new DistanceJointDef();
djd.bodyA = theBox;
djd.bodyB = body;
djd.collideConnected = true;
DistanceJoint dj = (DistanceJoint) box2d.createJoint(djd);
distanceJoints.add(dj);
}
}
public void draw() {
background(0);
colorMode(RGB, 1, 1, 1);
box2d.world.drawDebugData();
if (mousePressed) {
for (DistanceJoint dj : distanceJoints) {
float l = box2d.scalarWorldToPixels(dj.getLength());
println(l);
dj.setLength(box2d.scalarPixelsToWorld(l + 1));
// why does it not get active?
dj.getBodyA().setActive(true);
dj.getBodyB().setActive(true);
dj.getBodyA().setAwake(true);
dj.getBodyB().setAwake(true);
}
box2d.step();
}
}
public Vec2[] createVec2Arr(float... xy) {
Vec2[] result = new Vec2[xy.length/2];
int c = 0;
for (int i = 0; i < result.length; i++) {
result[i] = box2d.coordPixelsToWorld(xy[c], xy[c+1]);//new Vec2(xy[c], xy[c+1]);
c += 2;
}
return result;
}
}
The class to draw can be found in this topic: http://forum.processing.org/two/discussion/11669/box2d-debug-draw-class