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

VisualC++ と OpenGL を利用した仮想物理実験室
【2-6-2】重力+空気抵抗力による自由落下運動のシミュレーション

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

前節重力+空気抵抗力による運動の運動方程式とアルゴリズムでは、 重力と空気抵抗力がある場合の運動方程式の導出と、コンピュータでシミュレーションを行うためのアルゴリズムの導出を行ないました。 t=t_n[s]のときの加速度 a_n[m/s^2]は、

(2.6.1)
差分方程式

と、そのときの速度 v_n[m/s]によって決まる値となります。 あとは、加速度 a[m/s^2]から速度 v[m/s]、位置 x[m]を順番に計算することで、重力+空気抵抗力のある場合のシミュレーションを行うことができます。 今回は、重力+空気抵抗力における自由落下運動のシミュレーションを行います。位置、速度の初期値は【2-1】重力による運動:自由落下運動と同様、初期位置(x_0, y_0, z_0), 初速度(v_{x0}, v_{y0}, v_{z0}) を指定します。

重力+空気抵抗力による運動のための計算アルゴリズム

位置・速度・加速度の初期値(自由落下)

g = 9.80665 //重力加速度
k = 10.0 //空気抵抗係数
m = 1.0  //ボールの質量
// 位置・速度・加速度の初期値 
x = 0.0;
y = 0.0;
z = 80.0;
vx = 0.0;
vy = 0.0;
vz = 0.0;
ax = 0.0;
ay = 0.0;
az = -g;

速度・位置を逐次計算するアルゴリズム

//位置の計算
x  = x  + vx * dt; 
y  = y  + vy * dt; 
z  = z  + vz * dt; 
//速度の計算
vx = vx + ax * dt; 
vy = vy + ay * dt; 
vz = vz + az * dt; 
//加速度の計算
ax = -k/m * vx;    //<-----空気抵抗力からの寄与
ay = -k/m * vy;    //<-----空気抵抗力からの寄与
az = -g -k/m * vy; //<-----重力+空気抵抗力からの寄与

【6日目】重力による運動:自由落下の場合と比較して、質量m[kg]と空気抵抗係数 k[kg/s]が加えられています。

重力+空気抵抗力による自由落下運動のシミュレーション

質量を 0.1[kg]から 1.0[kg]まで変化させた10個のボールを、 z = 80[m]の位置からの自由落下運動させたときのシミュレーションを行ないます。 軽いほど空気抵抗力の影響が大きく、結果として等速直線運動のように見えます。

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

【6日目】重力による運動:自由落下と同様に「【0日目】仮想物理実験室の構築 (ver1.0)」をベースにプログラミングします。上記で解説した逐次計算を行うアルゴリズムをプログラミングします。

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

//--------------------------------------------------------
// 仮想物理実験室変数の定義
//--------------------------------------------------------
double t = 0.0;     //時刻
double dt= 0.01;    //時間刻み
int tn = 0;         //ステップ数
double g = 9.80665; //重力加速度 g
double k  = 10.0;     //空気抵抗の比例定数

// ボールの定義
struct BALL {
  double m;          //質量
  double x, y, z;
  double vx, vy, vz;
  double ax, ay, az;
};
const int N = 10;
BALL ball[N];
void SetUp(void){
  for(int i=0; i

ボールの位置「x,y,z」、速度「vx,vy,vz」、加速度「ax,ay,az」に加えて、 質量 m[kg]も構造体「BALL」のメンバとします。「BALL」型の変数「ball1」を宣言と同時に初期値を設定しています。

速度・位置を逐次計算するアルゴリズム

//--------------------------------------------------------
// 計算と物体の描画
//--------------------------------------------------------
void Calculate(){
  t = dt * double(tn);
  //ofs1 << dt*tn << " " << ball1.x << " " << ball1.vx << " " << ball1.ax <<endl;
  for(int i=0; i<N; i++){
    //位置の算出
    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;
    //速度の算出
    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].ax =    - k/ball[i].m * ball[i].vx * dt;
    ball[i].ay =    - k/ball[i].m * ball[i].vy * dt;
    ball[i].az = -g - k/ball[i].m * ball[i].vz * dt;
  }
 tn++;
}
void DrawStructure(){
  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(ball1.x, ball1.y, ball1.z); //平行移動値の設定
    glutSolidSphere(4.0, 20, 20);            //引数:(半径, Z軸まわりの分割数, Z軸に沿った分割数)
  glPopMatrix();
}

位置「ball1.x」「ball1.y」「ball1.z」
速度「ball1.vx」「ball1.vy」「ball1.vz」
加速度「ball1.ax」「ball1.ay」「ball1.az」
を逐次計算します。

20100110-05.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 トップ