見出し画像

Processing.pyでアート #11 VectorField

今回は、deconbatchさんのベクター・フィールドをpythonモードでやってみました。

作例はこんな感じ。

ベクトル場の生成には、以前のシェーダーを使った作品

で利用した、行列積&非線形変換による複雑な模様生成器を再利用。描画される線の流れが途中でカクっと変わる様になりました。

コードは以下です。

def setup():
   size(400, 400, P2D)
   pixelDensity(displayDensity()) # retinaディスプレイのための呪文
   smooth()
   colorMode(HSB, 360, 100, 100, 100)
   blendMode(SCREEN)
   
def draw():
   noiseSeed(long(random(1e6))) # noiseSeedの引数はlong型なので注意

   step = 0.002
   stepNum = 500
   gridNum = 50

   h = random(360)
   noFill()
   stroke(h, 50, 10, 50)
   background(0)

   for i in range(gridNum):
       for j in range(gridNum):
           x = map(i, 0, gridNum-1, 0, 1)
           y = map(j, 0, gridNum-1, 0, 1)
                   
           for k in range(stepNum):
               v, th = field(x, y) # 関数が多値を返せる
               v *= step
               v += step*0.1
               th = atan2(y-0.5, x-0.5) + th*PI
               
               x += v*cos(th)
               y += v*sin(th)
               
               strokeWeight(map(k, 0, stepNum, 1, 3))
               point(map(x, 0, 1, 0, width), map(y, 0, 1, 0, height))
   
   saveFrame("frames/####.png")
   if frameCount == 200:
       noLoop() 
   
def field(x, y): # ベクターフィールド (x, y成分ではなく大きさと角度として使う)
   r, th, _ = tr(*tr(*tr(abs(x-0.5), abs(y-0.5), 1))) # *でタプルのアンパック
   return r, th

def mat(i, j): # 以下のtr()で使う乱数
   return 2*noise(i, j)-1.

def act(x): # 以下のtr()で使う非線形関数
   return (3*noise(frameCount*0.1)*x)%1

def tr(a, b, c): # なにかややこしい変換 (行列演算&非線形変換)
   x = act(mat(0, 0) * a + mat(1, 0) * b + mat(2, 0) * c)
   y = act(mat(0, 1) * a + mat(1, 1) * b + mat(2, 1) * c)
   z = act(mat(0, 2) * a + mat(1, 2) * b + mat(2, 2) * c)    
   return x, y, z

3つの引数を取って3つの値を返す変換関数tr(a, b, c)を繰り返し使うことで、ベクトル場を用意。

pythonの関数は多値が返せるので便利... なのですが、関数の戻り値は実際にはタプルなので、「3つ値を返す関数」を「3つ変数を取る関数」の引数部分に書くには、* でタプルを展開(アンパック)する必要があります。コードの中では以下の部分。

r, th, _ = tr(*tr(*tr(abs(x-0.5), abs(y-0.5), 1))) # *でタプルのアンパック

ちなみに上の行は「なんかややこしいことにな〜れ」くらいの気持ちで書いてます。

ベクター・フィールドは、ベクトル場を作る数式(私のコードだとact()をいじると印象が大きく変化)を変えたり、線の密度や太さや色を変えたりでさらにいろいろ遊べます。...楽しい!


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