物理エンジンで学ぶC言語[Step1:物体の描画]

step1.cppの実行画面

step1.cppの実行画面

後学期は機械工学科の学生にC言語を教えています.前学期でロボティクス学科の学生に,物理エンジンを使い楽しみながらC言語をマスターすることを目指して講義を行い,物理エンジンにはOpen Dynamics Engine (ODE)を使用しました.授業アンケートを見ると説明不足という声が多かったので,このブログでももう少し詳しく説明していきたいと思います.内容的には今年6月に連載した「ODEで学ぶC言語2」と同じです.

なお,講義では別の教科書で一通りC言語を教えたので,プログラミング能力を高めるための演習ベースになり,C言語に対する細かい説明はあまりしません.プログラミングの楽しい演習だと思ってください.

今回は何もなかった仮想空間に物体を表示させてみましょう.ODEではいろいろな形状がサポートされています.ここではその中でも使い方が最も簡単な球を表示させます.

/* step1 球の表示 */
#include "dm1.h"

double R[12];                  // 回転行列(姿勢)の値を入れる配列
double p[3] = {0.0, 0.0, 1.0}; // 位置(x,y,z)[m]
double r = 0.2;                // 半径 [m]

void simLoop(int pause)        /***  シミュレーションループ ***/
{
  dsDrawSphere(p,R,r);         // 球の描画
}

int main()         /*** main関数 ***/
{
  dmLoop(800, 600, simLoop); // シミュレーションループ(ウインドウの横,縦)
  return 0;
}

まず,2行目のdm1.hはODEをより簡単に使うためのヘッダーファイルです.Step1ではまだ説明しません.

一般的に物体を3次元空間上に表示させるためには,物体の位置と姿勢を決める必要があります.ODEでは姿勢を回転行列とよばれる行列で表しています.その行列の要素を格納するのが配列R[12]です.回転行列は3×3の行列なので,1次元配列では要素数が9個で十分ですが,ODEでは高速化のために要素数12個の配列を用意します.配列の4, 8, 12番目の様子は0になっています.なお,R[12]には謎のヘッダファイルdm1.hの中で単位行列が設定されています.

また,位置は要素数3個のdouble型の配列p[3]に格納しています.位置のx座標(手前方向)を表す変数pの1番目の要素p[0]には0.0[m],y座標(右方向), z座標(高さ方向)を表すp[1], p[2]には0.0[m], 1.0[m]が設定されています.座標系は右手系です。上の図では中心から赤いピラミッドの方向がx軸の正,青いピラミッドの方向がy軸の正,上空方向がz軸の正です.ODEでは単位系はSI単位系で,長さはm,質量はkg,力はNとなります.

ソースコードのなかほどにあるsimLoop関数にシミュレーションでやりたいことを書きます.ここでは,球を表示したいのでdsDrawSphere関数を使って,位置p,姿勢R, 半径rの球を描画しています.なお、このソースコードだけではわかりませんが、simLoop関数はdmLoop関数の中で毎回呼び出されています。

今回はこれで終わりです.簡単でしたね.なお,この説明でわからない場合は,わからない部分をコメントに書いて頂けると補足説明します.

  • ホームワーク1
    1. step1-101217.zipをダウンロードし,実行してください.
    2. 手順
      • ode-0.11.1がインストールされていなかったらこの説明に従いインストールする
      • ダウンロードしたファイルをc:\ode-0.11.1\myprogの中に保存する.
      • そこで解凍する.c:\ode-0.11.1\myprog\step1というフォルダが作られます.
      • c:\ode-0.11.1\myprog\step1\step1.cbpをダブルクリックしてcodeblocksを起動しビルド・実行する.ダブルクリックするファイルの拡張子はcbpです.間違ってcppをダブルクリックしないように!
    3. 球の位置と大きさを変更してみましょう.
      • プロトタイプ宣言
        • void dsDrawSphere(const double p[3], const double R[12],  double r)
      • 引数p[3]は位置,R[12]は姿勢,rは半径.
    4. 直方体を表示させてください.次の関数を使います.
      • プロトタイプ宣言
        • void dsDrawBox(const double p[3], const double R[12], const double sides[3])
      • 上は関数のプロトタイプ宣言の形式なので,呼び出すときはconst doubleなどの型名を入れてはいけません.引数が配列の場合は,サンプルプログラムのように配列名だけを入れてください.
        例 dsDrawBox(p, R, sides);  // 呼び出す場合は配列名だけ
      • 1, 2番目の引数はdsDrawSphereのときと同じです.3番目の引数は直方体のx,y,z方向のサイズ[m]が入っている要素数3個の配列です.位置を表す配列pと同じように初期化すれば大丈夫です.
      • なお, doubleの前にあるconstは値を変えてはいけないという意味です。円柱を表示させてください
    5. 円柱を表示させましょう.
      • プロトタイプ宣言
        • void dsDrawCylinder(const double p[3], const double R[12],  double l, double r );
      • ここで,lは長さ,rは半径です.
    6. カプセルを表示させてください.dsDrawCapsuleでビルドできなエラーを直しましたので、最新のソースコードstep1-101217.zipをダウンロードし、それを変更してプログラムを作成してください。
      • プロトタイプ宣言
        • void dsDrawCapsule(const double  p[3], const double R[12], double l,  float r );

以上

ode
スポンサーリンク
シェアする
demura.netをフォローする

コメント

タイトルとURLをコピーしました