第三週 2次元グラフィックス

計算機序論2, www.kameda-lab.org 2004/10/03

実習の流れ

2次元図形変換を使って図形を書こう. そのために, 以下の部品を順番に作っていこう.
  1. 図形のためのデータ構造は前回の演習で用いたものを使う. 各線分はLINE構造体で,線分の集まりはFIGURE構造体で扱おう.
  2. 幾何変換を表現するためには,PARAMETER構造体を使う. 平行移動(dx, dy, dz),スケール(sx, sy, sz), 回転(thetax, thetay, thetaz)を順に書けば良い. これらも全て3次元グラフィックスに対応したものになっている. 回転が3つあるのが腑に落ちないかもしれないが, 3次元空間での回転は3つの軸(x, y, z軸)まわりの回転として 表される. ただし,2次元グラフィックスでは, x軸回り,y軸回りの回転を使わないので(適当な値を入れておき), z軸回りの回転(thetaz)にだけ欲しい回転角を入れよう

    // 幾何変換のためのパラメータ // 9つのパラメータと補足データを保持 struct PARAMETER { float dx; // 平行移動(x方向) float dy; // 平行移動(y方向) float dz; // 平行移動(z方向) float sx; // スケール(x軸) float sy; // スケール(y軸) float sz; // スケール(z軸) float thetax; // 回転(x軸) float thetay; // 回転(y軸) float thetaz; // 回転(z軸) mat3x3 matrix; // 変換行列 struct PARAMETER next; // 次の幾何変換パラメータ };
  3. 2次元幾何変換のための関数群を用意しよう.

    1. まず,変換行列のためのデータ型を定義しよう. 3x3行列となることに注意すること.
      typedef double mat3x3[3][3];
    2. 次に,変換行列の値を埋める関数を作ろう. 以下の例は平行移動で, (dx, dy) は平行移動量, transformが変換行列を表す.
      void simle_translation (double dx, double dy, mat3x3 transform)
    3. 変換行列とオリジナル図形(点列)から新しい図形(点列)を求める 関数を作ろう. LINE構造体と transformから, 新しい点列 LINE 構造体を作る. 新しいLINE構造体(へのポインタ)を返す関数であることに注意すること.
      struct LINE *LINE_transform(mat3x3 transform, LINE *line)
    4. 変換された直線を描画するための関数を作ろう. 正規化座標 系で定義された点列を基に, 実際のウィンドウに線を表示する.
      void normalized_draw_LINE(LINE *line)
  4. 面白いアニメーションを作ってみよう.

    1. 変換の行列を時刻(ループの回数)によって変えてみよう. 変換パラメータ(例えば, 上記の (dx, dy))を時刻によって 変えれば良い.
    2. 画面をクリアすれば,描かれていたものが全て消える.
      glClear (GL_COLOR_BUFFER_BIT);
    3. 一つの面白い方法として,一組(2つ)の変換パラメータを用意し, その間を補間した変換パラメータを使いながら多数回, 図を書き換えていく方法がある. こうすると,図形が滑らかに移動したアニメーションとなる.
    4. 適当に待ち時間を入れて, アニメーションのスピードを変えよう. それには, 以下の関数を用いると便利である. usleep(μsec)として 呼べば, μsec×(1/1,000,000)秒間, 動きが止まる. 詳しくは, man usleepで調べること. #include <unistd.h> int usleep(unsigned int microseconds)

今週の課題

今週行ったことを述べること。 なお,今回のレポートでは,プログラム構成,フローチャートを省いても 良い.実行結果は,時刻の違うものが2枚ぐらいあれば,わかりやすくて 良い.
特にどのような動きのアニメーション関数を作ったかは必ず記述すること。 もともとあった関数群に加えて新しい関数を用意したり、もとから あった関数に大幅に手を加えた場合は、高評価するので、その部分に ついて記述すること。

サンプルプログラム


ヒント


さらに先へ

余力のある人は,ボーナス課題をやってみよう.

  1. 時刻によって色や線種が変わるようにしよう[難度 ★]


  2. 床でボールが跳ねる,磁石に金属が吸い寄せられる等, 実際の物理現象として起こる運動をシミュレーションしてみよう[難度 ★★]

Yoshinari Kameda: 2004/09/17-
Yuichi Nakamura: Sun Oct 5 18:19:45 JST 2003