見出し画像

高校数学をプログラミングで解く(数学B編)「1-5 ベクトル方程式」

マガジンリスト > 数学B編 1.平面上のベクトル > 1-5 ベクトル方程式


はじめに

今回は、数学Bで学ぶ「ベクトル方程式」について、いくつかの直線と円のベクトル方程式に基づいた直線や円を描くプログラムを作成します。

ベクトル方程式

まず、直線および円のベクトル方程式についてまとめておきます。なお、
平面上の点と位置ベクトルを$${\mathrm{A}(\vec{a}), \mathrm{B}(\vec{b}), \mathrm{C}(\vec{c}), \mathrm{P}(\vec{p})}$$($${\mathrm{P}}$$は図形上の点)とします。 

直線のベクトル方程式


$${\mathrm{P}(x,y), \mathrm{A}(x_a,y_a), \vec{d}=(x_d,y_d)}$$とし、$${s,t}$$は実数とします。

① 点$${\mathrm{A}}$$を通り、$${\vec{d}}$$($${\vec{d} \neq \vec{0}}$$)に平行な直線

$$
\vec{p} = \vec{a}+t \vec{d} \ \ \ \ \ \ \ x=x_a+x_d t, \ y=y_a+y_d t
$$

図1 直線のベクトル方程式①

② 異なる2点$${ \mathrm{A}, \mathrm{B} }$$を通る直線

$$
\vec{p} = \vec{a}+t(\vec{b}-\vec{a}) = (1-t)\vec{a}+t\vec{b}
$$

または

$$
\vec{p} = s \vec{a}+t \vec{b} \mathrm{(ただし} s+t=1 \mathrm{)}
$$

図2 直線のベクトル方程式②

③ 点$${\mathrm{A}}$$を通り、$${\vec{n}}$$に垂直な直線

$$
\vec{n} \cdot ( \vec{p}-\vec{a} ) = 0
$$

図3 直線のベクトル方程式③

④ 直線$${ax+by+c=0}$$は$${\vec{n}=(a,b)}$$に垂直。

円のベクトル方程式


① 中心$${\mathrm{C}}$$、半径$${r}$$の円

$$
\left| \vec{p}-\vec{c} \right|=r \ \mathrm{または} \ (\vec{p}-\vec{c}) \cdot (\vec{p}-\vec{c}) = r^2
$$

図4 円のベクトル方程式①

② 線分$${\mathrm{AB}}$$を直径とする円

$$
(\vec{p}-\vec{a}) \cdot (\vec{p}-\vec{b})=0
$$

図5 円のベクトル方程式②

直線のベクトル方程式①の描画

それでは、直線のベクトル方程式①を利用して、実行ウィンドウのキャンバス内いっぱいに直線を描くプログラムを作成していきます。

直線のベクトル方程式①による直線を描く準備

直線のベクトル方程式①はベクトルの成分で表すと、

$$
x=x_a+x_d t, \ y=y_a+y_d t
$$

です。今回、キャンバスいっぱいに直線を描くので、この直線のキャンバス内での両端の座標を求めて、line関数を用いて描きます。
まず、左端の座標$${(x_l, y_l)}$$を求めます。左端なので、$${x_l}$$は、

$$
x_l = -\mathrm{range}
$$

となります。ここで、$${\mathrm{range}}$$は座標系の表示範囲$${-\mathrm{range} \leq x \leq \mathrm{range}}$$の両端の値を表します。$${x_l}$$を与えたので、このときの実数$${t}$$の値は

$$
t_l = \frac{x_l-x_a}{x_d}
$$

で計算することができます。この$${t_l}$$を利用して、$${y_l}$$の値は

$$
y_l = y_a + y_d t_l
$$

で求めることができます。同様に、右端の座標$${(x_r, y_r)}$$も

$$
x_r = \mathrm{range}, \ t_r = \frac{x_r-x_a}{x_d}, \ y_r = y_a + y_d t_r
$$

と求めることができます。

直線のベクトル方程式①による直線を描くプログラム

直線を描く準備ができたので、実際にプログラムを作成していきます。
記事『高校数学をプログラミングで解く(数学B編)「1-0 ベクトルを描く」』で作成したスケッチ「drawVector」をフォルダごとコピーして、スケッチの名前(フォルダ名)を「drawVectorEquation_line1」と変更し、またスケッチ「drawVectorEquation_line1」内の「drawVector.pde」ファイルの名前を「drawVectorEquation_line1.pde」に変更します。そして、pdeファイル「drawVectorEquation_line1.pde」をダブルクリックしてスケッチ「drawVectorEquation_line1」の開発環境ウィンドウを立ち上げます。開発環境ウィンドウのタブ欄で「drawVectorEquation_line1」タブを選択し、そのテキストエリアのソースコードを以下で書き換えます。

// 直線のベクトル方程式①による直線を描く
void setup(){
  size(500,500,P2D);
  noLoop();
  float x_range = 10.0; // x軸の表示範囲 -x_rangeからx_rangeまで
  float y_range = 10.0; // y軸の表示範囲 -y_rangeからy_rangeまで 
  setAxes(x_range, y_range); // 座標軸の準備
  
  // 点Aの位置ベクトル
  PVector a = new PVector(-1.0, 1.0);
  // 直線の方向ベクトル
  PVector d = new PVector(2.0, 1.0);
  
  // 直線の左端の座標を算出する
  float x_l = -x_range;
  float t_l = (x_l - a.x)/d.x;
  float y_l = a.y + d.y * t_l;
  
  // 直線の右端の座標を算出する
  float x_r = x_range;
  float t_r = (x_r - a.x)/d.x;
  float y_r = a.y + d.y * t_r;
    
  // 以下に図形を描いていく
  noFill(); // 中身を塗りつぶさない
  stroke(0,0,0); // 線の色を黒色に設定

  // 座標スケールからキャンバスのスケールに換算するための値
  float scale = width / 2.0 / x_range;

  // 点Aを描く
  strokeWeight(5);
  point(a.x * scale, a.y * scale);
  
  // ベクトルdを描く
  strokeWeight(1);
  arrow(0.0, 0.0, d.x, d.y, x_range);
  
  // 直線を描く(赤色)
  stroke(255,0,0);
  line(x_l * scale, y_l * scale, x_r * scale, y_r * scale);

}

ソースコード1 直線のベクトル方程式①による直線を描くプログラム

なお、点$${\mathrm{A}(-1,1)}$$、方向ベクトル$${\vec{d}=(2,1)}$$としています。また、直線を赤色で描くようにしています。直線を描く際に、直線の両端の座標$${(x_l,y_l)}$$と$${(x_r,y_r)}$$を座標スケールからキャンバスのスケールに変換する必要があることに注意してください。
このスケッチ「drawVectorEquation_line1」を実行すると、図6のように、実行ウィンドウのキャンバスに点$${\mathrm{A}}$$と方向ベクトル$${\vec{d}}$$が黒色で描かれ、直線のベクトル方程式①による直線が赤色で描かれます。

図6 直線のベクトル方程式①による直線

直線のベクトル方程式②の描画

次に、直線のベクトル方程式②を利用して、実行ウィンドウのキャンバス内いっぱいに直線を描くプログラムを作成していきます。

直線のベクトル方程式②による直線を描く準備

直線のベクトル方程式②はベクトルの成分で表すと、

$$
x=x_a+t(x_b-x_a), \ y=y_a+t(y_b-y_a)
$$

です。
直線のベクトル方程式①の時と同様に、この直線のキャンバス内での両端の座標を求めて、line関数を用いて描きます。左端の座標$${(x_l, y_l)}$$は、

$$
x_l = -\mathrm{range}, \ t_l = \frac{x_l-x_a}{x_b-x_a}, \ y_l=y_a+t_l(y_b-y_a)
$$

と求めることができます。同様に、右端の座標$${(x_r, y_r)}$$も

$$
x_r = -\mathrm{range}, \ t_r = \frac{x_r-x_a}{x_b-x_a}, \ y_r=y_a+t_r(y_b-y_a)
$$

と求めることができます。

直線のベクトル方程式②による直線を描くプログラム

直線のベクトル方程式②による直線を描く準備ができたので、実際にプログラムを作成していきます。
今度は、先ほど作成したスケッチ「drawVectorEquation_line1」をフォルダごとコピーして、スケッチの名前(フォルダ名)を「drawVectorEquation_line2」と変更し、またスケッチ「drawVectorEquation_line2」内の「drawVectorEquation_line1.pde」ファイルの名前を「drawVectorEquation_line2.pde」に変更します。そして、pdeファイル「drawVectorEquation_line2.pde」をダブルクリックしてスケッチ「drawVectorEquation_line2」の開発環境ウィンドウを立ち上げます。開発環境ウィンドウのタブ欄で「drawVectorEquation_line2」タブを選択し、そのテキストエリアのソースコードを以下で書き換えます。

// 直線のベクトル方程式②による直線を描く
void setup(){
  size(500,500,P2D);
  noLoop();
  float x_range = 10.0; // x軸の表示範囲 -x_rangeからx_rangeまで
  float y_range = 10.0; // y軸の表示範囲 -y_rangeからy_rangeまで 
  setAxes(x_range, y_range); // 座標軸の準備
  
  // 点Aの位置ベクトル
  PVector a = new PVector(-1.0, 1.0);
  // 点Bの位置ベクトル
  PVector b = new PVector(5.0, 4.0);
  
  // 直線の左端の座標を算出する
  float x_l = -x_range;
  float t_l = (x_l - a.x)/(b.x - a.x);
  float y_l = a.y + t_l * (b.y - a.y);
  
  // 直線の右端の座標を算出する
  float x_r = x_range;
  float t_r = (x_r - a.x)/(b.x - a.x);
  float y_r = a.y + t_r * (b.y - a.y);
    
  // 以下に図形を描いていく
  noFill(); // 中身を塗りつぶさない
  stroke(0,0,0); // 線の色を黒色に設定

  // 座標スケールからキャンバスのスケールに換算するための値
  float scale = width / 2.0 / x_range;

  // 点Aと点Bを描く
  strokeWeight(5);
  point(a.x * scale, a.y * scale);
  point(b.x * scale, b.y * scale);
  
  // 直線を描く(赤色)
  strokeWeight(1);
  stroke(255,0,0);
  line(x_l * scale, y_l * scale, x_r * scale, y_r * scale);

}

ソースコード2 直線のベクトル方程式②による直線を描くプログラム

なお、点$${\mathrm{A}(-1,1)}$$、点$${\mathrm{B}(5,4)}$$としています。
このスケッチ「drawVectorEquation_line2」を実行すると、図7のように、実行ウィンドウのキャンバスに点$${\mathrm{A}}$$と点$${\mathrm{B}}$$が黒色で描かれ、直線のベクトル方程式②による直線が赤色で描かれます。

図7 直線のベクトル方程式②による直線

直線のベクトル方程式③の描画

直線のベクトル方程式③を利用して、実行ウィンドウのキャンバス内いっぱいに直線を描くプログラムを作成していきます。

直線のベクトル方程式③による直線を描く準備

直線のベクトル方程式③はベクトルの成分で表すと、

$$
y=-\frac{x_n}{y_n}(x-x_a)+y_a
$$

です。
直線のベクトル方程式①②の時と同様に、この直線のキャンバス内での両端の座標を求めて、line関数を用いて描きます。左端の座標$${(x_l, y_l)}$$は、

$$
x_l = -\mathrm{range}, \ y_l = -\frac{x_n}{y_n}(x_l-x_a)+y_a
$$

となります。また、右端の座標$${(x_r, y_r)}$$は

$$
x_r = \mathrm{range}, \ y_r = -\frac{x_n}{y_n}(x_r-x_a)+y_a
$$

と求めることができます。

直線のベクトル方程式③による直線を描くプログラム

直線のベクトル方程式③による直線を描く準備ができたので、実際にプログラムを作成していきます。
先ほど作成したスケッチ「drawVectorEquation_line1」をフォルダごとコピーして、スケッチの名前(フォルダ名)を「drawVectorEquation_line3」と変更し、またスケッチ「drawVectorEquation_line3」内の「drawVectorEquation_line1.pde」ファイルの名前を「drawVectorEquation_line3.pde」に変更します。そして、pdeファイル「drawVectorEquation_line3.pde」をダブルクリックしてスケッチ「drawVectorEquation_line3」の開発環境ウィンドウを立ち上げます。開発環境ウィンドウのタブ欄で「drawVectorEquation_line3」タブを選択し、そのテキストエリアのソースコードを以下で書き換えます。

// 直線のベクトル方程式③による直線を描く
void setup(){
  size(500,500,P2D);
  noLoop();
  float x_range = 10.0; // x軸の表示範囲 -x_rangeからx_rangeまで
  float y_range = 10.0; // y軸の表示範囲 -y_rangeからy_rangeまで 
  setAxes(x_range, y_range); // 座標軸の準備
  
  // 点Aの位置ベクトル
  PVector a = new PVector(-1.0, 1.0);
  // 直線に垂直なベクトル
  PVector n = new PVector(-1.0, 2.0);
  
  // 直線の左端の座標を算出する
  float x_l = -x_range;
  float y_l = a.y - n.x / n.y * (x_l - a.x);
  
  // 直線の右端の座標を算出する
  float x_r = x_range;
  float y_r = a.y - n.x / n.y * (x_r - a.x);
  
  // 以下に図形を描いていく
  noFill(); // 中身を塗りつぶさない
  stroke(0,0,0); // 線の色を黒色に設定

  // 座標スケールからキャンバスのスケールに換算するための値
  float scale = width / 2.0 / x_range;

  // 点Aを描く
  strokeWeight(5);
  point(a.x * scale, a.y * scale);
  
  // ベクトルnを描く
  strokeWeight(1);
  arrow(0.0, 0.0, n.x, n.y, x_range);
  
  // 直線を描く(赤色)
  stroke(255,0,0);
  line(x_l * scale, y_l * scale, x_r * scale, y_r * scale);

}

ソースコード3 直線のベクトル方程式③による直線を描くプログラム

なお、点$${\mathrm{A}(-1,1)}$$、方向ベクトル$${\vec{n}=(-1,2)}$$としています。
このスケッチ「drawVectorEquation_line3」を実行すると、図8のように、実行ウィンドウのキャンバスに点$${\mathrm{A}}$$と方向ベクトル$${\vec{n}}$$が黒色で描かれ、直線のベクトル方程式③による直線が赤色で描かれます。

図8 直線のベクトル方程式③による直線

円のベクトル方程式①の描画

今度は、円のベクトル方程式①を利用して、実行ウィンドウのキャンバス上に円を描くプログラムを作成していきます。

円のベクトル方程式①による円を描く準備

円のベクトル方程式①はベクトルの成分で表すと、

$$
(x-x_c)^2+(y-y_c)^2=r^2
$$

となります。これは円の方程式そのものですので、circle関数を用いてそのまま描くことができます。

円のベクトル方程式①による円を描くプログラム

円のベクトル方程式①による円を描く準備ができたので、実際にプログラムを作成していきます。
先ほど作成したスケッチ「drawVectorEquation_line1」をフォルダごとコピーして、スケッチの名前(フォルダ名)を「drawVectorEquation_circle1」と変更し、またスケッチ「drawVectorEquation_circle1」内の「drawVectorEquation_line1.pde」ファイルの名前を「drawVectorEquation_circle1.pde」に変更します。そして、pdeファイル「drawVectorEquation_circle1.pde」をダブルクリックしてスケッチ「drawVectorEquation_circle1」の開発環境ウィンドウを立ち上げます。開発環境ウィンドウのタブ欄で「drawVectorEquation_circle1」タブを選択し、そのテキストエリアのソースコードを以下で書き換えます。

// 円のベクトル方程式①による円を描く
void setup(){
  size(500,500,P2D);
  noLoop();
  float x_range = 10.0; // x軸の表示範囲 -x_rangeからx_rangeまで
  float y_range = 10.0; // y軸の表示範囲 -y_rangeからy_rangeまで 
  setAxes(x_range, y_range); // 座標軸の準備
  
  // 点Cの位置ベクトル
  PVector c = new PVector(3.0, 3.0);
  // 円の半径r
  float r = 5.0;
    
  // 以下に図形を描いていく
  noFill(); // 中身を塗りつぶさない
  stroke(0,0,0); // 線の色を黒色に設定

  // 座標スケールからキャンバスのスケールに換算するための値
  float scale = width / 2.0 / x_range;

  // 点Cを描く
  strokeWeight(5);
  point(c.x * scale, c.y * scale);
  
  // 円を描く(赤色)
  strokeWeight(1);
  stroke(255,0,0);
  circle(c.x * scale, c.y * scale, 2.0 * r * scale);

}

ソースコード4 円のベクトル方程式①による円を描くプログラム

なお、点$${\mathrm{C}(3,3)}$$、半径$${r=5}$$としています。
このスケッチ「drawVectorEquation_circle1」を実行すると、図9のように、実行ウィンドウのキャンバスに円の中心$${\mathrm{C}}$$が黒色で描かれ、円のベクトル方程式①による円が赤色で描かれます。

図9 円のベクトル方程式①による円

円のベクトル方程式②の描画

最後に、円のベクトル方程式②を利用して、実行ウィンドウのキャンバス上に円を描くプログラムを作成していきます。

円のベクトル方程式②による円を描く準備

円のベクトル方程式②$${(\vec{p}-\vec{a}) \cdot (\vec{p}-\vec{b})=0}$$は、式変形していくと、

$$
\left( \vec{p}-\frac{\vec{a}+\vec{b}}{2} \right) \cdot \left( \vec{p}-\frac{\vec{a}+\vec{b}}{2} \right)=\frac{ \left| \vec{a}-\vec{b} \right|^2 }{4}
$$

となります。つまり、この方程式②は、中心が

$$
\left( \frac{x_a+x_b}{2}, \frac{y_a+y_b}{2} \right)
$$

で、半径が

$$
\frac{\sqrt{(x_a-x_b)^2+(y_a-y_b)^2}}{2}
$$

の円を描くことがわかります。

円のベクトル方程式②による円を描くプログラム

円のベクトル方程式②による円を描く準備ができたので、実際にプログラムを作成していきます。
先ほど作成したスケッチ「drawVectorEquation_circle1」をフォルダごとコピーして、スケッチの名前(フォルダ名)を「drawVectorEquation_circle2」と変更し、またスケッチ「drawVectorEquation_circle2」内の「drawVectorEquation_circle1.pde」ファイルの名前を「drawVectorEquation_circle2.pde」に変更します。そして、pdeファイル「drawVectorEquation_circle2.pde」をダブルクリックしてスケッチ「drawVectorEquation_circle2」の開発環境ウィンドウを立ち上げます。開発環境ウィンドウのタブ欄で「drawVectorEquation_circle2」タブを選択し、そのテキストエリアのソースコードを以下で書き換えます。

// 円のベクトル方程式②による円を描く
void setup(){
  size(500,500,P2D);
  noLoop();
  float x_range = 10.0; // x軸の表示範囲 -x_rangeからx_rangeまで
  float y_range = 10.0; // y軸の表示範囲 -y_rangeからy_rangeまで 
  setAxes(x_range, y_range); // 座標軸の準備
  
  // 点Aの位置ベクトル
  PVector a = new PVector(-1.0, 0.0);
  // 点Bの位置ベクトル
  PVector b = new PVector(7.0, 6.0);
  
  // 円の中心Cの位置ベクトル
  PVector c = a.copy().add(b.copy()).mult(0.5);
  // 円の半径r
  float r = a.copy().sub(b.copy()).mult(0.5).mag();
    
  // 以下に図形を描いていく
  noFill(); // 中身を塗りつぶさない
  stroke(0,0,0); // 線の色を黒色に設定

  // 座標スケールからキャンバスのスケールに換算するための値
  float scale = width / 2.0 / x_range;

  // 点A,Bを描く
  strokeWeight(5);
  point(a.x * scale, a.y * scale);
  point(b.x * scale, b.y * scale);

  // 円の中心Cと円を描く(赤色)
  stroke(255,0,0);
  point(c.x * scale, c.y * scale);
  strokeWeight(1);
  circle(c.x * scale, c.y * scale, 2.0 * r * scale);

}

ソースコード5 円のベクトル方程式②による円を描くプログラム

なお、点$${\mathrm{A}(-1,0)}$$、$${\mathrm{B}(7,6)}$$としています。
このスケッチ「drawVectorEquation_circle2」を実行すると、図10のように、実行ウィンドウのキャンバスに2点$${\mathrm{A}}$$と$${\mathrm{B}}$$が黒色で描かれ、円のベクトル方程式②による円とその中心位置が赤色で描かれます。

図10 円のベクトル方程式②による円

まとめ

今回は、数学Bで学ぶ「ベクトル方程式」について、いくつかの直線と円のベクトル方程式に基づいた直線や円を描くプログラムを作成しました。
直線や円は、line関数やcircle関数を用いて描きました。そのため、ベクトル方程式をベクトルの成分$${\vec{p}=(x,y)}$$を用いて書き直して考えました。図形を描く際は、ベクトル表記よりもベクトルの成分で表した方が便利なことが多いので、互いに変換できるようになっておくことをお勧めします。
なお、今回作成した直線を描くプログラムはいずれも$${y}$$軸と平行な直線を描くことができない状態になっています。このような直線も描くことができるようにプログラムを修正してみてください。

参考文献

改訂版 教科書傍用 スタンダード 数学B(数研出版、ISBN9784410209468)


この記事が気に入ったらサポートをしてみませんか?