見出し画像

Processing でグラフを描く⑤ バラ曲線

Processing でグラフを描く 第5回目です。
私がこのシリーズを書き始めた理由は、この「バラ曲線」を描いてみたいと思ったからでした。極座標で描かれる素敵な曲線は、きっと読者の皆様も気に入ってくださると思います。

バラ曲線

バラ曲線は正葉曲線とも呼ばれます。基本の定義式は極座標で

$$
r = a sin{\frac{n}{m}\theta}
$$

で表されます。このシンプルな式から描かれる、美しいグラフを見ていきましょう。

sin の周期の変化を捉える

BACKGROUND_COLOR = color(0, 44, 77)
colors = [
    [255, 255, 255],  # white
    [255, 127, 0],  # orange
    [255, 0, 255],  # magenta
    [127, 127, 255],  # lightblue
    [255, 255, 0],  # yellow
    [0, 255, 0],  # lime
    [255, 127, 127],  # pink
    [127, 127, 127],  # gray
    [191, 191, 191],  # lightgray
    [0, 255, 255],  # cyan
    [127, 0, 127],  # purple
    [0, 0, 255],  # blue
    [127, 0, 0],  # brown
    [0, 127, 0],  # green
    [255, 0, 0],  # red
    [0, 0, 0],  # black
]
SIZE = 1000
STEP = 50
RADIUS = 300
points = []
PERIODS = [1.0 / 5, 1.0 / 4, 1.0 / 3, 1.0 / 2, 1, 2, 3, 4, 5]
sin_wave = [sin(radians(i)) for i in range(360)]


def setup():
    global points
    size(SIZE, SIZE)

def draw():
    background(BACKGROUND_COLOR)
    noFill()
    strokeWeight(2)
    stroke(0, 255, 0, 50)
    for i in range(int(SIZE / STEP)):
        line(-2000, i * STEP, 2000, i * STEP)
        line(i * STEP, -2000, i * STEP, 2000)
    pushMatrix()
    translate(width / 2, height / 2)
    stroke(0, 255, 0)
    line(-2000, 0, 2000, 0)
    line(0, -2000, 0, 2000)
    # グラフを描く
    p_length = len(sin_wave)
    # sin波
    count = min(frameCount - 1, 360 * 5)
    for j, p in enumerate(PERIODS):
        stroke(colors[j][0], colors[j][1], colors[j][2])
        for i in range(count):
            x1 = radians(i) / float(p) * STEP
            y1 = sin_wave[i % p_length] * RADIUS
            x2 = radians(i + 1) / float(p) * STEP
            y2 = sin_wave[(i + 1) % p_length] * RADIUS
            line(x1, y1, x2, y2)
    popMatrix()
sin wave

バラ曲線を描く準備として、まず周期を変化させて、sin波を描きます。9本のグラフを描いたので少し見づらいですが、黄色が基本形 $${y = a sin{\theta}}$$ です。この曲線を基準に見ると理解しやすくなります。
次にライム(明るい緑) $${y = a sin{2 \theta}}$$ を見ると、基本形が1回往復するごとに2回往復していることが確認できます。$${\theta}$$ の係数が1より大きいとき、周期は早くなります。
ライトブルー $${y = a sin{\frac{\theta}{2}}}$$ を見ると、基本形が2往復するごとに1回往復していることが見て取れます。$${\theta}$$ の係数が1より小さいとき、周期は遅くなります。
そのほかの色も基本形と見比べて、周期の変化をつかんでおいてください。

バラ曲線(n = 1, m = 5)

def draw():
    background(BACKGROUND_COLOR)
    noFill()
    strokeWeight(2)
    pushMatrix()
    # translate(50, height / 2)
    translate(width / 2, height / 2)
    stroke(0, 255, 0, 50)
    for i in range(0, 360, 15):
        line(0, 0, 1000 * cos(radians(i)), 1000 * sin(radians(i)))
    for i in range(1, 1000, STEP):
        ellipse(0, 0, i * 2, i * 2)
    stroke(0, 255, 0)
    line(-2000, 0, 2000, 0)
    line(0, -2000, 0, 2000)
    # グラフを描く
    p_length = len(sin_wave)
    # バラ曲線
    j = 0
    p = PERIODS[j]
    if p < 1:
        count1 = min(frameCount - 1, 360)
    else:
        count1 = min(frameCount - 1, int(360 * p))
    stroke(colors[0][0], colors[0][1], colors[0][2], 100)
    line(
        0,
        0,
        1000 * cos(radians(count1) / float(p)),
        -1000 * sin(radians(count1) / float(p))
    )
    stroke(colors[0][0], colors[0][1], colors[0][2], 50)
    line(
        -1000 * cos(radians(count1) / float(p)),
        1000 * sin(radians(count1) / float(p)),
        0,
        0
    )
    fill(colors[j][0], colors[j][1], colors[j][2])
    stroke(colors[j][0], colors[j][1], colors[j][2])
    for i in range(count1):
        r1 = sin_wave[i % p_length] * RADIUS
        x1 = r1 * cos(radians(i) / float(p))
        y1 = r1 * sin(radians(i) / float(p))
        r2 = sin_wave[(i + 1) % p_length] * RADIUS
        x2 = r2 * cos(radians(i + 1) / float(p))
        y2 = r2 * sin(radians(i + 1) / float(p))
        line(x1, -y1, x2, -y2)
    else:
        r1 = sin_wave[i % p_length] * RADIUS
        x1 = r1 * cos(radians(i) / float(p))
        y1 = r1 * sin(radians(i) / float(p))
        ellipse(x1, -y1, 10, 10)
    popMatrix()
rose curve n=1 m= 5

バラ曲線(n = 1, m = 5)のグラフです。
先ほど描いたsin波と見比べてください。sin波はx方向(横)に移動していきますが、バラ曲線は回転しながらプロットしていきます(点を繋いでいく)。補助線(薄い白)を追いかけると、プロットする様子がよくわかります。
n = 1, m = 5 のとき、$${\theta}$$ の係数は 0.2 となります。基本形 $${y = sin{\theta}}$$ が5回往復するごとに、$${y = sin{\frac{\theta}{5}}}$$ は1回往復します。補助線に注目すると、2回重ねて線を描いていることが見て取れます。

バラ曲線(n = 1, m = 4)


# バラ曲線
j = 1
rose curve n=1 m=4

コードの修正箇所は、j = 1 に変更するだけです。n = 1, m =4 のときは、先ほどのグラフ(n=1, m=5)をy軸で鏡像反転したような図形になりました。線の重なりはありません。

バラ曲線(n = 1, m = 3)


# バラ曲線
j = 2
rose curve n=1 m=3

n = 1, m = 3 のとき、お尻のような形になりました(笑)。私の大好きな「マンデルブロ集合」というフラクタル図形があるのですが、その一部に似ているように見えます。

バラ曲線(n = 1, m = 2)

# バラ曲線
j = 3
rose curve n=1 m=2

n = 1, m = 2 のとき、先ほどのグラフ(n=1, m=3)をy軸で鏡像反転したような図形になりました。

バラ曲線(n = 1, m = 1)

# バラ曲線
j = 4
rose curve n=1 m=1

n = 1, m = 1 のとき、円が一つ現れました。この図形はかなり「円」に近いように見えますが、似ているだけかもしれません。数式から確認してみましょう。

$$
r = a sin(\theta)\\
r = \sqrt{x^2 + y^2}\\
sin(\theta) = \frac{y}{\sqrt{x^2 + y^2}} より\\
x^2 + (y - \frac{a}{2})^2 = (\frac{a}{2})^2\\
$$

つまり、グラフは、中心(0, $${\frac{a}{2}}$$) 半径 $${\frac{a}{2}}$$ の円であることが証明できた。

バラ曲線(n = 2, m = 1)

# バラ曲線
j = 5
rose curve n=2 m=1

n = 2, m = 1 のとき、やっと花びらが現れましたね。花びらの数が4枚で「四葉のクローバー」のようです。ここからは n の値と花びらの枚数について注意してみていきます。n = 3 のときは何枚になると思いますか?

バラ曲線(n = 3, m = 1)

# バラ曲線
j = 6
rose curve n=3 m=1

n = 3, m = 1 のとき、花びらの数が3枚になりました。グラフをよく見てください。プロット線は6枚の花びらを描いています。しかし4枚目以降は線をなぞる位置を通るため、3枚しか描かれていません。
つまり m の数が奇数のときは $${ m}$$ 枚の花びら、m の数が偶数のときは $${ 2 m}$$ 枚の花びらが描かれるということです。n > 3 で成り立つか、確認します。

バラ曲線(n = 4, m = 1)

# バラ曲線
j = 7
rose curve n=4 m=1

n = 4, m = 1 のとき、8枚の花びらが現れました。ちゃんと 2 m 枚になっています。バラ関数の中に正弦関数(sin)が含まれているために、なめらかに花びらが描かれていきます。何度見ていても楽しめますね。美しい図形です。

バラ曲線(n = 5, m = 1)

# バラ曲線
j = 8
rose curve n=5 m=1

最後のグラフになりました。n = 5, m = 1 のとき、5枚の花びらが現れました。本当は10枚描いているのですが、重ねて線を描いているため、5枚しか現れないのは、n = 3 のときと同じです。

9種類のバラ曲線を描いてきました。楽しいですね。一日中遊んでいられそうです。n ,m の別の値のときは、どんな図形が現れるでしょうか。ぜひご自分のパソコンで確かめてみてください。


前の記事
Processing でグラフを描く④ 極座標(螺旋と2次曲線)
次の記事
Processing でグラフを描く⑥ バラ曲線とジェネラティブアート

その他のタイトルはこちら


この記事が気に入ったらサポートをしてみませんか?