1

Nick Velliosのチュートリアルを使用して、Box2Dオブジェクトで放射状の重力を作成しました。ここSOでMakeaVortexを知っていますが、プロジェクトに実装する方法がわかりませんでした。

一定の角速度で回転するBox2DcircleShapeセンサーである渦オブジェクトを作成しました。他のBox2Dオブジェクトがこの渦オブジェクトに接触するとき、渦と同じ角速度で回転させ、徐々に渦の中心に近づけてほしいと思います。現時点では、オブジェクトは渦の中心に引き付けられていますが、私が望むようにゆっくりと回転するのではなく、渦の中心に向かってまっすぐに向かいます。また、渦の回転と同様に、渦とは反対の方向に移動します。

渦とbox2Dボディが与えられた場合、box2dボディが「吸い込まれた」ときに渦とともに回転するように設定するにはどうすればよいですか。

次のように作成するときに、渦の回転を設定します。

b2BodyDef bodyDef;
bodyDef.type = b2_dynamicBody;
bodyDef.angle = 2.0f;
bodyDef.angularVelocity = 2.0f;

Nick Velliosのサンプルコードに従って、これがラジアル重力を適用する方法です。

-(void)applyVortexForcesOnSprite:(CCSpriteSubclass*)sprite spriteBody:(b2Body*)spriteBody withVortex:(Vortex*)vortex VortexBody:(b2Body*)vortexBody vortexCircleShape:(b2CircleShape*)vortexCircleShape{

    //From RadialGravity.xcodeproj
    b2Body* ground = vortexBody;
    b2CircleShape* circle = vortexCircleShape;
    // Get position of our "Planet" - Nick
    b2Vec2 center = ground->GetWorldPoint(circle->m_p);
    // Get position of our current body in the iteration - Nick
    b2Vec2 position = spriteBody->GetPosition();
    // Get the distance between the two objects. - Nick
    b2Vec2 d = center - position;
    // The further away the objects are, the weaker the gravitational force is - Nick
    float force = 1 / d.LengthSquared(); // 150 can be changed to adjust the amount of force - Nick
    d.Normalize();
    b2Vec2 F = force * d;
    // Finally apply a force on the body in the direction of the "Planet" - Nick
    spriteBody->ApplyForce(F, position);
    //end radialGravity.xcodeproj


}

更新iForce2dは、私に道を進むのに十分な情報を与えてくれたと思います。今は微調整しているだけです。上記のコードに加えて、これは私が現在行っていることです。何が起こっているのかというと、体は渦の重力をうまく抜けるのに十分な速度を獲得しています。どこかで、速度がこの数値を下回っていることを確認する必要があります。現時点では、オブジェクトの質量を考慮していないのではないかと少し心配しています。

b2Vec2 vortexVelocity = vortexBody->GetLinearVelocityFromWorldPoint(spriteBody->GetPosition() );

b2Vec2 vortexVelNormal = vortexVelocity;
vortexVelNormal.Normalize();
b2Vec2 bodyVelocity = b2Dot( vortexVelNormal, spriteBody->GetLinearVelocity() ) * vortexVelNormal;

//Using a force
b2Vec2 vel = bodyVelocity;
float forceCircleX =    .6 * bodyVelocity.x;
float forceCircleY =    .6 * bodyVelocity.y;

spriteBody->ApplyForce( b2Vec2(forceCircleX,forceCircleY), spriteBody->GetWorldCenter() );
4

2 に答える 2

2

体の現在のポイントでの渦の方向に応じて、別の力を加える必要があるようです。b2Body :: GetLinearVelocityFromWorldPointを使用して、世界の任意のポイントでの渦の速度を見つけることができます。Box2Dソースから:

/// Get the world linear velocity of a world point attached to this body.
/// @param a point in world coordinates.
/// @return the world velocity of a point.
b2Vec2 GetLinearVelocityFromWorldPoint(const b2Vec2& worldPoint) const;

つまり、次のようになります。

b2Vec2 vortexVelocity = vortexBody->GetLinearVelocityFromWorldPoint( suckedInBody->GetPosition() );

目的の速度がわかれば、現在の速度から目的の速度に到達するために必要な力を計算できます。これは役立つかもしれません:http ://www.iforce2d.net/b2dtut/constant-speed

そのリンクのトピックでは、1次元の状況についてのみ説明しています。あなたの場合、吸い込まれた物体の現在の速度をvortexVelocityベクトルに投影すると、本質的に1次元にもなります。

b2Vec2 vortexVelNormal = vortexVelocity;
vortexVelNormal.Normalize();
b2Vec2 bodyVelocity = b2Dot( vortexVelNormal, suckedInBody->GetLinearVelocity() ) * vortexVelNormal;

これで、bodyVelocityとvortexVelocityが同じ方向になり、適用する力を計算できます。ただし、渦の速度に正確に一致するのに十分な力を加えるだけでは、吸い込まれた体はおそらく渦の周りの軌道に入り、実際には吸い込まれません。力をそれよりかなり小さくしたいと思います。重力の強さにも応じて縮小します。そうしないと、吸い込まれた物体が渦の外縁に接触するとすぐに横に飛び散ってしまいます。必要な効果を得るには、多くの調整が必要になる場合があります。

編集:

適用する力は、現在の速度(bodyVelocity)と目的の速度(vortexVelocity)のに基づいている必要があります。体がすでに渦で動いている場合は、力を加える必要はありません。上記のリンクにある「力の使用」というタイトルのサブセクションの最後のコードブロックを見てください。最後の3行は、「vel」と「desiredVel」をbodyVelocityおよびvortexVelocityベクトルのサイズに置き換えた場合に必要なことをほぼ実行します。

float desiredVel = vortexVelocity.Length();
float currentVel = bodyVelocity.Length();
float velChange = desiredVel - currentVel;
float force = body->GetMass() * velChange / (1/60.0); //for a 1/60 sec timestep
body->ApplyForce( b2Vec2(force,0), body->GetWorldCenter() );

しかし、これはおそらく体を軌道に乗せることになるので、途中のどこかで、適用する力のサイズを小さくしたいと思うことを覚えておいてください。'desiredVel'を一定の割合で減らし、'force'を一定の割合で減らすなど。渦の外縁でゼロになるように力を縮小することもできれば、おそらく見栄えが良くなります。

于 2012-05-21T01:58:30.997 に答える
0

小惑星が中心点の周りを渦巻くプロジェクトがありました(それらの間でジャンプするものがあります...これは別の点です)。

  • それらはb2DistanceJointsを介して「中央」本体に接続されています。
  • ジョイントの長さを制御して、ゆっくりと内側(または外側)にらせん状にすることができます。これにより、力の制御のバランスをとる代わりに、粒子の制御を見つけることができます。これは難しい場合があります。
  • また、接線方向の力を適用して、それらを中心に円を描きます。
  • 異なる(またはランダムに変化する)接線力を適用することにより、互いに衝突するなどのことができます。

この質問に対するより完全な回答をここに投稿しました。

于 2014-01-05T01:03:58.370 に答える