見出し画像

高校数学をプログラミングで解く(数学III編)「2-1 放物線」

割引あり

マガジンリスト > 数学Ⅲ編 2.式と曲線 > 2-1 放物線


はじめに

今回は、数学IIIで学ぶ「放物線」について、放物線を描くプログラムを作成します。

放物線

まず、放物線について解説します。

定義

定点$${\mathrm{F}}$$と、$${\mathrm{F}}$$を通らない定直線$${l}$$からの距離が等しい点$${P}$$の軌跡を 放物線 といい、点$${\mathrm{F}}$$をその 焦点 、直線$${l}$$を 準線 という。

図1 放物線

x軸を軸とする放物線

$${y^2 = 4px \ \ (p \neq 0)}$$

[1] 頂点は原点、焦点は点$${(p,0)}$$、準線は直線$${x=-p}$$
[2] 軸は$${x}$$軸で、放物線は軸に関して対称である。

y軸を軸とする放物線

$${x^2 = 4qy \ \ (q \neq 0)}$$

[1] 頂点は原点、焦点は点$${(0,q)}$$、準線は直線$${y=-q}$$
[2] 軸は$${y}$$軸で、放物線は軸に関して対称である。

放物線を描く

では、放物線を描くプログラムを作成していきます。

問題
次の条件を満たす点$${\mathrm{P}}$$の軌跡を求め、座標上に描け。
(1) 点$${\mathrm{A}(3,0)}$$と直線$${x=-3}$$から等距離にある点$${\mathrm{P}}$$
(2) 点$${\mathrm{A}(4,4)}$$と$${x}$$軸から等距離にある点$${\mathrm{P}}$$

アルゴリズム設計

まず、今回の問題に対する軌跡の方程式を求めてみます。
問題(1)は、$${x}$$軸を軸とする放物線となりますので、

$$
y^2= 4 \cdot 3 x = 12 x
$$

と表すことができます。
問題(2)は、少し計算が必要です。点$${\mathrm{P}}$$の座標を$${(x,y)}$$とすると、点$${\mathrm{P}}$$は点$${\mathrm{A}(4,4)}$$と$${x}$$軸から等距離にあるので、

$$
\sqrt{(x-4)^2+(y-4)^2} = |y|
$$

と式で表すことができます。そして両辺を二乗して整理すると、

$$
(x-4)^2 = 8(y-2)
$$

となります。この放物線は焦点が$${(0,2)}$$、準線が$${y=-2}$$の放物線を$${x}$$軸方向に$${4}$$、$${y}$$軸方向に$${2}$$だけ平行移動したものになっていることがわかります。

$${x}$$軸、$${y}$$軸を軸とする放物線の平行移動
問題(2)の結果を見ると、$${x}$$軸を軸とする放物線$${y^2 = 4px}$$や$${y}$$軸を軸とする放物線$${x^2 = 4qy}$$は、それらの平行移動も含めた形で考えた方がよさそうです。そこで、放物線を$${x}$$軸方向に$${a}$$、$${y}$$軸方向に$${b}$$だけ平行移動したものとして、$${x}$$軸を軸とする放物線を

$$
(y-b)^2 = 4p(x-a) \ \ \ \ \ \ \ \ x = \frac{1}{4p} (y-b)^2+a 
$$

(頂点$${(a,b)}$$、焦点$${(p+a,b)}$$、準線$${x=-p+a}$$)とし、また、$${y}$$軸を軸とする放物線を

$$
(x-a)^2 = 4q(y-b) \ \ \ \ \ \ \ \ y = \frac{1}{4q} (x-a)^2 + b
$$

(頂点$${(a,b)}$$、焦点$${(a,q+b)}$$、準線$${y=-q+b}$$)と考えることにします。

プログラム

では、$${x}$$軸、$${y}$$軸を軸とする放物線を描くプログラムを作成していきます。
グラフを描くので、記事『高校数学をプログラミングで解く(数学I編)「1-0-2 グラフを描くための準備(その2)」』で準備した座標軸を描く関数 setAxes を利用します。以下の zip ファイルをダウンロードして展開または解凍してください。

そして、スケッチの名前(フォルダ名)を「draw_parabola」と変更し、またスケッチ「draw_parabola」内の「drawFunction.pde」ファイルの名前を「draw_parabola.pde」に変更します。そして、pdeファイル「draw_parabola.pde」をダブルクリックしてスケッチ「draw_parabola」の開発環境ウィンドウを立ち上げます。そして、開発環境ウィンドウのタブ欄で「draw_parabola」タブを選択して、そのテキストエリアのソースコードを以下のソースコード1に書き換えます。

float x_range = 10.0; // x軸の表示範囲 -x_rangeからx_rangeまで
float y_range = 10.0; // y軸の表示範囲 -y_rangeからy_rangeまで 

void setup(){
  size(500,500);
  noLoop();

  setAxes(x_range, y_range); // 座標軸の準備
  
  noFill();
  stroke(0,0,0);
  
  // (1) 
  float p = 3.0;
  float a = 0.0;
  float b = 0.0;
  stroke(255,0,0);
  draw_parabola_x_axis(p,a,b);
 
  // (2)
  float q = 2.0;
  a = 4.0;
  b = 2.0;
  stroke(0,0,255);
  draw_parabola_y_axis(q,a,b);
 
}

// x軸を軸とする放物線を描く関数
void draw_parabola_x_axis(
  float p, // 焦点(p,0)、準線x=-p
  float a, // x軸方向の平行移動
  float b  // y軸方向の平行移動
){
  // グラフの定義域
  float y_min = -y_range;
  float y_max = y_range;
  int plot_num = 200; // グラフを描くための頂点の個数  
  
  // グラフを描画
  float x, y; // 関数の座標
  float X, Y; // キャンバス上の座標 
  beginShape();
  for(int i=0; i<=plot_num; i++){
    y = y_min + (y_max - y_min) / plot_num * i; // 放物線上の点のy座標
    x = (y-b)*(y-b)/4.0/p+a; // 放物線上の点のx座標
    // キャンバス上の座標位置に換算
    X = width / 2.0 / x_range * x;
    Y = height / 2.0 / y_range * y;
    vertex(X, Y);
  }
  endShape();
  
  // 焦点をプロット
  x = p + a;
  y = b;
  plot_point(x,y);
  
  // 準線を描く
  x = -p + a;
  X = width / 2.0 / x_range * x;
  line(X, -height/2.0, X, height);
  
}  

// y軸を軸とする放物線を描く関数
void draw_parabola_y_axis(
  float q, // 焦点(0,q)、準線x=-q
  float a, // x軸方向の平行移動
  float b  // y軸方向の平行移動
){
  // グラフの定義域
  float x_min = -x_range;
  float x_max = x_range;
  int plot_num = 200; // グラフを描くための頂点の個数  
  
  // グラフを描画
  float x, y; // 関数の座標
  float X, Y; // キャンバス上の座標 
  beginShape();
  for(int i=0; i<=plot_num; i++){
    x = x_min + (x_max - x_min) / plot_num * i; // 放物線上の点のx座標
    y = (x-a)*(x-a)/4.0/q+b; // 放物線上の点のy座標
    // キャンバス上の座標位置に換算
    X = width / 2.0 / x_range * x;
    Y = height / 2.0 / y_range * y;
    vertex(X, Y);
  }
  endShape();
  
  // 焦点をプロット
  x = a;
  y = q + b;
  plot_point(x,y);
  
  // 準線を描く
  y = -q + b;
  Y = height / 2.0 / y_range * y;
  line(-width/2.0, Y, width/2.0, Y);
  
}

// 座標(x,y)に点をプロットする関数
void plot_point(
  float x, // 点のx座標
  float y  // 点のy座標
){
  float X, Y; // キャンバス上の座標
  // キャンバス上の座標位置に換算
  X = width / 2.0 / x_range * x;
  Y = height / 2.0 / y_range * y;
  strokeWeight(5);
  point(X, Y);
  strokeWeight(1);
}

ソースコード1 $${x}$$軸、$${y}$$軸を軸とする放物線を描くプログラム

ソースコード1では、$${x}$$軸を軸とする放物線$${y^2=4px}$$を$${x}$$軸方向に$${a}$$、$${y}$$軸方向に$${b}$$だけ平行移動したものを描く関数 draw_parabola_x_axis と$${y}$$軸を軸とする放物線$${x^2=4qy}$$を$${x}$$軸方向に$${a}$$、$${y}$$軸方向に$${b}$$だけ平行移動したものを描く関数 draw_parabola_y_axis の2つの関数を準備して利用しました。また、それぞれの関数は放物線の焦点と準線を描くようにしています。

「draw_parabola」タブのテキストエリアをソースコード1に書き換えて、スケッチ「draw_parabola」を実行すると、図2のように、実行ウィンドウのキャンバス上に問題(1)の放物線が赤色、問題(2)の放物線が青色で描かれます。

図2 放物線の描画

一般的な放物線の軌跡を描く

上記の問題では、$${x}$$軸、$${y}$$軸を軸とする放物線を扱いましたが、今度は、より一般的な放物線の軌跡を考えてみます。つまり、焦点を$${\mathrm{F}(p,q)}$$、準線$${l}$$を直線$${ax+by+c=0}$$とする放物線の軌跡を考えます。

問題2
焦点$${(1,1)}$$、準線$${x+y+4=0}$$とする放物線の軌跡を描け。

アルゴリズム設計

一般的な放物線の方程式
放物線の定義から一般的な放物線の方程式を導きます。放物線上の点を$${\mathrm{P}(x,y)}$$とすると、点$${\mathrm{P}}$$と準線$${l}$$との距離は、

$$
\frac{|ax+by+c|}{\sqrt{a^2+b^2}}
$$

となります。一方、点{\mathrm{F}}と点$${\mathrm{P}}$$との距離は

$$
\sqrt{ (x-p)^2+(y-q)^2 }
$$

となります。したがって、一般的な放物線の方程式は

$$
\frac{|ax+by+c|}{\sqrt{a^2+b^2}} = \sqrt{ (x-p)^2+(y-q)^2 }
$$

となります。

一般的な放物線の軌跡を描く
この一般的な放物線の軌跡を描くにあたり、記事『高校数学をプログラミングで解く(数学II編)「2-5 軌跡と方程式」』で解説した方法を利用します。
つまり、$${xy}$$平面の描画範囲内の任意の点$${(x,y)}$$を取ってきて、その点が放物線の方程式を満たすかどうかを確かめ、方程式を満たしていればその点をキャンバス上の$${xy}$$平面にプロットし、方程式を満たしていなければプロットしないというルールで行います。そして、プロットされた点が描く軌跡が放物線になっているかを確認します。なお、記事『高校数学をプログラミングで解く(数学III編)「1-4 複素数と図形(1)」』で作成したスケッチ「drawTrajectory_complex」でも同様の方法を利用しているので、そちらの解説も確認してみてください。

プログラム

先程作成したスケッチ「draw_parabola」を再利用します。
スケッチ「draw_parabola」をフォルダごとコピーして、スケッチの名前(フォルダ名)を「draw_parabola_general」と変更し、またスケッチ「draw_parabola_general」内の「draw_parabola.pde」ファイルの名前を「draw_parabola_general.pde」に変更します。そして、pdeファイル「draw_parabola_general.pde」をダブルクリックしてスケッチ「draw_parabola_general」の開発環境ウィンドウを立ち上げます。

問題2の一般的な放物線の軌跡を描くプログラムを作成していきます。

// 放物線の方程式を満たす点が描く図形
float x_range = 10.0; // x軸の表示範囲 -x_rangeからx_rangeまで
float y_range = 10.0; // y軸の表示範囲 -y_rangeからy_rangeまで 

void setup(){
  size(500,500,P2D); // widthとheightは同じにしておく
  noLoop();

  setAxes(x_range, y_range); // 座標軸の準備
  
  noFill(); // グラフの中身を塗りつぶさない
  stroke(0,0,0); // グラフの線の色を黒色に設定
  
  // 点の生成回数
  int n = 1000000;
  // マージン
  float e = 0.001;
 
  // 焦点の座標
  float p = 1.0;
  float q = 1.0;
  
  // 準線を表す直線の方程式の係数
  float a = 1.0;
  float b = 1.0;
  float c = 4.0;
  
  float x, y; // 任意の点の座標
  float lhs, rhs; // 左辺と右辺の値
  for(int i=0; i<n; i++){
    // 任意の複素数を生成
    x = random(-x_range, x_range);
    y = random(-y_range, y_range);
    
    // (x,y)が放物線の方程式を満たせばプロット
    stroke(255,0,0);
    lhs = abs(a*x+b*y+c)/sqrt(a*a+b*b);
    rhs = sqrt((x-p)*(x-p)+(y-q)*(y-q));
    if( abs(lhs-rhs) < e ){
      plot_point(x,y);
    }    
  }
  
  // 焦点をプロット
  stroke(0,0,255);
  plot_point(p,q);
  
  // 準線を描く
  float y_l = -a/b * (-x_range) -c/b;
  float Y_l = height / 2.0 / y_range * y_l;
  float y_r = -a/b * (x_range) -c/b;
  float Y_r = height / 2.0 / y_range * y_r;
  line(-width/2.0, Y_l, width/2.0, Y_r);
  
}

// 座標(x,y)に点をプロットする関数
void plot_point(
  float x, // 点のx座標
  float y  // 点のy座標
){
  float X, Y; // キャンバス上の座標
  // キャンバス上の座標位置に換算
  X = width / 2.0 / x_range * x;
  Y = height / 2.0 / y_range * y;
  strokeWeight(5);
  point(X, Y);
  strokeWeight(1);
}

ソースコード2 一般的な放物線の軌跡を描くプログラム

スケッチ「draw_parabola_general」の「draw_parabola_general」タブを選択してそのテキストエディタ部分をソースコード2で書き換えて実行すると、図3のように、実行ウィンドウのキャンバスの$${xy}$$平面上に、問題2の一般的な放物線の方程式の軌跡が赤色、放物線の焦点と準線がそれぞれ青色で描かれます。

図3 一般的な放物線の描画

まとめ

今回は、数学IIIで学ぶ「放物線」について、放物線を描くプログラムを2つ作成しました。
1つ目は、$${x}$$軸、$${y}$$軸を軸とする放物線を描くプログラムを作成しました。プログラムでは、$${x}$$軸を軸とする放物線を描く関数 draw_parabola_x_axis と$${y}$$軸を軸とする放物線を描く関数 draw_parabola_y_axis を放物線の平行移動も考慮する形で準備しました。
2つ目は、準線が任意の直線の場合に放物線の定義から導かれる方程式の軌跡を描くプログラムを作成しました。こちらについては、$${xy}$$平面上の任意の点を取ってきて方程式を満たせば、$${xy}$$平面上にプロットするという方法を取りました。もちろん、1つ目のプログラムのように、一般的な放物線の方程式を用いて直接描くこともできます。ただ、少し工夫が必要になってきます。たとえば、一般的な放物線の方程式

$$
\frac{|ax+by+c|}{\sqrt{a^2+b^2}} = \sqrt{ (x-p)^2+(y-q)^2 }
$$

を$${y}$$の2次方程式と考えて解くと、その2つの解が

$$
y = f(x) + g(x), \ \ y = f(x) - g(x)
$$

と、$${x}$$の関数として得られます。これら2つの関数を描いていくことで一般的な放物線を描くことができます。ちょっと大変かもしれませんが、一度チャレンジしてみてください。

参考文献

改訂版 教科書傍用 スタンダード・オリジナル 数学III(数研出版、ISBN9784410209567)


演習問題

次の条件を満たす点$${\mathrm{P}}$$の軌跡を求め、その軌跡を座標上に描くプログラムを作成してください。
(1) 直線$${x=5}$$に接し、点$${(-5,0)}$$を通る円の中心$${\mathrm{P}}$$
(2) $${x}$$軸に接し、円$${x^2+(y-5)^2=1}$$に外接する円の中心$${\mathrm{P}}$$


演習問題の解答例

ここから先は

248字 / 1画像 / 1ファイル

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