2005後期
情報グラフィックス論U
担当 鳥海有紀
授業資料 情報グラフィックス論U
戻る(プログラムを書く2) 次へ(アニメーションへの応用)

ループ文の色々な使い方

ループは様々な表現に応用することができる。
例えば、同じ図形を異なる場所に表示したり、色を順に変更して描いたり・・
以下にはループを使った色々の使い方を例を使って説明する。

色を順々に変える
円を描く
同じ図形を図形を繰り返し描く
アニメーション風に表示する


色を順々に変える

ループで変化できるは、図形の座標値だけはない。 このプログラムではループで色を順に変えていく例である。


#include <stdio.h>

int  main(void)
{
    int    i;       /*  カウンタとして使う変数 */
    int    x;       /*  xの移動量に使う変数 */
    int    y;       /*  yの移動量に使う変数  */
    int    r;       /*   色(r)の変化量に使う変数  */

    gopen(300, 300);
    for (i = 0; i < 256 ; i++) {

        x = 0;   /*  x方向の基準位置を代入する */
        y = i;   /*  y方向の基準位置を代入する */
        r = i;

        /*  基準位置に描く図形(線)の座標値を足す */
        gline(x+10, y+10, x+190, y+10, 255-r, 255, 255);
    }

    gclose();

    return 0;
}

ここでは変数rを使って、色の赤(R)を減らしている。 図形は白からシアンへと順に色を変えて表示される。 他の色にも同じように設定すれば、色のグラデーションを表現することができる。

トップへ


円を描く

円は、コンパスで描くときのように、中心と半径を決めた位置(点)を360度回転させて描く。 ここで円を描くループで使用するカウンタ変数にはi、円の位置に使う変数にはxyを使用する。


#include <stdio.h>
#include <math.h>

int main(void)
{
    int   i;
    int   x, y;

    gopen(400,400);
    for (i = 0; i < 360; i++)
    {
	    x = 200 + 50 * cos (3.1415 / 180 * i);  /*  式1  */
	    y = 200 + 50 * sin (3.1415 / 180 * i);  /*  式2  */
	    gpoint(x, y, 255, 255, 255);
    }
    gclose();

    return 0;
}

上のソースコードで円を描くための各点のx座標の表示位置が式1、y座標の表示位置が式2である。 それぞれ、次のような意味がある。

     x = (xの中心座標) + (x方向の半径)* cos (3.1415 / 180 * 角度)
     y = (yの中心座標) + (y方向の半径)* sin (3.1415 / 180 * 角度)

x方向の半径とy方向の半径を同じにすると円が描ける。 x方向の半径とy方向の半径を変えると楕円を描くこともできる。 for文で指定するループの範囲を変えれば円弧や楕円弧を描くことが可能である。 中心座標の位置が変わりながら円を描くことも可能である。

sin関数とcos関数

sin関数とcos関数は、図形の変換(回転)に必ず使う関数である。 それぞれの基本式は次のようになる。

   cosθ =  x  /  r
   sinθ =  y  /  r

この基本式によれば、角度(θ)と半径(r)を与えるとx座標値、y座標値を求めることができる。つまり、

      x = r * cosθ
      y = r * sinθ

となる。円はX軸上のrの位置にある点を回転して描かれている。 θには一般にラジアン角を使う。ラジアン角はPI(3.1415)を基準とする角度で、180度=PI(3.1415)である。 通常の角度(degree)をラジアン角に変換するには、次のようにする。

      θ = 3.1415 / 180 * degree

トップへ


同じ図形を図形を繰り返し描く


#include <stdio.h>

int  main(void)
{
    int    i;       /*  カウンタとして使う変数 */
    int    x;       /*  xの基準位置に使う変数 */
    int    y;       /*  yの基準位置に使う変数  */

    gopen(200, 200);
    for (i = 0; i < 3; i++) {

        x = i * 25;  /*  x方向の基準位置を代入する */
        y = 0;       /*  y方向の基準位置を代入する */

        /*  基準位置に描く図形(線)の座標値を足す */
        gline(x+10, y+10, x+10, y+20, 255, 255, 255);
        gline(x+10, y+20, x+20, y+20, 255, 255, 255);
        gline(x+10, y+10, x+20, y+10, 255, 255, 255);
        gline(x+20, y+10, x+20, y+20, 255, 255, 255);
    }

    gclose();

    return 0;
}

プログラムを見やすくするために
C言語はフリーフォーマットの言語。つまり() や;や{}を正しく書けばよく、スペースや改行はプログラムの処理には関係ない。 従って自分が見やすいように、スペースや改行を入れるとよい。 /* と */で挟まれた部分はコメントとして処理される。コメントはプログラムの処理には影響しない。 コメントを入れるを処理の概要が解りやすくなるはず。

図形の基準位置

コンピュータ上で図形を描くときは座標を使う。何も指定しなければ描画する図形の基準は(0,0)になる。 この基準の座標を変更すれば図形全体をそのまま別の場所に描くことができる。

このプログラムでは、基準位置になる座標を(x,y)として変数をつかう。 カウンタに使う変数iに代入するのでX軸方向に図形(この場合は四角)を並べて描くことになる。 Y軸方向に並べたい場合は、y = 0; となっている部分をカウンタに従って変化するように代入文を変更する。 (例えば、 y = i * 25;) 同じ図形を繰り返し描いて行くには、変数xyをカウンタの増加に従って変化するように代入文を作る。 繰り返し回数は、for (i = 0; i < 3; i++)3で決まる。 この場合3回繰り返す。

応用:図形に太い線が含まれる場合

図形に太い線がループで書かれた図形を繰り返して描く場合は、ループを二重にする。


#include <stdio.h>

int  main(void)
{
    int    i;       /*  図形の繰り返しのカウンタに使う変数 */
    int    x;       /*  xの基準位置に使う変数 */
    int    y;       /*  yの基準位置に使う変数  */
    int    j;       /*  太い線を書くためのカウンタに使う変数 */

    gopen(200, 200);
    for (i = 0; i < 3; i++) {

        x = i * 25;  /*  x方向の基準位置を代入する */
        y = 0;       /*  y方向の基準位置を代入する */

        /*  基準位置に描く図形(線)の座標値を足す */
        gline(x+10, y+10, x+10, y+20, 255, 255, 255);
        gline(x+10, y+20, x+20, y+20, 255, 255, 255);
        gline(x+10, y+10, x+20, y+10, 255, 255, 255);
        /*  太い線 */
        for (j = 0; j < 4; j++) {
            gline(x+20+j, y+10, x+20+j, y+20, 255, 255, 255);
        }
    }

    gclose();

    return 0;
}

トップへ


応用:図形が円の場合

円を繰り返して描く場合はループを二重にすると良い


#include <stdio.h>
#include <math.h>

int  main(void)
{
    int    i;       /*  図形の繰り返しのカウンタに使う変数 */
    int    x;       /*  xの基準位置に使う変数 */
    int    y;       /*  yの基準位置に使う変数  */
    int    j;       /*  太い線を書くためのカウンタに使う変数 */
    int    cx, cy;  /*  円の中心座標 */

    gopen(300, 300);
    for (i = 0; i < 3; i++) {

        x = 50 + i * 25;       /*  x方向の基準位置を代入する */
        y = 50 + i * 25;       /*  y方向の基準位置を代入する */

        /*  半径50の円を描く */
        for (j = 0; j < 360; j++) {
            cx = x + 50 * cos(3.1415 / 180 * j);
            cy = y + 50 * sin(3.1415 / 180 * j);
            gpoint(cx, cy, 255, 255, 255);
        }
    }

    gclose();

    return 0;
}

トップへ


アニメーション風に表示する

1つの図形を描いた後、次の図形を描く前にその図形を消してから描くようにすると、 あたかもその図形が動いたように表示することが出来る。


#include <stdio.h>

int main(void)
{
    int  i;
    int  x;
    int  y;

    gopen(300, 200);
    for (i=0; i < 100; i++) {
        x = i;
        y = 0;
        gclear();    /*  前回描いた図形を消す */

        gline(x+50,  y+50,  x+150, y+50,  0, 255, 255);
        gline(x+50,  y+50,  x+100, y+150, 255, 0, 255);
        gline(x+100, y+150, x+150, y+50,  255, 255, 0);
    }
    gclose();

    return 0;
}

描く図形が少なくコンピュータの処理が速すぎて図形がスムーズに動くように見えない場合は、 描画が終わったあとに適当な待ち時間を入れるとよい。 逆に図形が多くてスムーズに動くように見えない場合は、書いた部分を上から背景と同じ色で描くとよい。 gclear()を呼び出すことと同じになり、処理も速くなる。

トップへ


授業資料 情報グラフィックス論U 戻る(プログラムを書く2) 次へ(アニメーションへの応用)

Copyright 2002-2005 Yuki Toriumi