第4回講義資料(グラフィック・プログラミング入門 - 2)

曲線の描画と場合分け

グラフィック

場合分け

数学関数の利用

サンプルプログラム

  #include "sfcgl.h"
  #include <math.h>
  #define PI 3.141593                            /* 円周率π*/

  void display() {
    double x, y, x1, y1, t;
    BGColor(0,0,0);                              /* 背景色を変更する */
    for(t = 0.0; t < PI; t += 0.3) {
      x = cos(t);                                /* x座標を計算する */
      y = sin(t);                                /* y座標を計算する */
      if(t != 0.0) {
        DrawLine(x, y, 0, x1, y1, 0);            /* 線分を描画する */
      }
      x1 = x; y1 = y;                            /* 座標を保存しておく */
    } 
    SGSwapFrames();
  } 

  int main(int argc, char** argv) {
    SGInit(argc, argv);                   /* SGLを初期化する */
    SGOpenWindow(50, 50, 500, 500);       /* ウインドウを開く*/
    /*SG2DMode();*/                       /* 2次元座標系モードを設定する */
    SGSetDisplay(display);                /* 描画関数を設定する */
    SGCallBack();                         /* コールバック関数を設定する */
    return 0;
  }

課題1

(a) きれいな1周の円を描画するように変更しましょう.
ヒント:パラメータ t を 0〜PI(3,14…)まで変化させると半周の円が描けます. 円を1周させるには t を 0〜PI*2(6.28…)まで変化させるます. また t の増分を小さくすることで, 滑らかな曲線が描けます. 例えば, 次のようにします.
/* t を 0〜2*PI まで変化させる */
/* t を 0.01 ずつ増やす        */
for(t = 0.0; t < PI*2; t += 0.01) {
  ....
}
解答例
(b) 円の半径を指定できるように変更しましょう.
ヒント:円の半径を保存しておく大域変数(double r;)を用意し, scanf文を用 いて半径を読み込みます. display() 関数内で変数 r の値を利用して円を書 くようにします. 上のサンプルプログラムでは, 半径1の円を書くようになっ ているので, x, y座標をr倍することで半径 r の円を描画できます.
解答例
(c) n 重の円を描画できるように変更しましょう.
ヒント:円を描画する箇所をfor文で囲み, n 回繰り返すようにします. また, 繰り返すごとに n を用いて半径を計算し, 円が小さくなっていくようにしま す.
解答例
(d) 楕円を n 重に描画するよう変更しましょう.
ヒント:x, y座標を計算する部分を楕円を描画するように変更します.
 楕円を描画する.
  x = a * cos(t) * r;
  y = b * sin(t) * r;
大域変数 double a, b; を用意しておき, scanf文を用いて読み込むようにします. (ex. a = 1.0, b = 0.5).
解答例

課題2

(a) エピトロコイドを書いてみましょう.
ヒント:x, y座標を計算する部分を次のように変更します.
  エピトロコイドを描画する.
  x = (a+b)*cos(t) - c*cos((a/b+1.0)*t);
  y = (a+b)*sin(t) - c*sin((a/b+1.0)*t);
大域変数 double a, b, c; を用意しておき, scanf文を用いて読み込むようにします. (ex. a=1.0, b=0.2, c=0.3).
解答例
(b) c の値を変化させて, エピトロコイドを重ね書きしてみましょう.
ヒント:エピトロコイドを描画する箇所をfor文で囲い, cの値を変化させながら繰り返し描画を行います.
解答例

課題3

(a) ハイポトロコイドを書いてみましょう.
ヒント:x, y座標を計算する部分を次のように変更します.
  /* ハイポトロコイドを描画する */
  x = (a-b)*cos(t) + c*cos((a/b+1.0)*t);
  y = (a-b)*sin(t) - c*sin((a/b+1.0)*t);
大域変数 double a, b, c; を用意しておき, scanf文を用いて読み込むようにします. (ex. a=1.0, b=0.2, c=0.3).
解答例
(b) c の値を変化させて, ハイポトロコイドを重ね書きしてみましょう.
ヒント:ハイポトロコイドを描画する箇所をfor文で囲い, cの値を変化させながら繰り返し描画を行います
解答例

課題4

係数, +−をいろいろ変更して美しい絵を描画するプログラムを作りましょう. ただし, 提出するプログラムには入力文(scanf文)を入れないこ と. scanf文を使って数値を読み込むのではなく, プログラムのどこかで数値 を与えておきましょう.
メールで kusumoto 宛に10月23日(月)23時59分までに プログラムの .c のファイルを 送ること。コメントもプログラム中に入れておくこと。 メールのSubject は ipl1bc-04-4 とすること。 前回、.exe の実行ファイルを送った人がいるので、注意すること。