HOME > natural science Laboratory > コンピュータ・シミュレーション講座 > 仮想物理実験室

VisualC++ と OpenGL を利用した仮想物理実験室
【2-2-1】重力による鉛直投射運動のシミュレーション

文責:遠藤 理平 (2010年8月29日) カテゴリ:仮想物理実験室(277)

【2-1-2】重力による運動のアルゴリズムの導出では、ニュートンの運動方程式から、重力による物体の運動をシミュレーションするためのアルゴリズムを導出し、自由落下の場合のシミュレーションを行ないましました。 今回は、鉛直投射運動と呼ばれる運動のシミュレーションを行ないます。

(2.2-1)
時刻 t=tn[s] におけるニュートンの運動方程式

重力による運動は、上記のアルゴリズムと t=t_0[s]のときの状態、初期値を適切に設定することですべての運動を表現することができます。自由落下のシミュレーションでは、初期値として、z_0 = 120[m] としました。 今回も、異なった初期値の運動をシミュレーションします。

鉛直投射運動

鉛直投射運動とは、真上にボールを投げて、重力により落下してくる運動です。 投げ上げるためには、z軸方向に初期速度を与えることで表現することができます。

鉛直投射運動の図

位置・速度・加速度の初期値(鉛直投射運動)

g = 9.80665 //重力加速度
// 位置・速度・加速度の初期値 
x = 0.0;
y = 0.0;
z = 0.0;
vx = 0.0;
vy = 0.0;
vz = 50.0; //<---------------z軸方向の初期速度を設定
ax = 0.0;
ay = 0.0;
az = -g;  //重力

鉛直投射運動のシミュレーション

これまでは、ボールを1個をシミュレーションしました。 今回は、初期値 v_{z0} を変化させた場合のシミュレーションを同時に行ないます。 初期速度が一番大きな v_{z0}=50[m/s]の場合、約5秒後に最高点に至り、約10後に元の場所にたどり着くことを確認することができます。

VisualC++ + OpenGL プログラミング

【6日目】重力による運動:自由落下と同様に「【0日目】仮想物理実験室の構築 (ver1.0)」をベースにプログラミングします。複数のボールを同時に扱うために、C言語の配列を使用します。

仮想物理実験室変数の定義

//--------------------------------------------------------
// 仮想物理実験室変数の定義
//--------------------------------------------------------
double t = 0.0;  //時刻
double dt= 0.03; //時間刻み
int tn = 0;      //ステップ数
double g = 9.80665; //重力加速度 g

// ボールの定義
struct BALL {
  double x, y, z;
  double vx, vy, vz;
  double ax, ay, az;
};
BALL ball[5]; //<------------------------ BALL型の配列 ball[5] を宣言
void SetUp(void){ //<---------------------初期値代入用の関数
  for(int i=0; i<5; i++ ){
    ball[i].x = 0.0;
    ball[i].y = 0.0;
    ball[i].z = 0.0;
    ball[i].vx = 0.0;
    ball[i].vy = 0.0;
    ball[i].vz = 10.0*(i+1);//<-----------vz の値を変化させる
    ball[i].ax = 0.0;
    ball[i].ay = 0.0;
    ball[i].az = -g;
  }
}

構造体 BALL型の配列 ball[5] を宣言します。 これまでは、構造体の変数宣言と同時に初期値の代入を行なっていましたが、 今回は配列なので、初期値を代入するための関数を用意し、main 関数の最初にこの関数を呼び出すことで、初期値を代入します。C言語では、変数に値を代入するのは main 関数の中でしか行なえないためです。

main()の変更

//--------------------------------------------------------
// メイン関数
//--------------------------------------------------------
int main(int argc, char *argv[]){
 SetUp();//<---------------------初期値代入用の関数の呼び出し
・・・
}

計算と物体の描画

//--------------------------------------------------------
// 計算と物体の描画
//--------------------------------------------------------
void Calculate(){
  t = dt * double(tn);
  for(int i=0; i<5; i++){
    //速度の算出
    ball[i].vx = ball[i].vx + ball[i].ax * dt;
    ball[i].vy = ball[i].vy + ball[i].ay * dt;
    ball[i].vz = ball[i].vz + ball[i].az * dt;
    //位置の算出
    ball[i].x = ball[i].x + ball[i].vx * dt;
    ball[i].y = ball[i].y + ball[i].vy * dt;
    ball[i].z = ball[i].z + ball[i].vz * dt;
  }
 tn++;
}
void DrawStructure(){
  for(int i=0; i<5; i++){
    glPushMatrix();
      glMaterialfv(GL_FRONT, GL_AMBIENT, ms_ruby.ambient);
      glMaterialfv(GL_FRONT, GL_DIFFUSE, ms_ruby.diffuse);
      glMaterialfv(GL_FRONT, GL_SPECULAR, ms_ruby.specular);
      glMaterialfv(GL_FRONT, GL_SHININESS, &ms_ruby.shininess);
      glTranslated(ball[i].x, ball[i].y, ball[i].z); //平行移動値の設定
      glutSolidSphere(4.0, 20, 20);            //引数:(半径, Z軸まわりの分割数, Z軸に沿った分割数)
    glPopMatrix();
  }
}

i 番目のボールの 位置「ball[i].x」「ball[i].y」「ball[i].z」
速度「ball[i].vx」「ball[i].vy」「ball[i].vz」
加速度「ball1.ax」「ball[i].ay」「ball[i].az」
を逐次計算します。 等加速度直線運動 なので、加速度の変化はありません。

20100112-02.gif

VisualC++ と OpenGL を利用した仮想物理実験室

第0章 仮想物理実験室の構築

第1章 様々な運動

第2章 ニュートンの運動方程式

第3章 剛体の運動(エネルギー保存則と運動量保存則)

付録

  • 【A-1】参考文献
    ・(A-1-1)OpenGL について
    ・(A-1-2)VisualC++ について
    ・(A-1-3)物理シミュレーション
    ・(A-1-4)数値計算

未分類

力学

量子力学

波動論



▲このページのトップNPO法人 natural science トップ

関連記事

仮想物理実験室







▲このページのトップNPO法人 natural science トップ