オリジナルなタートルグラフィックスプログラムを作成せよ,
ただし,芸術性よりも技術性を重視する.
また,あまりにも複雑過ぎるとプログラムが誤動作する可能性がある. タートルの操作回数(タートル制御関数の呼出回数)を 10万ステップ以内に収めること.
注意事項:本科目は,CG の単なる作成 を目的とするものではない. 作業の効率化が目的である. CG は単なる手段(例題)にすぎない.
なお,「複雑さ」は「乱雑さ」とは異なる. 「規則性」や「美しさ」を意識せよ.
To: yanagawa@kushiro-ct.ac.jp Subject: ap-kame
(本文) ・個人情報:クラス,番号,氏名 ・作品情報:タイトル,説明文(+工夫アピール等) (添付ファイル) ・ソースファイル(ファイル名:ユーザ名.c) # 例:s1806XX.c,k1807XX.c ・画像ファイル(ファイル名:ユーザ名.png) # 例:s1806XX.png,k1807XX.png
作品のファイル名について, 作成中には各自で自由に決めてよいが, 提出時には規定のファイル名(ユーザ名.拡張子) に変更すること. (例:k1806XX.c, s1807XX.png)
$ mv 移動元ファイル名 移動先ディレクトリ名/ # 他のディレクトリへ移動 $ mv 移動元ファイル名 移動先ファイル名 # ファイル名の変更
$ cp コピー元ファイル名 コピー先ディレクトリ名/ $ cp コピー元ファイル名 コピー先ファイル名
$ rm ファイル名
$ pwd
$ ls ディレクトリ名/ # ディレクトリ内のファイル一覧 $ ls # カレントディレクトリ内のファイル一覧
なお,ディレクトリ間をまたぐ移動・複製では, 次のような特殊なディレクトリ名も使うと便利.
# 撮影対象ウィンドウを最前面に出しておき... $ import ユーザ名.png # 撮影 # 撮影対象ウィンドウ内で左クリック.
$ display ユーザ名.png & # 撮影結果の確認
// アプリケーション制御関数 void Init(char *title) アプリの初期化とタイトルの設定(必須) void InitCanvas(int w, int h) キャンバスサイズを設定(デフォルト:10×10) void Play() アニメーションを開始(必須) // タートル制御関数 void PenUp() ペンを上げる(足跡を残さない) void PenDown() ペンを下げる(足跡を残す) void SetColor(int color) 色を設定(0〜7) void SetPower(double power) ペン上移動時のジャンプ力を設定(デフォルト:1.0) void SetSpin(int spin) ペン上移動時のスピン回数を設定(デフォルト:0) void Goto(double x, double y) 位置を設定(絶対的な位置変更) void Head(double deg) 角度を設定(絶対的な角度変更) void Move(double step) 移動(相対的な位置変更) void Turn(double deg) 旋回(相対的な角度変更) // タートル状態関数 double PosX() x 座標 double PosY() y 座標 double Dir() 角度 int Pen() ペンの状態(0:up,1:down) int Color() ペンの色番号(0〜7) int Step() 制御ステップ数(現在までに実行された制御命令の個数) // 乱数 int Rand(int n) 0 以上 n 未満の整数乱数
[Q] 終了(Quit) [S] 一時停止/再開(Stop/Start) [R] 初期状態(Reset) [E] 最終状態(End) [C] 軌跡表示変更(Change) [V] 視点変更(View) [Cursor] 回転 [Space],[B] ズーム [-],[+] 速度調整
kame3d では,複数匹のタートルを同時に動かすこともできる. 以下はそのサンプル synchro.c:
// 複数タートルの例 #include "kame3d.h" #include <math.h> // 数学関数(sin, cos 等)を使うのに必要 // タートル t で多角形を描く // n:頂点数,len:辺の長さ void Polygon(tgObj *t, int n, double len) { int i; for (i = 0; i < n; i++) { tgMove(t, len); // タートル t の移動 tgTurn(t, 360.0/n); // タートル t の旋回 } } int main(int argc, char **argv) // メインの引数(必須) { tgObj *t[10]; // タートルを10匹分用意(匹数は任意) int i; double x, y, a, d; int c; tgInit(argc, argv, "Synchronized Turtle"); // アプリケーションの初期化(必須,タイトル文字列の内容は任意) tgInitCanvas(10.0, 10.0); // キャンバスの初期化 for (i = 0; i < 6; i++) { // タートル t[i] の処理 a = 2.0*M_PI*i/6.0; // 座標計算用の方位角(rad) x = 1.0*cos(a); // x座標 y = 1.0*sin(a); // y座標 d = i*60.0-90.0; // 進行方向の方位角(deg) c = Rand(8); // 色 t[i] = tgNewTurtle(x, y, d); // タートル t[i] を生成 tgSetColor(t[i], c); // タートル t[i] のペンの色を設定 Polygon(t[i], 18, 0.4); // タートル t[i] で多角形を描く } tgPlay(10, t, 6); // アニメーション開始(必須) // 10:各フレーム間の時間間隔 (ミリ秒).再生速度に関連. // t, 6:タートル t[0]〜t[5] の 6匹を同時に動かす. return (0); }
ソースコード的な単数版との違いの要点は,次の通り:
なお,すべてのタートルは,同時並行にしか動かない. つまり, 「タートル t[0] の動作が終了してから, タートル t[1] をスタートさせる」 みたいなことはできない.
また,課題提出・評価の対象は,描画結果の静止画像とソースコードだけなので, 描画過程のアニメーションに凝りすぎて時間を浪費しないように注意しよう.