F01 ベジェ曲線

4点を与えて,3次のベジェ曲線を描きます。

まずは,「GeoGebra日本」の「GeoGebra実例」「F01 ベジェ曲線」にならって書いてみましょう。ただし,次の点を変えます。

GeoGebra実例では,AB上に点Eをとり,この点を駆動点としてAからBまで動かし,その位置で0から1までの数 t を決めて次々に点を定義し,最終的にツール化しています。Cinderellaでは同じ方法で軌跡は描けないので,点EをABの内分点として E=t*A+(1-t)B とし,このtで他の点を定義し,最終的に J に相当する関数を定義して,この関数のグラフを 0≦t≦1 の範囲で描くことにします。

bezier(list):=(

pa=list_1;

pb=list_2;

pc=list_3;

pd=list_4;

f1(t):=(1-t)*pb+t*pc;

f2(t):=(1-t)*pc+t*pd;

f3(t):=(1-t)*(t*pb+(1-t)*pa)+t*f1(t);

f4(t):=(1-t)*f1(t)+t*f2(t);

f5(t):=(1-t)*f3(t)+t*f4(t);

plot(f5(t),stop->1,steps->100);

);

bezier([A.xy,B.xy,C.xy,D.xy]);

少し補足をします。

引数の list は,点の座標のリストです。したがって,fn(t) はすべて媒介変数 t で表された式になります。

plot() 関数は,媒介変数表示のときは,デフォルトでは定義域を 0≦t で描きます。したがって,終値の stop->1 だけ指定すればよいのです。また,steps->100 はプロットする点の数の指定です。デフォルトのままでは,きれいな曲線にならないことがあります。

さて,f1(t) から f4(t) を順にあとの方の式に代入していくと,結局 f5(t) は

(1-t)^3A+3(1-t)^2tB+3t^2(1-t)C+t^3D

になることがわかるでしょう。これが3次のベジェ曲線の式です。

したがって,一度にこの式で定義してしまうことができます。

bezier2(list):=(

pa=list_1;

pb=list_2;

pc=list_3;

pd=list_4;

bz(t):=(1-t)^3*pa+3*t*(1-t)^2*pb+3*t^2*(1-t)*pc+t^3*pd;

plot(bz(t),stop->1,steps->100);

);

bz(t) を定義せず,直接 plot() の式に書いてしまうこともできます。

plot((1-t)^3*pa+3*t*(1-t)^2*pb+3*t^2*(1-t)*pc+t^3*pd,stop->1,steps->100);

それならば,引数の数に応じて,2次または3次のベジェ曲線にすることもできそうですね。

これをここでは完成形としましょう。

bezier(list):=(

pa=list_1;

pb=list_2;

pc=list_3;

if(length(list)==3,

plot((1-t)^2*pa+2*t*(1-t)*pb+t^2*pc,stop->1,steps->100);

);

if(length(list)==4,

pd=list_4;

plot((1-t)^3*pa+3*t*(1-t)^2*pb+3*t^2*(1-t)*pc+t^3*pd,stop->1,steps->100);

);

);

さらに,4次のベジェ曲線も追加することもできるでしょう。