見出し画像

Processing.pyでアート #2 de Jong Attractor

せっかくpythonモードなので、なにかpythonっぽいことがしたい!
そんなわけでde Jongアトラクタです。

 de Jong Attractor

x, y = sin(a*y) - cos(b*x), sin(c*x) - cos(d*y)

de Jongアトラクタは、上記の漸化式にしたがって点を打つことで描けるパターンです。詳しくはFALさんdeconbatchさんが書いているので、そちらをどうぞ!

ジェネレータ

で、この「漸化式をもとに次々に点を生成する」って部分が、pythonモードだとジェネレータを使ってこんなふうに書けるのです。

def deJongAttractor(a, b, c, d):
    x, y = random(1), random(1)

    while True:
        x, y = sin(a*y) - cos(b*x), sin(c*x) - cos(d*y)

        yield x, y

return のかわりに yield で値を返すことで、呼び出されるたびに次々に値を返すジェネレータができるのです。カッコイイ!もとい、便利!

ただ、このジェネレータは無限に点を生み出し続けるので、呼び出し側で回数を決めて呼び出す必要があります。

だったらforループでいいじゃないか、という気もしますが、ジェネレータはひとつのオブジェクトなので、グローバル変数にして何度も使えるのが強み。Processingのdraw()関数で各フレーム1万点描画して、次のフレームでは前のフレームの続きから描画、みたいなことができます。

Processing.pyでde Jong Attractor

あとは多分、以下の実際のコードを見てもらうのが早いかもです。
乱数生成の部分に手を入れたので、deJongAttractor()の実装は上の例とはちょっと違います。

def setup():
    size(360, 360)
    colorMode(HSB, 360, 100, 100, 100)
    blendMode(ADD)
    pixelDensity(displayDensity()) # retinaディスプレイ対応
    reset()

def reset():
    background(0)

    # グローバル変数を作る時はglobalで宣言する必要あり
    global attractor, dot_color
    attractor  = deJongAttractor()
    dot_color = color(random(360), 100, 100, 10)

def draw():
    # 背景色を半透明にして重ねることで、昔の点を薄くしていく
    noStroke()
    fill(0, 20)
    rect(0, 0, width, height)
    
    # 点の描画
    translate(width/2, height/2)
    stroke(dot_color)
    strokeWeight(1./displayDensity())
    for i, (x, y) in enumerate(attractor):
        point(x*width/4, y*height/4)
        
        if i == 5e4:
            break
        
    print frameCount
    
def deJongAttractor():
    
    # 乱数の取り方をこうするとレアキャラの排出率が上がる気がする
    from random import choice
    a, b, c, d, x, y = [choice([random(-2, -1), random(1, 2)]) for _ in range(6)]

    while True:
        # 複数変数への同時代入便利...!
        x, y = sin(a*y) - cos(b*x), sin(c*x) - cos(d*y)
        yield x, y

# ガチャを引き直したり、お気に入りの結果を保存したりする
def keyPressed():    
    if key == 'r': reset()
    if key == 's': saveFrame("####.png")

keyPressed()関数を使って、"r"を押すたびに違うアトラクタを生成するので、"r"連打でde Jongアトラクタガチャを引くことができます。
このガチャはなんと無料なので、レアキャラ(面白いパターン)が出るまで何度でもトライできますよ!


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