グランディの🌹バラを立体的に描く

・　極座標系で花弁を描く
・　Z軸を加える
・　巻き上げる

# グランディの🌹バラ

ルイージ・グイド・グランディ (Luigi Guido Grandi) さんは、17-18世紀の、イタリアの数学者です。グランディさんは、sin 関数や cos 関数を使ってバラを描く研究をしたことで知られています。

<a href = "https://ja.wikipedia.org/wiki/%E3%83%90%E3%83%A9%E6%9B%B2%E7%B7%9A">Wikipedia バラ曲線</a>

<a href = "https://en.wikipedia.org/wiki/Rose_(mathematics)">Grandi's Rose Curves (English Wikipedia)</a>

# 🌹バラを描く
<img width = 480 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333980/844423a7-03d1-1fe5-4821-88a7055806cc.png">

バラじゃないじゃないか、というご意見もあるかと思いますが、まずはここからスタートします。

```MATLAB:Grandi_5
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 のような単純な関数を利用することで丸く持ち上がります。適当に係数を調節していきます。

<img width = 480 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333980/88464385-8af7-e067-3c55-469a7a3e90cf.png">

花弁を作る際には、極座標系で、半径rと角度theta （変数名はt）を利用して、少しずつ原点を中心として回転しながら作ります。面のように見えますが、中身は、原点から花弁のふちまで連続した点を打っていきます。そのため、だんだんと色が薄くなっていると思います。

```MATLAB:rose3D
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軸方向に均等に、同じ高さまで持ち上げる方法に変更します。

<img width = 480 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333980/0a3e491c-5ceb-108c-0cc3-8d11d760f350.png">

```MATLAB:variation1
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) の周り加減の、周波数を変えてみて、花弁を大きくしてみます。

<img width = 480 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333980/997192a8-ffb6-0d21-8534-72fc28eb47b9.png">

下のコードのZ軸にあるように、回転するに従って、上のほうに巻いていくようにします。図では見にくいかもしれせんが、花弁は、f(x) = x ^ 2 の式の一部を使って、ゆるくカーブしています。

```MATLAB:variation2
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 動画にしてみました！　立体感がわかるかと思います。けっこうきれいにできました！

<img width = 480 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333980/45836861-7898-c294-7ba1-6f328709ada1.gif">

ここでまだ、一番端の花弁がちぎれているのを直すとか、だんだんZ軸の上のほうに行くにしたいが、花弁が大きくなってしまっているのを小さくするとか、などなどを適当な関数を使って直してあげる、ということがありますが、今回はここまでにして終わります。

# スピログラフ
<a href = "https://ja.wikipedia.org/wiki/%E3%82%B9%E3%83%94%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%95">スピログラフ (Spirograph)　</a>は、もっとあとになって発明されたもので、子供のときにおもちゃとして使ったことがあるかもしれません。
<br>

<img width = 480 src = "https://upload.wikimedia.org/wikipedia/commons/4/4d/Rose.svg">

実はこれがグランディの🌹バラそのもので、同じ原理を使っています。