アラカン"BOKU"のITな日常

文系システムエンジニアの”BOKU”が勉強したこと、経験したこと、日々思うことを書いてます。

Pythonでグラフィックス:「花びらを描く(花びら曲線)」処理を実装してみました。

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)と、デフォルトの描画サンプルです。

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()

これを実行すると、こんな感じの花びらが描けます。 

 

f:id:arakan_no_boku:20181126005815j:plain

これが基本形です。

あとは「draw_flower()」のパラメータを変えていくと、色んな花びらになります。

なお。

上記でタイトルを日本語で表示してますが、matplotlibはデフォルトでは日本語表示できませんので、上記と同じように表示するには、以下の記事で紹介した方法で日本語化が必要です。

arakan-pgm-ai.hatenablog.com

 

さて、いろいろとやってみます。

 

まず、花びらの数だけ30枚にしてみます。

x,y = draw_flower(a=30)

 するとこうなります。

f:id:arakan_no_boku:20181130202249j:plain

突起の数をひとつ(つまり花びらにくぼみを作らない)にしてみます。

x,y = draw_flower(a=30,n=1.0)

すると、とてもプレーンな花びらになります。

f:id:arakan_no_boku:20181130212845j:plain

上記を引き継いで、今度は突起の数を5つにします。

x,y = draw_flower(a=30,n=5) 

すると、こんな感じ。

f:id:arakan_no_boku:20181130202554j:plain

今度は、n(突起の数)をデフォルトにして、k1(花びらの切れ込み)とk2(突起の切れ込み)を大きくしてみます。

x,y = draw_flower(a=30,k1=0.9,k2=0.7) 

するとこんな感じ。

f:id:arakan_no_boku:20181130212107j:plain

こうやって、パラメータを変更しながら、どんな形になるのか想像して、実際にやってみるというのは、結構な暇つぶしになります。

 

ちょっとビックリするのが、bのパラメータを動かしたとき

 

b以外のパラメータは、結果が、なんとなく予想できます。

でも、bのパラメータは予測不能です。

なので、ほとんど変更しないのですが、試しにやってみます。

まず、bだけを、うんと大きく「30」くらいにしてみます。

x,y = draw_flower(b=30.0)

なんとビックリ(笑)

f:id:arakan_no_boku:20181130213235j:plain

花じゃないし・・。

じゃあ、100.0 くらいにしたらどうかな。

x,y = draw_flower(b=100.0)

どんどん花から離れていきます。

f:id:arakan_no_boku:20181130213603j:plain

でも、bでも3.0くらいなら、まだ花です。

x,y = draw_flower(b=3.0)

こんな風。

f:id:arakan_no_boku:20181130214254j:plain

x,y = draw_flower(b=4.0)

4.0なら、ぎりぎり・・・。

f:id:arakan_no_boku:20181130214524j:plain

x,y = draw_flower(b=5.0)

5.0になると・・終わった(笑)

f:id:arakan_no_boku:20181130214742j:plain

まあ、こんな感じで。

暇つぶしのおもちゃにはもってこいです。

ではでは。