在 Box2D 项目中,我需要在用户双击的确切点处的两个 PolygonShaped 主体之间创建一个 RevoluteJoint。
我有接触点,以及两个形状中每一个的顶点列表(显然设置为不相互碰撞。)如果我理解正确,接触点是世界位置,顶点正在描述形状,它可以存在于任何世界。但是我如何从一个“翻译”到另一个?
例如,用户在 (3.63,5.07) 处双击。
形状1的顶点为:[(0.37485206,-0.17777264),(-0.2880008,-0.033603553),(-0.1609711,-0.2395713) 0.29765773)]
形状 2 的顶点:[(-0.015462875,0.24353802), (-0.13529873,0.31698608), (-0.36852637,0.4127499), (-0.4136281,0.17009032), (-0.2880008,-0.03)]
revoluteJoint:
RevoluteJointDef jd = new RevoluteJointDef();
jd.bodyA = touchedBodies.get(0);
jd.bodyB = touchedBodies.get(1);
jd.collideConnected = false;
jd.localAnchorA.set(?????);
jd.localAnchorB.set(?????);
world.createJoint(jd);
任何帮助将不胜感激。
编辑:
我取得了一些进展,但仍然没有。我现在正在做的是根据形状的顶点找到一个“平均”位置。我取第一个条目,并且知道顶点逆时针计算哪个是中间顶点,并假设它离第一个顶点最远。所以我对两者进行平均,并将关节设置在那里。
这是代码:
Shape shape1 = touchedFixtures.get(0).getShape();
Vec2 oneAverage = null;
if(shape1.getClass() == PolygonShape.class) {
PolygonShape s = (PolygonShape)shape1;
Vec2[] vs = s.m_vertices;
List<Vec2> vsNonZero = new LinkedList<Vec2>();
for(int i=0; i<vs.length; i++) {
if(vs[i].x != 0 || vs[i].y != 0) {
vsNonZero.add(vs[i]);
}
}
Vec2 oneOne = vsNonZero.get(0);
Vec2 oneMiddle = vsNonZero.get(Math.round(vsNonZero.size()/2));
oneAverage = new Vec2((oneOne.x + oneMiddle.x)/2, (oneOne.y + oneMiddle.y)/2);
}
以及关节的本地锚点:
jointDef.localAnchorA.set(oneAverage);
我对关节的第二个身体做同样的事情。这找到了相当不错的接近度,但它并不完美,尤其是在形状较大的情况下。
知道如何更接近实际接触点吗?我需要的是 shape.getTouchedPoint() 之类的东西,但 API 似乎没有提供它。