2017-01-18 25 views
3

オブジェクトに重力を実装する際に問題があります。オブジェクトに重力を適用する

私はOpenGLを使用して描画している円のオブジェクトの束を持っています。私はdelta-xdelta-yを使って円(ボール)を動かしています。私はyに重力定数を加えて各フレームを調整しようとしていますので、下に引っ張られるようにシミュレートしていますが、正確にどのように行うのかは分かりません。

ここに関連するコードです:

class Ball 
{ 
    public: 
     double x; 
     double y; 
     double radius; 
     double deltaX; 
     double deltaY; 
}; 


std::vector<Ball> gAllBalls; // a vector of balls with random positions and delta-values 
double gGravity = ?; // gravitational constant - I know it's 92 m/s^s, but I don't know how to apply that to deltaX and deltaY 


void display(void) 
{ 
    glClear(GL_COLOR_BUFFER_BIT); 

    for (auto &thisBall : gAllBalls) 
    { 
     // draw 
     glColor3d(thisBall.red, thisBall.green, thisBall.blue); 
     DrawCircle(thisBall.x, thisBall.y, thisBall.radius); 

     // gravity - not working 
     if (thisBall.y + thisBall.radius < gScreenHeight - gGravity) 
     { 
      thisBall.y += gGravity; 
     } 

     // wall bouncing 
     if (thisBall.y + thisBall.radius + thisBall.deltaY >= gScreenHeight) // up 
     { 
      thisBall.deltaY = -thisBall.deltaY; 
     } 

     if (thisBall.y + thisBall.deltaY - thisBall.radius < 0) // down 
     { 
      thisBall.deltaY = -thisBall.deltaY; 
     } 

     if (thisBall.x + thisBall.deltaX - thisBall.radius < 0) // left 
     { 
      thisBall.deltaX = -thisBall.deltaX; 
     } 

     if (thisBall.x + thisBall.radius + thisBall.deltaX >= gScreenWidth) // right 
     { 
      thisBall.deltaX = -thisBall.deltaX; 
     } 

     // move 
     thisBall.x += thisBall.deltaX; 
     thisBall.y += thisBall.deltaY; 
    } 
    glutSwapBuffers(); 
    glutPostRedisplay(); 
} 

私がいる大きな問題は、私が代わりに別の速度を持つのdeltaXdeltaYを使用していますので、私は、重力を計算する方法がわからないということですがと92m/s^2を計算するための距離変数。しかし、私が重力をどのように設定しても、ボールは重力にかかわらず、何か間違っている必要がありますが、何が分からないのか分かりません。

+0

'thisBall.y + = gGravity;'一定の速度で、一定の加速になりません。 YではなくdeltaYを調整すると、おそらくあなたが意図するものに近づくでしょう。最良の方法は、ピクセルや任意の時間ステップではなく、メートルや秒などの工学単位で作業し、必要に応じてそれらの間で変換することです。最後に、 'G'の値はオフになっています。実際には9.8 m/secです。^ 2 –

+0

ああ、もちろん理にかなっています。私はYの代わりにdeltaYに変更しましたが、最初はうまくいくように見えますが、ボールは減速するのではなく、速くて速く加速し始めます。私は重力定数として1を使用しています。 私はより良いユニットを使用したいと思っていますが、それらの実装方法はわかりません。提案やリソースはありますか? – Grav

+0

"** 92 ** m/s^2"、あなたは何かの超木星か小さな星をシミュレートしていますか? – genpfault

答えて

4

ここで問題となっているのは、プログラミング技術ではなく、物理現象だと思います。 あなたの場合、ボールクラスの 'デルタ'メンバーを 'スピード'に変更します。これは、サイクル(時間)ごとにオブジェクトの位置を変更する距離の単位ですからですが、これは単なる提案ですそれは...第二位で

class Ball 
{ 
    public: 
     double x; 
     double y; 
     double radius; 
     double speedX; 
     double speedY; 
}; 

を視覚化しやすく、私はあなたのコードでは、あなたはかなりの速度よりも、「Y」メンバーを変更している、と重力は問題故に、速度を変更するので。 これを試してみてください。デバッグの目的で、厳密なオブジェクト(半径なし、単純(x、y)座標)を試してみましょう。

ので、結論に、私は単純に次のようにあなたの重力のコードを変更します

// gravity - 'fixed' 
    if (thisBall.y + thisBall.radius < gScreenHeight - gGravity) 
    { 
     thisBall.speedY -= gGravity; //notice the '-' 
    } 

とりうるような単純なものを維持するように、重力の値は、絶対的な正でなければなりません。これを試してみると、理想的なシンプルな物理シミュレータが必要です。一定のspeedXのボール(大きさではなく方向のみが変わります)。 これを試してみて、それがどうなっているのか教えてください。

+0

'speedY - = gGravity;'という物理学者として私は奇妙に見えます。 'gGravity'自体を負の数にして積極的にそれを合計します(' + = ')。 – datenwolf

+0

ありがとう!それにより、私は望みの結果にもっと近づきました。しかし、私はまだ小さな問題を抱えています。ボールがバウンスすると、スピードを落とす代わりにバウンスが高くなります。私が変えた唯一の事は、位置ではなく速度に影響する重力でした。なぜこれが起こっているのでしょうか? – Grav

関連する問題