编辑2: http://youtu.be/KiCzUZ69gpA - 正如您在此视频中看到的那样,当我为每个身体渲染一些文字时,摇动效果放大。观察当每个物体在其附近渲染一些文本时,地面体(蓝色)如何猛烈摇晃,以及当文本渲染被注释掉时它是如何形成的。这必须连接!
编辑:我对原始问题做了两个重要的补充:我添加了渲染功能,相机(翻译)方法和我认为错误实际上存在,而不是在JBox2D中。
我正在尝试模拟和渲染许多与RevoluteJoint
s连接的随机体(2-20)。一个主体可以连接到多个其他主体,并且没有单独的结构,即所有主体都是相互连接的。
然而,在观看实时渲染时,它非常不稳定且不稳定。我的意思是,身体的位置(或者角度)似乎随机波动,没有明显的原因,使模拟看起来不稳定。
这是我正在观察的视频:
注意中间正方形和旋转矩形。中间的正方形在看似随机的间隔内来回移动其位置,旋转的矩形非常紧张(看看它正在旋转的点)。
这会产生什么影响?它是(J)Box2D的一个已知问题,还是我的渲染系统的一个问题?我认为我在某种程度上错误配置了物理引擎,但渲染系统中的一些浮点数学也可能是罪魁祸首
以下是我创建身体和关节的方法:
private Body setPart(Part part) {
// body definition
BodyDef bd = new BodyDef();
bd.position.set(0f, -10f);
bd.angle = 0f;
bd.type = BodyType.DYNAMIC;
// define shape of the body.
PolygonShape Shape = new PolygonShape();
Shape.setAsBox(part.width / 2, part.height / 2);
// define fixture of the body.
FixtureDef fd = new FixtureDef();
Filter filter = new Filter();
filter.groupIndex = -1;
fd.filter = filter;
fd.shape = Shape;
fd.density = 0.5f;
fd.friction = 0.3f;
fd.restitution = 0.5f;
// create the body and add fixture to it
Body body = world.createBody(bd);
body.createFixture(fd);
body.setUserData(new PartUserData());
return body;
}
private void setJoint(PartJoint partJoint) {
Body bodyOne = partToBody.get(partJoint.partOne);
Body bodyTwo = partToBody.get(partJoint.partTwo);
RevoluteJointDef jointDef = new RevoluteJointDef();
jointDef.bodyA = bodyOne;
jointDef.bodyB = bodyTwo;
jointDef.localAnchorA = partJoint.partOne
.getAnchor(partJoint.percentOne);
jointDef.localAnchorB = partJoint.partTwo
.getAnchor(partJoint.percentTwo);
// rotation
jointDef.lowerAngle = GeomUtil.circle(partJoint.rotateFrom);
jointDef.upperAngle = GeomUtil.circle(partJoint.rotateTo);
jointDef.enableLimit = true;
jointDef.maxMotorTorque = 10.0f; // TODO limit maximum torque
jointDef.motorSpeed = GeomUtil.circle(partJoint.angularVelocity);
jointDef.enableMotor = true;
world.createJoint(jointDef);
}
时间步长为0.01f
。
以下是我绘制身体的方法:
private void drawBody(Body body) {
// setup the transforms
Vector position = camera.translate(body.getPosition());
currentGraphics.translate(position.x, position.y);
currentGraphics.rotate(body.getAngle());
// do the actual rendering
for (Fixture fixture = body.getFixtureList(); fixture != null; fixture = fixture
.getNext()) {
PolygonShape shape = (PolygonShape) fixture.getShape();
if (body.getUserData() instanceof PartUserData) {
fillShape(shape, partFillColor);
currentGraphics.setStroke(partOutlineStroke);
outlineShape(shape, partOutlineColor);
} else {
fillShape(shape, groundFillColor);
outlineShape(shape, groundOutlineColor);
}
}
// clean up
currentGraphics.rotate(-body.getAngle());
currentGraphics.translate(-position.x, -position.y);
currentGraphics.setColor(defaultColor);
currentGraphics.setStroke(defaultStroke);
}
我认为问题可能就是我处理所有身体的渲染方式。
这是每个机构的算法:
1.将Graphics2D
对象转换为其位置
2.按body.getAngle()
旋转
3.渲染身体
4.向后旋转图形
5.翻译图形
在所有这些转变中,有可能出现问题吗?
当我删除对相机方法的调用时,效果似乎已减少。这些是相关的相机方法:
public Vector translate(Vec2 worldPosition) {
Vector point = new Vector();
point.x = (int) (worldPosition.x * pixelsPerMeter) - position.x;
point.y = (int) (worldPosition.y * pixelsPerMeter) - position.y;
point.x = (int) (point.x * zoom);
point.y = (int) (point.y * zoom);
point.x += renderer.getWidth() / 2;
point.y += renderer.getHeight() / 2;
return point;
}
public Vector translateRelative(Vec2 worldPosition) {
Vector point = new Vector();
point.x = (int) (worldPosition.x * pixelsPerMeter);
point.y = (int) (worldPosition.y * pixelsPerMeter);
point.x = (int) (point.x * zoom);
point.y = (int) (point.y * zoom);
return point;
}
但是它们中的哪一部分会引起问题?
答案 0 :(得分:0)
tl;博士:我找到了一个解决方案,但还没有发现确切的问题。很确定这是我的翻译方法。
似乎我已经确定了问题的范围和解决方案,但我仍然不确定究竟是什么导致了这种行为。
在我在问题中发布的那些翻译公式中,所有JBox2D向量都乘以称为pixelsPerMeter
的标度。当我将此比例设置为较低值时,会发生抖动效果(同样重要的是要注意还有另一个因素,称为zoom
,对于较低的pixelsPerMeter
通常更大。< / p>
所以,可能是当乘以相对较低的pixelsPerMeter
时,我必须乘以更高的zoom
因子,因为我在两者中都转换为int
s步骤,浮点数学中可能存在一些错误。请参阅我在问题中发布的翻译方法。
以下是一段视频演示:(待上传)
请注意,当我将pixelsPerMeter
设置为250
时,抖动似乎已经消失,而当我将其设置为25
时,它非常明显。
答案 1 :(得分:0)
您的解决方案是正确的。您不应该使用Box2D物理引擎的像素单位:)
http://box2d.org/2011/12/pixels/
和
https://code.google.com/p/box2d/wiki/FAQ#How_do_I_convert_pixels_to_meters?