LoginSignup
0
0

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

Last updated at Posted at 2023-12-20

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

グランディの🌹バラ

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

Wikipedia バラ曲線

Grandi's Rose Curves (English Wikipedia)

🌹バラを描く

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

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

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

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

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

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

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

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

スピログラフ

スピログラフ (Spirograph) は、もっとあとになって発明されたもので、子供のときにおもちゃとして使ったことがあるかもしれません。

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

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0