ギンの備忘録

デジタルアートやプログラミングやテクノロジー関連のこと。

歪なde Jong アトラクターの描き方(ストレンジアトラクターとフローフィールドを組み合わせる)

f:id:gin_graphic:20220305181113p:plain:w400

目次

はじめに

私は普段のクリエイティブコーディングでの制作でストレンジアトラクターやフローフィールドを描いたりしています。
この2つは割と数学寄りのアルゴリズムで個人的には作るのが好きな系統です。
ただ、ストレンジアトラクターは特定の数式で決まっている振る舞いを可視化しているため、
想定外の絵を生成するわけではないので、ジェネラティブアートとは言い難いのかなと思っています。

ストレンジアトラクターを上手くジェネラティブアートに昇華させる方法はないかなと考えてところ、
ストレンジアトラクターとフローフィールドを組み合わせるアイデアを思いつきました。

そこで今回、ストレンジアトラクターとフローフィールドを組み合わせることで、歪なde Jong アトラクターを描く方法を共有したいと思います。

De Jong アトラクター

今回説明するのにde Jong アトラクターを使います。
de Jong アトラクターはストレンジアトラクターの一種です。

アトラクターとはなにか?ストレンジアトラクターとはなにか?という話になります。
ここでは難しい説明は割愛しておきます。

簡単に言えば、アトラクターに分類される特殊な数式の振る舞いを描いたとき、不思議な形になるものがストレンジアトラクターです。

de Jong アトラクターは下の式にしたがったアトラクターです。

x_n+1 = sin(a*y_n) - cos(b*x_n)
y_n+1 = sin(c*x_n) - cos(d*y_n)

a, b, c, dは定数です。描く際に値を設定して描画します。

  let a = -1.4;
  let b = 1.4;
  let c = 1.7;
  let d = -1.4;

として、de Jong アトラクターを描いてみると下の様になります。

ソースコード

f:id:gin_graphic:20220305122931p:plain:w400

4つのパラメータを変えて、描画を楽しんだりできます。

フローフィールド

位置毎に流れる方向、大きさが異なる場のことで、ベクトル場のことを指します。
ある座標位置(x, y)にいる点が、動く方向とどのくらい移動するかがフローフィールドによって決まります。

      x += cos(TAU*noise(x*1.2, y*1.5, 0.2))*0.01;
      y += sin(TAU*noise(x*1.5, y*1.2, 0.3))*0.01;

としてパーリンノイズを用いたフローフィールドを描画すると下の様になります。

ソースコード

f:id:gin_graphic:20220305122935p:plain:w400

ランダムに選択した座標位置からフローフィールドにしたがって移動させながら点を描画します。
それを何度も繰り返すことでフローフィールドによってできる流れが可視化されます。

ストレンジアトラクターとフローフィールドを組み合わせる

ここからアトラクターとフローフィールドを組み合わせていきます。

de Jong アトラクターは上で紹介したものをそのまま用います。

フローフィールドはアトラクターへの変化量を調整したり、パーリンノイズの入力を設定しやすいように変数を用いて下の様にしてみました。

  let noise_input_x = [0.8, 0.9, 0.5];
  let noise_input_y = [0.9, 0.8, 0.6];
  let noise_weight = 0.25;

      dx += cos(TAU*noise(x*noise_input_x[0], y*noise_input_x[1], noise_input_x[2])) * noise_weight;
      dy += sin(TAU*noise(x*noise_input_y[0], y*noise_input_y[1], noise_input_y[2])) * noise_weight;

組み合わせる方法はシンプルで、ある座標位置(x, y)でde Jongアトラクターに従って、移動先の座標位置(dx, dy)を計算します。
その移動先の座標位置(dx, dy)に対して、フローフィールドでの移動量を足し込んで上げるだけです。

コードでいうと下の部分の処理になります。

      let dx = sin(y*a) + cos(x*b);
      let dy = sin(x*c) + cos(y*d);

      dx += cos(TAU*noise(x*noise_input_x[0], y*noise_input_x[1], noise_input_x[2])) * noise_weight;
      dy += sin(TAU*noise(x*noise_input_y[0], y*noise_input_y[1], noise_input_y[2])) * noise_weight;

これを実行すると下の様になります。

ソースコード

f:id:gin_graphic:20220305134954p:plain:w400

はじめにみたde Jong アトラクターが歪んだ形になりました。 パーリンノイズを用いているので、実行する度に形が変わります。

f:id:gin_graphic:20220305134951p:plain:w400

f:id:gin_graphic:20220305135003p:plain:w400

f:id:gin_graphic:20220305134957p:plain:w400

アトラクターの式やパラメータ、フローフィールドの式やパラメータの組み合わせができるため、非常に多くのバリエーションが作れるのではないでしょうか。
色々な式やパラメータを試すと楽しいと思います。

あとは色を着けてみても綺麗な形で楽しめます。

ソースコード

f:id:gin_graphic:20220305175250p:plain:w400

f:id:gin_graphic:20220305175254p:plain:w400

おわりに

ストレンジアトラクターとフローフィールドを組み合わせる方法を紹介しました。
今回は歪なde Jong アトラクターを描いてみました。
紹介したコードのパラメータを変えるだけでも楽しめますし、別のストレンジアトラクターやフローフィールドで組み合わせ方を変えても面白いと思います。

楽しいと思うので遊んでみてください。

ストレンジアトラクターに限らず数式などで決まった描画をするものに、フローフィールドでパーリンノイズなどのジェネラティブな要素を組み込むことができるはずです。
適用できそうなアルゴリズムがあれば是非試してみてください。