0

Box2D プロジェクトでは、ユーザーがダブルタップした正確なポイントで、2 つの PolygonShaped ボディ間に RevoluteJoint を作成する必要があります。

接触点と、2 つの形状のそれぞれの頂点のリストがあります (明らかに、互いに衝突しないように設定されています)。私の理解が正しければ、接触点は世界の位置に関するものであり、頂点は説明しています。どんな世界にも存在できる形。しかし、あるものから別のものに「翻訳」するにはどうすればよいでしょうか。

たとえば、ユーザーが (3.63,5.07) をダブルタップしたとします。

形状1の頂点は次のとおりです。 0.29765773)]

形状 2 の頂点: [(-0.015462875,0.24353802), (-0.13529873,0.31698608), (-0.36852637,0.4127499), (-0.4136281,0.17009032), (-0.2880008,-03.0533)]

回転ジョイント:

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);

どんな助けでも大歓迎です。

編集:

私は少し進歩しましたが、まだそこにはいません。私が今行っているのは、形状の頂点に基づいて「平均的な」位置を見つけることです。私は最初のエントリを取り、頂点が反時計回りに移動することを知っているので、どれが中央の頂点であるかを計算し、それが最初の頂点から最も遠いと仮定します。だから私は2つの平均をやっていて、そこにジョイントを設定しています.

コードは次のとおりです。

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);

ジョイントの 2 番目のボディについても同じことを行っています。これはかなり適切な近接性を見つけますが、特に形状が大きい場合は完全ではありません。

実際のタッチポイントに近づく方法はありますか? 私が必要とするのは shape.getTouchedPoint() のようなものですが、API はそれを提供していないようです。

4

2 に答える 2

1

これはあなたがそれを行う方法です:

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

上記の touchedBodies は、タッチされた 2 つのボディの単なるリストであるため、上記は次のように置き換えることができます。

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

ここ ( http://www.cocos2d-iphone.org/forum/topic/343137#post-507904 ) にいくつかの説明と C++ コードを添えてこの回答を提供してくれた iforce2d に感謝します。

于 2013-05-06T08:03:41.630 に答える
0

ローカル アンカーは、ローカル ボディ座標で、ジョイントが「接続」している場所を参照します。各ボディには独自の座標系があり、ボディに形状を配置するときに使用する座標系です。たとえば、ボディがワールド内で回転する場合、シェイプはボディのローカル座標で同じ位置にあります。

したがって、localAnchorA はボディ A のローカル座標系におけるボディ A への接続であり、B とボディ B についても同じです。

基本的には、作成時に指定した形状座標を使用して方眼紙に形状を描き、その座標系を使用してジョイントのアンカーのポイントを選択します。

編集:動的なものgetLocalPointについては、 body オブジェクトでメソッドを使用するか、よりクールでgetLocalPointToOutメソッドを使用してください。何かのようなもの:

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