Pythonで「花びら曲線」を実装してみました。
1992年頃(古いなあ)の「Turbo C グラフィックス入門」(絶版です)という本のC言語のソースを移植したものです。
まずは仕様です
関数のパラメータは5つです。
名前が、a,b,n,k1,k2 といい加減ですけど、そこはご勘弁を。
あと、サンプルとして見づらくなるので、パラメータに対するエラーチェックは特にいれてません。
a | 花びらの枚数の基本数です。3.0以上で適当に。 |
b | 基本、2.0固定です。1.0にすると「2×a」が花びらの枚数となります。bが3.0以上になると、どんどん予測できない形になっていきます。 |
n | 1枚の花びらのなかにある突起の数です。1.0以上で適当に。 |
k1 | 花びらと花びらの間の切れ込みの深さです。値が大きいと、切れ込みが深くなりますが、0.1~0.9の範囲でないとどうなるかわかりません。 |
k2 | 花びら1枚の中での突起と突起の間の切れ込みの深さです。値が大きいと切れ込みが深くなります。0.1~0.9の範囲でないとどうなるかわかりません。 |
これらのパラメータの値を変更していくと、花びらの形がどんどん変化していくので、なかなか面白いです。
ソースコードとちょっとだけ解説です。
まず、花びら関数(deaw_flower)と、デフォルトの描画サンプルです。
gr_plt_flower.py
import random import matplotlib.pyplot as plt import numpy as np def draw_flower(a=5.0, b=2.0, n=2.0, k1=0.7, k2=0.3): tx = [] ty = [] k = 0 if(int(b % 2.0) == 0): k = 1 else: k = 2 for ang in np.arange(0.0, 180.0 * k * b + 1.0, 1.0): s = ang * (np.pi / 180.0) r = ((1.0 - k1) + k1 * np.fabs(np.sin(a / b * s))) * \ ((1.0 - k2) + k2 * np.fabs(np.sin(n * a / b * s))) tx.append(100.0 * r * np.cos(s)) ty.append((100.0 * r * np.sin(s)) * -1.0) return tx, ty x, y = draw_flower() plt.plot(x, y) plt.title('花びら関数') plt.show()
これを実行すると、こんな感じの花びらが描けます。
これが基本形です。
あとは「draw_flower()」のパラメータを変えていくと、色んな花びらになります。
なお。
上記でタイトルを日本語で表示してますが、matplotlibはデフォルトでは日本語表示できませんので、上記と同じように表示するには、以下の記事で紹介した方法で日本語化が必要です。
さて、いろいろとやってみます。
まず、花びらの数だけ30枚にしてみます。
x,y = draw_flower(a=30)
するとこうなります。
突起の数をひとつ(つまり花びらにくぼみを作らない)にしてみます。
x,y = draw_flower(a=30,n=1.0)
すると、とてもプレーンな花びらになります。
上記を引き継いで、今度は突起の数を5つにします。
x,y = draw_flower(a=30,n=5)
すると、こんな感じ。
今度は、n(突起の数)をデフォルトにして、k1(花びらの切れ込み)とk2(突起の切れ込み)を大きくしてみます。
x,y = draw_flower(a=30,k1=0.9,k2=0.7)
するとこんな感じ。
こうやって、パラメータを変更しながら、どんな形になるのか想像して、実際にやってみるというのは、結構な暇つぶしになります。
ちょっとビックリするのが、bのパラメータを動かしたとき
b以外のパラメータは、結果が、なんとなく予想できます。
でも、bのパラメータは予測不能です。
なので、ほとんど変更しないのですが、試しにやってみます。
まず、bだけを、うんと大きく「30」くらいにしてみます。
x,y = draw_flower(b=30.0)
なんとビックリ(笑)
花じゃないし・・。
じゃあ、100.0 くらいにしたらどうかな。
x,y = draw_flower(b=100.0)
どんどん花から離れていきます。
でも、bでも3.0くらいなら、まだ花です。
x,y = draw_flower(b=3.0)
こんな風。
x,y = draw_flower(b=4.0)
4.0なら、ぎりぎり・・・。
x,y = draw_flower(b=5.0)
5.0になると・・終わった(笑)
まあ、こんな感じで。
暇つぶしのおもちゃにはもってこいです。
ではでは。