見出し画像

高校数学10分プログラミング(数学B編 2.空間のベクトル)9日目「平面の方程式を考える」

マガジンリスト > 数学B編 2.空間のベクトル > 9日目 課題

おはようございます。

本日は、高校数学10分プログラミング(数学B編 2.空間のベクトル)の9日目です。

本日の課題は、平面の方程式を用いて平面を描くプログラムを作成することです。


空間における平面の方程式

$${\vec{n}=(a,b,c) \neq \vec{0}}$$、平面上の任意の点を$${\mathrm{P}(x,y,z)}$$、また$${\mathrm{A}(x_1,y_1,z_1)}$$とします。
① 点$${\mathrm{A}}$$を通り、$${\vec{n}}$$に垂直な平面($${\overrightarrow{\mathrm{OP}}=\vec{p}, \overrightarrow{\mathrm{OA}}=\vec{a}}$$とします。)

$$
\vec{n} \cdot \overrightarrow{\mathrm{AP}}=0 \\  \\ \vec{n} \cdot (\vec{p}-\vec{a})=0 \\  \\ a(x-x_1)+b(y-y_1)+c(z-z_1)=0
$$

② 一般形

$$
ax+by+cz+d=0
$$

は平面を表し、法線ベクトルは$${\vec{n}=(a,b,c)}$$となる。


課題

点$${\mathrm{A}(1,1,1)}$$を通り、ベクトル$${\vec{n}=(1,2,1)}$$に垂直な平面の方程式を求めて、その平面を空間上に描くプログラムを作成してください。


ヒント

今回の課題の点$${\mathrm{A}(x_1,y_1,z_1)}$$を通り、ベクトル$${\vec{n}=(a,b,c)}$$に垂直な平面の方程式を求めて、その平面を空間上に描く手順は以下のようにします。

① 平面の方程式を求めます。平面上の任意の点を$${\mathrm{P}(x,y,z)}$$とすると、空間における平面の方程式①から

$$
a(x-x_1)+b(y-y_1)+c(z-z_1)=0
$$

となり、この方程式を空間における平面の方程式②一般形に書き直すと、

$$
ax+by+cz+d  = 0, \ \ \ \ d = -(ax_1+by_1+cz_1)
$$

となります。ここからもう少し変形して、

$$
z = \alpha x + \beta y + \gamma, \ \ \ \ \alpha = -\frac{a}{c}, \ \ \beta = -\frac{b}{c}, \ \ \gamma = -\frac{d}{c}
$$

としておきます。

② 課題の平面を描く方法として、今回は、平面を小さな点を平面上に並べることで表現することにします。こうする理由は、空間上に浮かんでいる平面を表すために、少し透過した形で表現するためです。
具体的には、$${xy}$$平面上の領域(今回は$${-\mathrm{range}/2 \leq x, y \leq \mathrm{range}/2}$$)に等間隔に碁盤目状に点を並べて(今回は$${100 \times 100}$$)、それぞれの点$${(x,y)}$$に対して先ほど求めた平面の方程式$${z = \alpha x + \beta y + \gamma}$$から$${z}$$の値を求めて、その空間の座標$${(x,y,z)}$$をプロットしていくことで実現していきます。


プログラム

今回の課題の平面の方程式を用いて平面を描くプログラムをスケッチ「drawPlane」として準備しました。以下の zip ファイルをダウンロードして展開または解凍してご利用ください。

展開または解凍して得られるスケッチ「drawPlane」の中のpdeファイル「drawPlane.pde」をダブルクリックしてスケッチ「drawPlane」の開発環境ウィンドウを立ち上げます。開発環境ウィンドウのタブ欄で「drawPlane」タブを選択すると、そのテキストエリアに以下のソースコードが書かれています。


// 平面を描く

float range; // 座標系での表示範囲-range≦x,y.z≦range
float res; // 座標系のサイズをキャンバスのサイズに変換するパラメータ
float angle = 0.0;

PVector a1; // 平面が通る点Aの座標
PVector n; // 平面の法線ベクトル

void setup(){
  size(400, 400, P3D);
  noFill();
  ortho();
  range = 10.0; 
  res = width / 2.0 / range;
  
  // 課題の点Aの座標と法線ベクトルn
  a1 = new PVector(1.0, 1.0, 1.0);
  n = new PVector(1.0, 2.0, 1.0);
    
}

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);
  // 以下に、図形を描いていく

  float a,b,c,d; // 平面の方程式の一般形の係数
  float alpha, beta, gamma; // 一般形をz= αx+βy+γの形にした時の係数

  // 平面上の点を表す座標
  PVector plane_point = new PVector(0.0,0.0,0.0);
  // 平面を点群で表わすときの各軸方向に並べる点の数
  int plot_num = 100;
  // 図形を描く範囲
  float m_range = -range/2.0;
  float p_range = range/2.0;

  // 課題の平面(黄色)
  // 平面のパラメータ
  a = n.x;
  b = n.y;
  c = n.z;
  d = 
  alpha = -a/c;
  beta = -b/c;
  gamma = -d/c;

  // 点Aをプロットする
  strokeWeight(5);
  stroke(255,255,0);
  fill(255,255,0);
  point_rhs(a1.copy().mult(res));

  // 法線ベクトルを描く
  strokeWeight(1);
  arrow3D(a1.x*res,a1.y*res,a1.z*res,(n.x+a1.x)*res,(n.y+a1.y)*res,(n.z+a1.z)*res); 
  
  // 平面を描画
  stroke(255,255,0);
  for(int i=0; i<plot_num; i++){
    for(int j=0; j<plot_num; j++){
      plane_point.x = m_range + i*(p_range-m_range)/plot_num;
      plane_point.y = m_range + j*(p_range-m_range)/plot_num;
      plane_point.z = 
      point_rhs(plane_point.copy().mult(res)); 
    }
  }

}

ソースコード1 平面の方程式を用いて平面を描くプログラム(未完成)

このソースコード1の draw 関数内の平面の方程式$${ax+by+cz+d=0}$$のパラメータ$${d}$$を表す変数 d の式

  // 平面のパラメータ
  a = n.x;
  b = n.y;
  c = n.z;
  d = 

と、平面上の点の$${z}$$座標を表す変数 plane_point.z の部分

      plane_point.x = m_range + i*(p_range-m_range)/plot_num;
      plane_point.y = m_range + j*(p_range-m_range)/plot_num;
      plane_point.z = 

は未完成です。ヒントに沿って各値を記述してプログラムを完成させてください。


それでは、よろしくお願いします。

MK's papa

いいなと思ったら応援しよう!