ギンの備忘録

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

de Jong アトラクターを自動生成しよう

目次

はじめに

p5.jsでde Jong アトラクターを自動生成するコードを書いたので、その使い方を紹介をしていきます。

私がストレンジアトラクターで遊んでいたり、@deconbatch さんとストレンジアトラクターについて語っていたところ、
@KojiSaito さんがJ. C. Sprott氏のストレンジアトラクターに関する論文を発見してくれました。
これによりストレンジアトラクターのパラメータを自動で探索するという道が開けました。

@KojiSaito さんのSprott氏の論文の手法をProcessingで再現している記事があるので、そちらも非常に参考になります。

note.com

note.com

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は定数です。

この4つのパラメータによってストレンジアトラクターの不思議な形が決まります。
パラメータの選択次第で、一点に収束してしまう場合もあります。
不思議な形を形成させるには4つのパラメータをうまく探さなければなりません。

Sprott氏の手法を用いる事で、この4つのパラメータを自動で探索し、良い感じの形を自動生成をしていきます。

de Jong アトラクターの自動生成プログラム

いきなりですがソースコードを示しておきます。

ソースコード

これを実行すれば、de Jong アトラクターの4つのパラメータを自動で探索し、 見つけたパラメータを用いてde Jong アトラクターを描画します。

実行して自動生成されたde Jong アトラクターが下になります。

f:id:gin_graphic:20220318221538p:plain:w300

f:id:gin_graphic:20220318221548p:plain:w300

f:id:gin_graphic:20220318221559p:plain:w300

f:id:gin_graphic:20220318221603p:plain:w300

どうでしょうか。 自動生成によって不思議な形が大量に生成できるようになりました。
いくらでもde Jong アトラクターが作れるので楽しいですね。

使い方

探索失敗閾値

探索失敗となる判定を関数test_res()内でしています。
変数lの値が設定値を下回る場合、探索失敗になります。

  if(n > 100 && l < 0.3){t = 2;}

今回のコードでは0.3としています。

点に収束してしまうものを取り除くことが一つの目的です。
閾値をどうするのが良いというのはなく、設定した値で何度か実行して経験則で決めましょう。
自分が良いと思うものが多く生成できそうな値にすれば良いです。

de Jong アトラクターでは変数lの値がマイナスのものはほとんど収束している印象です。
0.3にした場合は私好みが多いだけです。0.1とかでも十分自動生成して形が形成されると思います。

画像自動保存

変数save_modetrueにすれば、自動でパラメータを探索後に描画を行い、完了した時点で画像を保存します。

let save_mode = false;
ループ

変数loop_modetrueにすれば、パラメータ探索から描画までを繰り返し実行します。

let loop_mode = false;

上の画像自動保存と組み合わせれば、自動生成をループしながら画像も描画毎に保存することができます。
これにより大量の自動生成が可能です。

描画

変数Nに従って描画する点の数が決まります。
描画時の点の密度など好みに合わせて値を変えて下さい。値が大きいと処理時間がかかるため、程々の値が良いかと思います。

let N = 300000;

描画時にランダムに色を指定してます。
好みの色を指定する場合はfill()で色を変えて下さい。

    push();
    blendMode(SOFT_LIGHT);
    fill(random(360), 70, 100);
    stroke(0,0);
    rect(0,0,w,h);
    pop();

関数draw_set_pram()内で、探索した4つのパラメータから決まる値をrandomSeed()でシート値に指定しているので、形毎に色が決まったコードになっています。 実行毎にランダムにしたければ、コメントアウトなどして下さい。

  for(let i=0;i<4;i++){
    sum += A[i]*10000;
  }

  randomSeed( int(sum) );
ID

パラメータは-2.55875から2.55875の間で4095個の値となるようにしています。
これは1つのパラメータを3桁の16進数で表せるようにするためです。
000からFFEになり、4つ並べると12桁のIDで形を示すことができます。
IDはコンソールログに出力されるようにしてます。

  A = [];
  id = '';
  for(let i=0;i<4;i++){
    let a = int(random(4095));
    A[i] = floor(a - 2047)/800;
    id += a.toString(16).padStart(3, '0');
  }

このIDを記録しておくことで、パラメータの数値自体よりも簡単な文字列で記録が取れます。
画像自動保存でのファイル名にこのIDを付加しているので、そのIDからストレンジアトラクターを再現できるようにしています。
このIDの概念はSprott氏の手法をアレンジして導入しています。

4つのパラメータの選択を下の様にもっと精度の高い小数で決めても良いと思います。
この場合選択したパラメータを自分で記録しておけば再現もできるはずです。

    A[i] = random(-1, -1)*PI;

おわりに

Sprott氏の論文の手法を用いたde Jong アトラクターを自動生成するp5.jsのコードを紹介しました。
使い方は記載した通りなので、実行してde Jong アトラクターをたくさん生成して楽しんで下さい。

自動探索の手法の詳細はSprott氏の論文を読んでいただければと思います。
何かわからないことやご指摘点などがあればご連絡下さい。