2009-05-21 14 views
4

Objective-Cの質問「Ball to Ball Collision - Detection and Handling」のコードを実装しました。しかしながら、ボールがある角度で衝突するときはいつも、それらの速度は劇的に増加する。すべてのベクトル演算は、cocos2d-iphoneを使用して、ヘッダCGPointExtension.hとともに行われます。この望ましくない加速の原因は何ですか?Ball to Ball Collision - 衝突時に大きな速度を得ます。

入力:
質量== 12.56637
velocity.x == 1.73199439
velocity.yの== -10.5695238

ボール

は、次の高速化の一例です.mass == 12.56637
ball.velocity.x == 6.04341078
ball.velocity.y == 14.2686739

出力:
質量== 12.56637
velocity.xの== 110.004326
velocity.y == -10.5695238

ball.mass == 12.56637
ball.velocity.x == - 元のコードとオリジナルポスターのコメント、コードを見直した102.22892
ball.velocity.y == -72.4030228

#import "CGPointExtension.h" 
#define RESTITUTION_CONSTANT (0.75) //elasticity of the system 

- (void) resolveCollision:(Ball*) ball 
{ 
    // get the mtd (minimum translation distance) 
    CGPoint delta = ccpSub(position, ball.position); 
    float d = ccpLength(delta); 
    // minimum translation distance to push balls apart after intersecting 
    CGPoint mtd = ccpMult(delta, (((radius + ball.radius)-d)/d)); 


    // resolve intersection -- 
    // inverse mass quantities 
    float im1 = 1/[self mass]; 
    float im2 = 1/[ball mass]; 

    // push-pull them apart based off their mass 
    position = ccpAdd(position, ccpMult(mtd, (im1/(im1 + im2)))); 
    ball.position = ccpSub(ball.position, ccpMult(mtd, (im2/(im1 + im2)))); 

    // impact speed 
    CGPoint v = ccpSub(velocity, ball.velocity); 
    float vn = ccpDot(v,ccpNormalize(mtd)); 

    // sphere intersecting but moving away from each other already 
    if (vn > 0.0f) return; 

    // collision impulse 
    float i = (-(1.0f + RESTITUTION_CONSTANT) * vn)/([self mass] + [ball mass]); 
    CGPoint impulse = ccpMult(mtd, i); 


    // change in momentum 
    velocity = ccpAdd(velocity, ccpMult(impulse, im1)); 
    ball.velocity = ccpSub(ball.velocity, ccpMult(impulse, im2)); 

} 
+0

あなたの物理ここで問題です:あなたは、反発係数は、(1以上)1.75であることから、運動エネルギーを節約しない衝突を設定しています。 これはプログラミングに関するエラーではありません。 – jpinto3912

+0

正常に機能するコードの最終版を投稿できますか? –

+0

@ jpinto3912 - 勢いの保全を意味しないのですか? –

答えて

3

私はあなたが参照した元のボールバウンスコードを書いた人です。 downloadとそのコードを試してみると、正常に動作することがわかります。

次のコードは、(あなたが最初にそれを持っていた方法で)正しい:

// collision impulse 
float i = (-(1.0f + RESTITUTION_CONSTANT) * vn)/(im1 + im2); 
CGPoint impulse = ccpMult(mtd, i); 

これは非常に一般的な物理学のコードであり、あなたはそれがほぼ正確に、以下の例では、このように実装確認できます。

これは間違いなく、他の人が示唆しているように〜〜は1.0以上のCoRを作成していません。これは、質量と反発係数に基づいて相対インパルスベクトルを計算しています。

摩擦を無視して、簡単な1Dの例は以下の通りである:

J = -Vr(1+e)/{1/m1 + 1/m2} 

EはあなたのCoRある場合、Vrはあなたの正規化速度であり、Jは、インパルス速度のスカラー値です。

これ以上進歩する予定がある場合は、すでに多くの物理ライブラリの1つを使用することをお勧めします。私が上のコードを使用したとき、それはいくつかのボールのためには問題ありませんでしたが、私はそれを数百に増やしてチョークを開始しました。私はBox2D物理エンジンを使用しました。そのソルバはより多くのボールを扱うことができ、より正確です。

とにかく、私はあなたのコードを見て、一見一見それはかなり忠実な翻訳です。おそらく、間違った値が渡されたり、ベクトルの数学の問題が発生する、小さくて微妙なエラーです。

私はiPhoneの開発に関しては何も知らないが、その方法の最上部にブレークポイントを設定し、その結果として得られる各ステップを監視して、どこにブローアップがあるかを見つけることをお勧めします。 MTDが正確に計算されていること、衝突の速度などが大きく増加する場所がわかるまで確認してください。

その方法の各ステップの値を報告して、われわれが持っているものを見てみましょう。この行で

5

元のコードライブラリが正しく実装されていれば、不正なベクターライブラリや何らかの初期化されていない変数があると思われます。

なぜ反発係数に1.0を追加していますか?

から:CORは、一般的に範囲[0,1]内の数であるhttp://en.wikipedia.org/wiki/Coefficient_of_restitution

。定性的には、1は完全に弾性の衝突を表し、0は完全に非弾性の衝突を表す。理論的には1以上のCORがあり、地雷が一緒に投げ込まれて爆発するなど、運動エネルギーを生成する衝突を表します。あなたはおそらく、質量の合計で割るべきである - あなたが接触のベクトルに沿っ衝動を取得するために、質量の逆数の和で除算している

/ (im1 + im2) 

もう一つの問題はこれです自分自身。これはあなたのインパルスを拡大しています(「彼女が言ったことです」)。

+0

nice catch 1.0 - > 1.0f – curtisk

+0

問題は1.0fと同じです –

+0

とにかく1.0と1.0fの違いは何ですか? –

0

CGPoint impulse = ccpMult(mtd, i); 

MTDは、正規化されている必要があります。元のコードmtdが前の行で正規化されていて、コードでは正規化されていないため、エラーが発生しました。あなたはこのような何かをすることによってそれを修正することができます:

CGPoint impulse = ccpMult(ccpNormalize(mtd), i); 
関連する問題