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次のベジェ曲線も追加することもできるでしょう。