n次関数のグラフと接線

2次関数、3次関数のグラフと接線の図を描きます。(もちろん4次以上でも同様にできます)

2次関数のグラフと接線で囲まれる領域

【例1】2次関数のグラフ上の2点A,Bにおける接線が交わる点をPとして、線分AP,BPと放物線で囲まれた部分の面積を求めさせるときの問題図です。

放物線を描くのに,関数のグラフとして plot() (またはKeTCindyのPlotdata() )を使って描く方法と,焦点と準線から放物線を描くツールを使って放物線を描く方法があります。作図ツールを使って描いた放物線は幾何要素となり、点を放物線上に載せて自由に動かすことができます。plot() で描いた場合は放物線上を動かすことはできません。そこで,作図ツールで放物線を描き,その上に点A,Bをとって,A,Bのx座標を用いて接線の方程式を求めるようにします。

まず、「矩形領域を画面サイズに拡大」ツールを使って方眼を少し大きくしておき、「グリッドを細かくする」ツールで目盛も細かくしておくとよいでしょう。次の図は、方眼を0.25 にしています。「直線を加える」ツールで直線 y=-1/4 を描き、「点を加える」ツールで点(0,1/4) をとります。準線と焦点です。

磁石アイコンのスナップツールを使えば、格子点にぴったり合わせることができますが、念のため、「表示」ー「式による表示」で座標を確認しておきましょう。

次に「焦点と準線で決まる放物線」ツールを使って、放物線を描き、「直線を加える」ツールで、放物線上の2点を通る直線を引きます。まず放物線上で左ボタンを押して点Dをとり,そのままドラッグして放物線上の別の点でボタンを離します。描画順序の関係で、名前がA,Bにはなりませんが、かまいません。次の図ではDEになっています。

さらに、点Dを通る直線を適当に引き、このときの作図でできたもう一方の点FとEを結んだ直線を引きます。

これで作図は完了です。あとは、CindyScript を用いてDFが接線になるようにし、Fの座標も決めます。接線は,CindyScript の組み込み関数 d(f(x)) を用いて微分をして接線の方程式を求めます。KeTCindyの微分関数を使うこともできます。

スクリプトは次のようにします。

f(x):=x^2;

g(x):=d(f(#),D.x)*(x-D.x)+D.y;

F.xy=[(D.x+E.x)/2,g((D.x+E.x)/2)];

f(x) が2次関数、g(x)が接線の方程式を表す関数です。

d(f(#),D.x) が Dのx座標における微分係数、すなわち直線の傾きです。

DFとEFが接線のとき、点Fのx座標は (D.x+E.x)/2 です。このことは既知とします。

したがって、「Fは直線DF上でx座標が (D.x+E.x)/2の点」とすればよいわけです。

点D,Eをドラッグしてみましょう。常にDF , EFが接線になるように動くはずです。

では、この図を書き出します。

必要な幾何要素は、2次関数 f(x) のグラフと3本の直線です。点の名前もつけましょう。

Plotdata("1","x^2","x");

Lineplot([D,E]);

Lineplot([D,F]);

Lineplot([E,F]);

Letter([D,"w","A",E,"es","B",F,"e","P"]);

Plotdata() で関数のグラフを描きます。書式は、Plotdata(名前 , 関数式 , 変数名 ) で、すべて文字列とします。名前はどんなものでもかまいません。

Linplot(2点のリスト) で2点を通る直線を描きます。

Letter(位置(点),方向,文字) で点の位置に点の名前を表示します。幾何要素の点と名前が異なっていることに注意してください。

これを追加して実行すると、Cinderellaでは青で表示されていた放物線と直線が黒で上書きされます。

次に斜線です。斜線は Hatchdata() で入れます。Hachdata() の引数は、名前、方向、閉曲線、オプション です

まず、閉曲線から設定します。斜線を引くのは、放物線のDからEまでの部分の下、直線DFの上、直線EFの上です。そこで、「放物線のDからEまでの部分」をプロットデータとして作ります。

Partcrv("1",D,E,"gr1");

プロットデータ名は part1 になります。

こうしておいて「放物線のDからEまでの部分の下、直線DFの上、直線EFの上」は、上下を南北のn,sで表して

[["part1","s"],["lnDF","n"],["lnEF","n"]]

と表現します。

方向は内・外を i ・o で表しますが、先ほど南北で指定した方が内側です。線が3本あるのでそれぞれ内側の iii で指定します。

Hatchdata("1","iii",[["part1","s"],["lnDF","n"],["lnEF","n"]]);

となります。(オプションは略しました)

これで斜線が入って、このページの最初に示した図ができます。

座標軸の設定も含めた全体のコードは次の通りです。

Addax(1);

Setax(["a"]);

f(x):=x^2;

g(x):=d(f(#),D.x)*(x-D.x)+D.y;

F.xy=[(D.x+E.x)/2,g((D.x+E.x)/2)];

Plotdata("1","x^2","x");

Lineplot([D,E]);

Lineplot([D,F]);

Lineplot([E,F]);

Letter([D,"w","A",E,"es","B",F,"e","P"]);

Partcrv("1",D,E,"gr1");

Hatchdata("1","iii",[["part1","s"],["lnDF","n"],["lnEF","n"]]);

KeTCindyで微分する

微分はCindyScriptの組み込み関数 d(f(#),x) でできますが、KeTCindyの関数でもできます。関数 Deffun() を使って関数 f(x) を定義しておき、Derivative() を使います。

先ほどの

f(x):=x^2;

g(x):=d(f(#),D.x)*(x-D.x)+D.y;

F.xy=[(D.x+E.x)/2,g((D.x+E.x)/2)];

Plotdata("h","x^2","x");

の部分を

Deffun("f(x)",["regional(y)","y=x^2","y"]);

coeff=Derivative("f(x)","x",D.x);

g(x):=coeff*(x-D.x)+D.y;

F.xy=[(D.x+E.x)/2,g((D.x+E.x)/2)];

Plotdata("fn","f(x)","x");

に変えます。

3次関数のグラフと接線

3次関数のグラフは、Cinderella の作図ツールでは描けませんので、Cindyscript の plot() 関数,またはKeTCindyの Plotdata() 関数を使ってグラフを描くことになります。このとき、描かれたグラフは幾何要素ではないので、点をこの上に載せる(インシデント)ことはできません。したがって、マウスドラッグでグラフ上を.動かすには、その都度座標を計算することになります。

まず、直線を描くための2点A,Bと,式の表示位置として点Cを適当な位置にとっておき、次のスクリプトを書きます。

Deffun("f(x)",["regional(y)","y=x^3-4*x","y"]);

g(x):=d(f(#),A.x)*(x-A.x)+A.y;

A.y=f(A.x);

B.y=g(B.x);

Plotdata("1","f(x)","x",["Num=200"]);

Lineplot([A,B]);

Expr([C,"e","f(x)=x^3-4x"]);

1行目で3次関数を定義しています。Deffun() を使って定義をすると、内部的には f(x):= を使って定義したのと同じになり、その後は f(x) が使えます。

接戦の傾きは Derivative() で微分係数を求めています。Cindyscript の d(f(#),x) を使うこともできます。

g(x) は点Aにおける接線の方程式です。

Aをグラフ上の点とし、Bを接線上の点として,Lineplot([A,B]) で直線ABが引かれます。

ここで、点A,Bを作図しただけで、直線ABは作図していないことに注意しましょう。

Plotdata() の ["Num=200"] はグラフを描くための点の数をふやして曲線を滑らかにするもので。このオプションがない場合と比較してみましょう。

Expr はTeX書式で文字を表示する関数です。引数はLetter() と同じ形式です。

これで冒頭の図が書き出されます。

点A , B, C を作図せずに、すべてをKeTCindyの関数で行うこともできます。

Deffun("f(x)",["regional(y)","y=x^3-4*x","y"]);

Putpoint("A",[0,f(0)],[A.x,f(A.x)]);

coeff=Derivative("f(x)","x",A.x);

Defvar("Coeff=coeff");

Deffun("g(x)",["regional(y)","y=Coeff*(x-A.x)+A.y","y"]);

Plotdata("1","f(x)","x",["Num=200"]);

Plotdata("2","g(x)","x");

2行目で点Aを作ります。こうすると、あらかじめ点Aを作図しておかなくてもよくなります。点Aは原点(0,f(0))にできますが,ドラッグして動かすことができます。

4行目のDefver() は変数の定義です。変数名がどこかで使われているときにバッティングしないための予防です。

これを使わず、5行目の Coeff を coeff としても、ここでは動きます。

直線の場合は2点だけプロットして結べばよいので、点Bを用意しなくても、7行目の方法で直線が描けます。

点Cは取っていないので,式を表示する位置は座標で指定しています。ただし,この場合,位置を調整するのにいちいち座標を打ち直す必要があります。点Cだけでもとっておいて位置をCとすればインタラクティブに位置決めができます。

接線と3次曲線の交点を求める

スクリプトを前の状態に戻しておきます。点A,Bを作図してから、Lineplot([A,B])で接線を描く方です。

ここで、接線と3次曲線の交点を求めて名前を付けることにします。3次曲線は描画ツールで描いた幾何要素ではないので、描画ツールを用いて交点をとることはできません。交点の座標を計算しなければならないので,CindyScriptでもそう簡単にはできませんが、(方程式の解を求める関数を使えばできます)KETCindyなら Intersectcrvs() 関数を使って比較的簡単にできます。

ここで、プロットデータについての知識がちょっと必要です。

プロットデータとは、円や直線、関数のグラフなどの作図データのことで、それぞれ名前がついています。

Lineplot([A,B]) で直線ABを引くと、その直線は lnAB という名前になります。

Plotdata("1","f(x)","x"); でグラフを描くと、gr1 という名前になります。

この名前は、コンソールに表示されます。

Intersectcrvs() 関数では、このプロットデータの名前を使って交点を求めます。

pt=Intersectcrvs("gr1","lnAB");

println(pt);

とすると,交点の座標のリストが pt に代入されて,println() でコンソールに表示されます。

たとえば,[[1.4,-2.86]] のようになります。交点が複数あればそれらのリストになります。

点 Dを作図しておき

D.xy=pt_1;

とすると,点Dが交点になります。

Deffun("f(x)",["regional(y)","y=x^3-4*x","y"]);

g(x):=d(f(#),A.x)*(x-A.x)+A.y;

A.y=f(A.x);

B.y=g(B.x);

Plotdata("1","f(x)","x",["Num=200"]);

Lineplot([A,B]);

pt=Intersectcrvs("gr1","lnAB");

D.xy=pt_1;

Expr([C,"e","f(x)=x^3-4x",A,"ne","A",D,"se","B"]);

実行結果です。