直線の式のパラメーター表示とコンピュータグラフィックスのC言語プログラム
教育用の覚書。グラフィックス座標とワールド座標の変換についてのラフな説明。
問題: y=x2-2x-2 のグラフを -1≦x≦3 の範囲で描きなさい。
数学的知識をプログラミングに応用するときの要点
- [出発点となる基礎知識] 始点 A(x0,y0), 終点 B(x1,y1) をつなぐ線分上の点の座標 P(X,Y) を表す式は
ただし
と必ず書ける。理由は「t=0を代入するとAの座標になる」「t=1を代入するとBの座標になる」「Pの座標はtの1次関数である」からである。 - [tを作る] X が区間 X0 ≦ X ≦ X1 にあるとき、 は 「X0のとき t=0」「X1のとき t=1」となる1次関数である。
- だからグラフィック座標が Imim ≦ i ≦ Imax でワールド座標(数学的な値の座標)が Xmin ≦ x ≦ Xmax ならば、「グラフィック座標を数学座標に変換する計算」は
すると i=Imin のとき x=Xmin, i=Imax のとき x=Xmax となる関数を作ることができる。ここでCプログラミングを考えると 1 の t の式を 2 の x の式に代入したややこしい式をわざわざ作る必要はない。- を計算する
- この t を使って x = (1-t) Xmin + t Xmax を計算する
- この考え方は「数学座標をグラフィックス座標に変換する計算」にも使えて
すると y=Ymin のとき j=Jmax, y=Ymax のとき j=Jmin となる関数を作ることができる。- を計算する
- この t を使って j = (1-t) Jmax + t Jmin を計算する
- 区間の両端, Imin と Imax, Xmin と Xmax の値の対応さえきちんとしていれば、途中も大丈夫。
コードを書く上での要点
- 数学的な座標(x,y)の数値とCG的な座標の数値(i,j)の変換は関数で作っておいて、変換が必要なときは関数の呼び出しで済ませること。目的はプログラムを書くときに、ピクセル座標と数学座標の変換をいちいち考えないため。
- プログラム上で固定されるパラメーターは定数として宣言しておき、定数名を使うこと。目的はピクセル座標や数学座標のサイズ変更を容易にするため。
教育用サンプルコード(教育用なので1ピクセル程度の表示の狂いが出ることもある。*1)
#include <[何か描画用].h> // ピクセル座標(i,j)の数値の最大値と最小値の設定 #define Imin (0) #define Imax (800) #define Jmin (0) #define Jmax (800) // 数学座標(x,y)の数値の最大値と最小値の設定 #define Xmin (-1.0) #define Xmax (3.0) #define Ymin (-1.0) #define Ymax (1.0) // x方向のピクセル座標を数学座標にする関数 double doubleX (int I) { double t=(((double)(I-Imin))/((double)(Imax-Imin))); double x= (1.0-t)*Xmin + t*Xmax; return x; } // y方向の数学座標をピクセル座標にする関数 int pixelY (double Y) { double t=(Y-Ymin)/(Ymax-Ymin); double y= (1.0-t)*Jmax + t*Jmin; return (int) y; } // 描きたいグラフを数学座標の値で計算する関数 double F (double X) { return x*x-2*x-2; // このサンプルは2次関数 f(x)=x^2-2x-2 } // エントリポイント関数 int main (void) { int i,j; double x,y; // ピクセル座標でのx方向の for ループ for ( i=Imin ; i<=Imax ; i++ ) { // 関数のグラフ(x,y)の計算 x= doubleX(i); // ピクセル座標 i の数学座標 x への変換 y= F(x); // 数学座標 x のときの y の値の計算 // 描画 j= pixelY(y); // 数学座標 y のピクセル座標 j への変換 [描画用関数]( i , j ); } return 0; }
書き出してみると案外と長くなるものだな。