0

在 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 似乎没有提供它。

4

2 回答 2

1

这就是你的做法:

jd.localAnchorA = touchedBodies.get(0).getLocalPoint(locationWorld);
jd.localAnchorB = touchedBodies.get(1).getLocalPoint(locationWorld);

上面的touchedBodies 只是一个包含被触摸的两个物体的列表,所以上面可以替换为:

jd.localAnchorA = bodyA.getLocalPoint(locationWorld);
jd.localAnchorB = bodyB.getLocalPoint(locationWorld);

感谢 iforce2d 在这里提供这个答案(http://www.cocos2d-iphone.org/forum/topic/343137#post-507904),并附有一些解释和 C++ 代码。

于 2013-05-06T08:03:41.630 回答
0

局部锚点是指关节在局部身体坐标中“连接”到的位置。每个身体都有自己的坐标系,这是您在身体中定位形状时使用的系统。例如,当身体在世界中旋转时,形状在身体的局部坐标中处于相同的位置。

所以 localAnchorA 是主体 A 的局部坐标系中与主体 A 的连接,对于 B 和主体 B 也是如此。

基本上,使用创建时提供的形状坐标在方格纸上绘制形状,然后使用该坐标系为关节的锚点选择一个点。

编辑:对于动态的东西,使用getLocalPointbody 对象上的方法,或者更酷并使用getLocalPointToOut方法。就像是:

jd.bodyA.getLocalPointToOut(worldLocation, jd.localAnchorA);
于 2013-05-05T05:09:43.723 回答