・ 極座標系で花弁を描く
・ Z軸を加える
・ 巻き上げる
グランディの🌹バラ
ルイージ・グイド・グランディ (Luigi Guido Grandi) さんは、17-18世紀の、イタリアの数学者です。グランディさんは、sin 関数や cos 関数を使ってバラを描く研究をしたことで知られています。
Grandi's Rose Curves (English Wikipedia)
🌹バラを描く
バラじゃないじゃないか、というご意見もあるかと思いますが、まずはここからスタートします。
clear;
a = 3;
k = 5;
t = 0:.01:2*pi;
r = a*cos(k*t);
figure;
plot(r.*cos(t), r.*sin(t), '.');
axis equal;
axis off;
言語はMATLABです。他の言語でも、ほぼ同じ書き方になると思いますが、変数 r や、変数 t は一次元の行列です。また、.* は、行列の要素を順番に掛けてくれるもので、行列を一度に演算する際には短いコードで書けますね。
花弁を持ち上げます
次に、適当なZ軸の関数を加えて花弁を持ち上げていきます。Z軸に、f(x) = x^2 のような単純な関数を利用することで丸く持ち上がります。適当に係数を調節していきます。
花弁を作る際には、極座標系で、半径rと角度theta (変数名はt)を利用して、少しずつ原点を中心として回転しながら作ります。面のように見えますが、中身は、原点から花弁のふちまで連続した点を打っていきます。そのため、だんだんと色が薄くなっていると思います。
clear;
close all;
a = 3;
k = 5;
t = 0:.01:2 * pi;
rmax = a*cos(k*t);
xmax = rmax.*cos(t);
ymax = rmax.*sin(t);
v = [xmax; ymax];
v = v';
figure;
hold on;
plot(rmax.*cos(t), rmax.*sin(t), '.');
for k = 1:length(t)
theta = t(k);
r = [0: .001: 1];
x = v(k,1) * r;
y = v(k,2) *r;
z = x.^2 /(a * 3);
plot3(x, y, z, '-b');
end
axis off;
im = getframe(gcf);
imwrite(im.cdata, 'flat.png', 'png');
% change view manually
ax=gca;
ax.View = [-2.1580 70.7664];
均等に持ち上げる
このままでも自然な花の感じがしてよいのですが、このあと🌹バラの花にするためには、花弁を広くして、巻き上げるほうがいいですね。巻き上げる際に、徐々にZ軸を上げていかないといけないので、まずはZ軸方向に均等に、同じ高さまで持ち上げる方法に変更します。
figure;
hold on;
plot(rmax.*cos(t), rmax.*sin(t), '.');
for k = 1:length(t)
theta = t(k);
r = [0: .001: 1];
x = v(k,1) * r;
y = v(k,2) *r;
d = hypot(x, y);
z = d.^2 /(a * 3);
plot3(x, y, z, '-b');
end
axis off;
% change view manually
ax=gca;
ax.View = [-2.1580 70.7664];
巻き上げる
バラじゃないじゃん、という指摘もあると思いますので、少しだけ手を加えてみます。中心角 theta (変数名はt) の周り加減の、周波数を変えてみて、花弁を大きくしてみます。
下のコードのZ軸にあるように、回転するに従って、上のほうに巻いていくようにします。図では見にくいかもしれせんが、花弁は、f(x) = x ^ 2 の式の一部を使って、ゆるくカーブしています。
clear;
close all;
a = 3;
k = 1.8;
t = 0:.01:9*pi/k;
rmax = a*cos(k*t);
xmax = rmax.*cos(t);
ymax = rmax.*sin(t);
v = [xmax; ymax];
v = v';
figure;
hold on;
plot(rmax.*cos(t), rmax.*sin(t), '.');
for k = 1:length(t)
theta = t(k);
r = [0: .001: 1];
x = v(k,1) * r;
y = v(k,2) *r;
d = hypot(x, y);
z = d.^2 /(a * 2 + theta);
plot3(x, y, z, '-b');
end
plot3(xmax, ymax, hypot(xmax, ymax).^2./(a * 2 + t),'.m')
axis off;
% change view manually
ax=gca;
ax.View = [-2.1580 70.7664];
違う角度から見せたいので、gif 動画にしてみました! 立体感がわかるかと思います。けっこうきれいにできました!
ここでまだ、一番端の花弁がちぎれているのを直すとか、だんだんZ軸の上のほうに行くにしたいが、花弁が大きくなってしまっているのを小さくするとか、などなどを適当な関数を使って直してあげる、ということがありますが、今回はここまでにして終わります。
スピログラフ
スピログラフ (Spirograph) は、もっとあとになって発明されたもので、子供のときにおもちゃとして使ったことがあるかもしれません。
実はこれがグランディの🌹バラそのもので、同じ原理を使っています。