仮想計算機構

IT業界と無縁な派遣社員のブログ

ボグダノフ写像の可視化


ボグダノフ写像は以下で定義されます。



x_{n+1}=x_n+y_{n+1}\\
y_{n+1}=y_n+\epsilon y_n + kx_n(x_n-1)+\mu x_ny_n

シミュレーション

Wikipediaにならってパラメータを

\mu=\epsilon=0\\
k=1.2
に設定しました。

下記の範囲に点を20x20=400個配置し、各点の軌跡を描画します。

‐0.8 < x < 0.8\\
‐0.8 < y < 0.8

結果は以下のとおりです。

f:id:riverta1992:20201130113433p:plain

プログラム

<html>
    <body>
        <script type="text/javascript" src="bogdanov.js"></script>
    </body>
</html>

/* Bogdanov Map */
const WIDTH = 600;
const HEIGHT = 600;

const canvas = document.createElement('canvas');
canvas.width = WIDTH;
canvas.height = HEIGHT;

const context = canvas.getContext('2d');

document.body.appendChild(canvas);

class Point{
    constructor(id, x, y){
        this.id = id;
        this.x = x;
        this.y = y;
    }
    update(){
       let new_y = this.y +1.2*this.x*(this.x-1);
       let new_x = this.x+new_y;

       this.x = new_x;
       this.y = new_y;
    }
    render(context,xmin,xmax,ymin,ymax){
        context.beginPath();
        context.fillStyle = "gray";
        context.fillRect(WIDTH*(xmax-this.x)/(xmax-xmin), HEIGHT*(ymax-this.y)/(ymax-ymin), 1, 1);
        context.fill();
    }
}

N = 20;
mv = 0.8;

const objects = [];
for(let i=0;i<N;i++){
  for(let j=0;j<N;j++){
   let tx = (i+1)*2*mv/(N+1)-mv;
   let ty = (j+1)*2*mv/(N+1)-mv;
   objects.push(new Point(i+j*N,tx ,ty));
  }
}

let count = 0;

function loop(timestamp) {

  context.clearRect(0, 0, 100, 50);
  objects.forEach((obj) => obj.update());
  objects.forEach((obj) => obj.render(context,-mv,mv,-mv,mv));
  requestId = window.requestAnimationFrame((ts) => loop(ts));
  count++;
  if(count >= 500){
    window.cancelAnimationFrame(requestId);
  }
  context.fillStyle = "black";
  context.font = "15px sanserif";
  context.fillText("n : " + (count).toFixed(2), 10, 15);

}

window.requestAnimationFrame((ts) => loop(ts));