高校数学10分プログラミング(数学B編 2.空間のベクトル)1日目「空間上の図形について考える」解説
マガジンリスト > 数学B編 2.空間のベクトル > 1日目 解説
本日の課題、おつかれさまでした。
課題の空間上に三角形を描いてその形状を調べるためのプログラムを作成することができたでしょうか。
解答例
今回の課題の$${\triangle \mathrm{ABC}}$$を描いてその形状を調べるためのプログラムの例を示します。
float range; // 座標系での表示範囲-range≦x,y.z≦range
float res; // 座標系のサイズをキャンバスのサイズに変換するパラメータ
float angle = 0.0;
PVector a,b,c; // 空間の座標
void setup(){
size(400, 400, P3D);
noFill();
ortho();
range = 10.0;
res = width / 2.0 / range;
// 点A,B,Cの座標を表わすベクトル
a = new PVector(1.0, 1.0, 5.0);
b = new PVector(4.0, 3.0, -1.0);
c = new PVector(-2.0, 1.0, 2.0);
// △ABCの各辺の長さ
float AB = sqrt((b.x-a.x)*(b.x-a.x) + (b.y-a.y)*(b.y-a.y) + (b.z-a.z)*(b.z-a.z));
float BC = sqrt((c.x-b.x)*(c.x-b.x) + (c.y-b.y)*(c.y-b.y) + (c.z-b.z)*(c.z-b.z));
float CA = sqrt((a.x-c.x)*(a.x-c.x) + (a.y-c.y)*(a.y-c.y) + (a.z-c.z)*(a.z-c.z));
println("AB:", AB);
println("BC:", BC);
println("CA:", CA);
}
void draw(){
background(204); // 背景をグレーにする
// 視点を設定する
camera(200.0, -200.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0);
// マウスボタンが押されたときの処理
if(mousePressed){
if( mouseButton == LEFT ){ // 左ボタンがおされたときはz軸時計周りに回転
angle = angle + 1.0;
} else if( mouseButton == RIGHT ){ // 右ボタンがおされたときはz軸反時計周りに回転
angle = angle -1.0;
} else {
}
}
// z軸周りに回転
rotateZ(radians(angle));
// 座標軸の設定
strokeWeight(1);
fill(255,0,0);
stroke(255,0,0);
arrow3D(0.0,0.0,0.0,range * res,0.0,0.0); // x軸(赤色)
fill(0,255,0);
stroke(0,255,0);
arrow3D(0.0,0.0,0.0,0.0,range * res,0.0); // y軸(緑色)
fill(0,0,255);
stroke(0,0,255);
arrow3D(0.0,0.0,0.0,0.0,0.0,range * res); // z軸(青色)
noFill();
stroke(0,0,0);
// 以下に、図形を描いていく
// △ABCの頂点をプロットする
strokeWeight(5);
stroke(0,0,0);
point_rhs(a.copy().mult(res));
point_rhs(b.copy().mult(res));
point_rhs(c.copy().mult(res));
// △ABCを描く
strokeWeight(1);
triangle_rhs(a.copy().mult(res),b.copy().mult(res),c.copy().mult(res));
}
ソースコード2 $${\triangle \mathrm{ABC}}$$を描いてその形状を調べるためのプログラム(完成版)
ソースコード2を、スケッチ「drawTriangle3D」の 「drawTriangle3D」タブのテキストエディタ部分に書いて実行すると、開発環境ウィンドウのコンソールに、
AB: 7.0
BC: 7.0
CA: 4.2426405
と出力されます(図1)。
また、実行ウィンドウのキャンバスに3次元空間の座標軸として$${x}$$軸を赤色、$${y}$$軸を緑色、$${z}$$軸を青色の矢印でそれぞれ表し、その3次元座標上に、3つの点$${\mathrm{A,B,C}}$$とそれらの点を結んでできる$${\triangle \mathrm{ABC}}$$が黒色で描かれます(図2)。
なお、実行ウィンドウのキャンバス上をクリックすると図形が$${z}$$軸(青色)を中心として時計回りに回転し、右クリックすると図形が$${z}$$軸(青色)を中心として反時計回りに回転するようになっています。
図3は、図形を時計回りに少し回転させたものになります。
図3を見ると、$${\triangle \mathrm{ABC}}$$は二等辺三角形になっていると推測できます。実際、開発環境ウィンドウのコンソールに出力された結果をみると、辺$${\mathrm{AB}}$$と$${\mathrm{BC}}$$の長さが同じ値$${7}$$となっており、$${\triangle \mathrm{ABC}}$$は二等辺三角形であることがわかります。
プログラムの解説
スケッチ「drawTriangle3D」のプログラムについて、順に説明していきます。
グローバル変数を設定する
setup 関数、draw 関数などで共通して利用する変数や draw 関数で更新しながら利用する変数などは、プログラムの先頭でグローバル変数としてこれらの関数の外で宣言、初期化しておきます。
float range; // 座標系での表示範囲-range≦x,y.z≦range
float res; // 座標系のサイズをキャンバスのサイズに変換するパラメータ
float angle = 0.0;
PVector a,b,c; // 空間の座標
空間座標を利用する
ソースコード2の setup 関数内の
size(400, 400, P3D);
は、実行ウィンドウのキャンバスの大きさを設定する関数ですが、その3つ目の引数に P3D と設定することで、空間座標を扱うことができるようになります。
draw 関数
draw 関数はその中身に記述されたプログラムを 1 秒間に 60 回実行するものです。以下で、draw 関数の中身の記述について解説しておきます。
背景をグレーにする
draw 関数では、最初に background 関数を呼び出しています。
background(204); // 背景をグレーにする
204 の数値は、実行ウィンドウのキャンバスのデフォルトの背景色を表しています。つまり、draw 関数により、最初にキャンバス全体をグレー色で塗りつぶして描かれていた図形を一旦全て消してしまいます。
視点を設定する
次に
// 視点を設定する
camera(200.0, -200.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0);
では、3次元空間をどの位置からどの方向に見るかを設定しています。詳細は記事『高校数学をプログラミングで解く(準備編)「4-3 Processingでの3次元座標」』で解説していますので、興味のある方は確認してみてください。
マウス操作を行う
次のコード
// マウスボタンが押されたときの処理
if(mousePressed){
if( mouseButton == LEFT ){ // 左ボタンがおされたときはz軸時計周りに回転
angle = angle + 1.0;
} else if( mouseButton == RIGHT ){ // 右ボタンがおされたときはz軸反時計周りに回転
angle = angle -1.0;
} else {
}
}
// z軸周りに回転
rotateZ(radians(angle));
は、マウス操作を行う処理を記述しています。上記で説明した通り、実行ウィンドウのキャンバス上をクリックすると図形が$${z}$$軸(青色)を中心として時計回りに回転し、右クリックすると図形が$${z}$$軸(青色)を中心として反時計回りに回転するようになっていますが、この部分がその処理のコードとなります。詳細は記事『高校数学をプログラミングで解く(準備編)「4-2 マウス操作」』で解説していますので、興味のある方は確認してみてください。
座標軸の設定
今回3次元空間上の座標軸を表すために、空間ベクトルを描くための関
数 arrow3D を利用しています。
// 座標軸の設定
strokeWeight(1);
fill(255,0,0);
stroke(255,0,0);
arrow3D(0.0,0.0,0.0,range * res,0.0,0.0); // x軸(赤色)
fill(0,255,0);
stroke(0,255,0);
arrow3D(0.0,0.0,0.0,0.0,range * res,0.0); // y軸(緑色)
fill(0,0,255);
stroke(0,0,255);
arrow3D(0.0,0.0,0.0,0.0,0.0,range * res); // z軸(青色)
この arrow3D 関数は自作した関数です。スケッチ「drawTriangle3D」の開発環境ウィンドウで「setArrow3D」タブを選択すると、そのソースコードを確認することができます(図4)。
空間ベクトルを描く関数 arrow3D は、次のようになっています。
arrow3D(
float start_x, // ベクトルの始点のx座標
float start_y, // ベクトルの始点のy座標
float start_z, // ベクトルの始点のz座標
float end_x, // ベクトルの終点のx座標
float end_y, // ベクトルの終点のy座標
float end_z // ベクトルの終点のz座標
)
なお、それぞれの座標値はキャンバスのサイズで設定されることに注意してください。arrow3D 関数の詳細は記事『高校数学をプログラミングで解く(数学B編)「2-0-1 空間ベクトルを描く」』で解説していますので、興味のある方は確認してみてください。
図形を描く
draw 関数の中身の最後に、図形を描くコードを記述しています。
// △ABCの頂点をプロットする
strokeWeight(5);
stroke(0,0,0);
point_rhs(a.copy().mult(res));
point_rhs(b.copy().mult(res));
point_rhs(c.copy().mult(res));
// △ABCを描く
strokeWeight(1);
triangle_rhs(a.copy().mult(res),b.copy().mult(res),c.copy().mult(res));
point_rhs 関数が空間上に点をプロットする関数で、triangle_rhs 関数が空間上に三角形を描く関数になります。これらの関数も自作した関数です。スケッチ「drawTriangle3D」の開発環境ウィンドウで「tools_rhs」タブを選択すると、そのソースコードを確認することができます(図5)。
空間上に点をプロットする関数 point_rhs と空間上に三角形を描く関数 triangle_rhs は、次のようになっています。
point_rhs(
PVector a
)
// 右手座標系上に三角形を描く関数
triangle_rhs(
PVector a,
PVector b,
PVector c
)
なお、関数名に rhs を付けているのは、右手系の3次元座標上で表されることを表しています。Processing での空間上の点は左手系の座標で表されます。一方、高校数学では空間上の点を表すために右手系の座標が利用されます。そのため、それぞれの関数を右手系を基準にして図形を描くように補正しています。これらの詳細は記事『高校数学をプログラミングで解く(準備編)「4-3 Processingでの3次元座標」』で解説していますので、興味のある方は確認してみてください。
本日は以上です。
明日は、空間ベクトルの演算について考えていきます。
明日もよろしくお願いします。
読んだ感想などをお寄せください
本記事を読んだ感想や質問などを以下のお問い合せフォームからお寄せください。(お問合せフォームの本文に、本記事のタイトルを入れてください。)
MK’s papa