関数の立体図の回転
2変数との関数
の様子は曲面の立体図として視覚的に表すことができる。
図1 関数の立体図
図1は関数
のにおける関数値を表す曲面を描いたものである。図1では関数値の曲面を立方体の内部に描き、それを適当に回転してY軸の負の方向から見た状態で描いている(図2)。
図2 関数の曲面と視線
関数の変域と関数値の範囲を適当に線形変換して立方体内にちょうど収まるようにした後、Y軸の負の方向から見た点の軌跡(曲面)を描いている。関数値は、変域を格子状に区切り、格子点における関数値を求め、関数値の曲面を、格子点での値を通る、点を頂点とする四角形を連結した面(タイルをつないだような面)で表している。このタイルは以下のようにクラス型として表している。
//
// タイル: 描画単位
//
struct Tile {
double Coord[4][3];
double v;
Tile(){
}
//
// コピー・コンストラクタ
//
Tile(
Tile & tile ){
this->v = tile.v;
for (int i = 0; i
< 4; i++)
for (int j = 0; j
< 3; j++)
this->Coord[i][j] = tile.Coord[i][j];
}
//
// 代入演算子=
//
Tile
& operator = ( Tile & R ){
this->v = R.v;
for (int i = 0; i
< 4; i++)
for (int j = 0; j
< 3; j++)
this->Coord[i][j] = R.Coord[i][j];
return *this;
}
};
//
// タイルのY座標の比較
//
bool operator > ( Tile & L, Tile & R ); // 演算子> のオーバーロード
bool operator < ( Tile & L, Tile & R ); // 演算子< のオーバーロード
立方体内の関数の曲面は、オイラーの角(斉藤、1966)を設定して自由に回転することができる。オイラーの角とは、次のように3次元空間での回転を表す3つの角、、、、のことである。Y軸の回りの角θの回転を、Z軸の回りの角および角の回転をおよびで表わすと、回転Tは3つの回転の積
として書き表すことができる。すなわち、
(1)
と書ける。(1)式による回転では、まず角によりZ軸の周りの回転が行われ、その後Y 軸の回りの角θの回転が行われる。最後にこれら2つの回転後の新しいZ軸の周りでの角での回転が行われる。
回転後の描画は、視線をY軸の負の方向から正の方向に取り、Y軸の正の方向の後ろの曲面を表す四辺形(のタイル)から順番に前の方(Y軸の負の方向の方)のタイルを描いていくことにより、視線の前方の曲面から隠れている後ろの曲面の描画の処理を行っている。
描画の対象となる関数は、ソースコードファイルcommon.cppにおいて関数MyFuncとして以下のように定義されている。
double MyFunc( double
x, double y ){
return sqr(sqr(0.5*x)) + sqr(sqr(0.5*y)) - 2.0 *
(sqr(0.5*x) + sqr(0.5*y));
}
この関数は、ヘッダーファイルForm1.hにおいて描画用参照クラス型FormDisplayのオブジェクトを生成して、以下のようにメソッドSetFuncにより描画対象関数として設定している。
cf
= gcnew FormDisplay();
cf->SetFunc(
MyFunc ); // 描画関数MyFunc
cf->ShowDialog();
これらのファイルは圧縮ファイルPerspectiveRot.zipとしてまとめた。
図1の立体図を描くプログラムPerspectiveRot.exeはプログラム名PerspectiveRot.exeをクリックしてダウンロード・実行することができる。プログラムはVisual C++2008/CLRで作成され、.NET
Framework3.5対応である。プログラムのソースファイルなどをまとめた圧縮ファイルPerspectiveRot.zipもファイル名をマウスの右ボタンでクリックしてダウンロードすることができる。ダウンロードしたファイルは、ファイル名PerspectiveRot.zipをマウスの右ボタンでクリックして表示されるメニュから「解凍」あるいは「展開」を選んで解凍することができる。解凍したファイルはVisual C++2008で開くことができる。
描画対象関数は、プログラムをVisual
C++2008で開いて自由に変更することができる。また、関数の立体図描画用ヘッダーファイルFormDisplay.hなどは他のプロジェクトに取り込んで利用することもできる。これらの他のプロジェクトでの利用方法は、<岡本安晴「大学生のための心理学VC++プログラミング入門」勁草書房>の「17.2 子フォームの再利用」Pp. 282-288 で詳しく説明している。
プログラムの使い方
プログラムを実行すると先ず図3のフォームが表示される。
図3 実行開始時のフォーム
関数は、、の範囲で描画される。X軸およびY軸での分割数がnの格子の交点の値によって描画が行われる。「GO」ボタンのクリックで図4の描画用フォームが表示され、回転を行わない状態での関数の曲面の描画が行われる。
図4 回転前の描画
関数の曲面は、関数値に対応した色で描かれているが、この色は次のコードによって設定され、関数を表すタイルの描画が行われている。
for (int i = 0; i < n*n; i++){
int ci =
105 + int((tilesV[i]->v + 1.0) * 75);
int ci0 =
int((tilesV[i]->v + 1.0) * 75);
bshB = gcnew
SolidBrush(Color::FromArgb(0, ci0, ci));
array<Point>
^ ps = {Point(DScaleX(tilesV[i]->Coord[0][0]),
DScaleY(tilesV[i]->Coord[0][2])),
Point(DScaleX(tilesV[i]->Coord[1][0]),
DScaleY(tilesV[i]->Coord[1][2])),
Point(DScaleX(tilesV[i]->Coord[3][0]),
DScaleY(tilesV[i]->Coord[3][2])),
Point(DScaleX(tilesV[i]->Coord[2][0]),
DScaleY(tilesV[i]->Coord[2][2]))};
gh->FillPolygon(bshB, ps);
gh->DrawPolygon(pn, ps);
}
画面下に並んでいる3つのトラックバーを動かして適当に回転を行う。トラックバーを動かすとそれに合わせて回転された曲面の描画が表示される(図5)。
図5 回転
トラックバーの下には回転角が度を単位として表示されている。
表示されている図は、画面右上の「Save」ボタンのクリックでファイルに保存することができる。
図6 画像保存用ファイル名の設定
「Save」ボタンをクリックすると図6のダイアログボックスが表示される。ファイルはビットマップファイル(*.bmp)として保存されるので、ファイル名は拡張子として.bmpを付けておく。ファイル名の設定後、「保存」ボタンをクリックすると設定した名前のファイルに描画図形が保存される。
画面右上の「Close」ボタンをクリックすると図3に戻る。関数の変域や格子点の数などを他の値に設定して「GO」ボタンをクリックすると、設定された値に対応した描画が行われる。「Close」ボタンをクリックするとプログラムの実行終了となる。
関数の等高線図の描画プログラム例は<関数の等高線図の描画>に用意した。
なお、Visual C++プログラミングの解説を<岡本安晴「大学生のための心理学VC++プログラミング入門」勁草書房>で行っている。