Canvasによるマンデルブロ描画サンプル(ImageData)

icon 項目のみ表示/展開表示の切り替え

概要

Canvasを使用してマンデルブロを描画してみました。
下図は、複素座標(-1.33,-1)-(1.33,1)の範囲を320*240ピクセルの大きさで最大反復回数64回でJavascriptにより描画しています。
素のCanvasには点を描画する関数が無いのでcanvasと同サイズのバッファをcreateImageDataで作成することによりバイトサイズの配列でピクセル操作をすることができます。
各ピクセルは配列で操作して最後にputImageDataでCanvasを更新します。
1ピクセルごとにputImageDataを呼び出すとi7-3820では181msかかりました。
さらに1ピクセルごとに長方形で描画すると248msかかります。
図の下には描画に要した時間が表示されます。
マンデルブロについては、マンデルブロ描画プログラムVersion2.3を参照してください。

サンプル



以下に環境による実行速度の例を示します。
CPU Windows ブラウザ 実行速度
Intel(R) Core(TM) i7-3820 CPU @ 3.60GHz(OC4.2GHz) Windows 7 InternetExplorer 11 11.0.9600.19230 79ms
Intel(R) Core(TM) i7-3820 CPU @ 3.60GHz(OC4.2GHz) Windows 7 Chrome 74.0.32729.157(64bit) 11ms
Intel(R) Core(TM) i5-4300U CPU @ 1.90GHz Windows 8.1 InternetExplorer 11 11.0.9600.19356 134ms
Intel(R) Core(TM) i5-4300U CPU @ 1.90GHz Windows 8.1 Chrome 74.0.32729.157(64bit) 18ms

createImageData(width,height)

幅width、高さheightのImageDataオブジェクトを作成し返します。
ImageDataオブジェクトは以下のプロパティを所有しています。

width

ImageDataの幅

height

ImageDataの高さ

data

各要素が1byteの配列で、1ピクセルが4byte(4要素)です。
0バイト目がR、1バイト目がG、2バイト目がB、3バイト目がアルファの順です。

putImageData(imageData,x,y)

左上座標x,yにimageDataを描画します。

ソースコード

本ページからCanvasによるマンデルブロ描画にかかわる部分のみを抽出したhtmlのソースコードを以下に示します。
htmlのソースコードは本ページの最後のリンクよりダウンロードすることができます。
<!DOCTYPE html> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head>
 <meta charset="utf-8"/>
 <title>Canvasによるマンデルブロ描画サンプル</title>
</head> 

<body> 

<canvas id="c1" width="320" height="240"></canvas><br />

<script type="text/javascript">

// マンデルブロ描画
function mandelbrot(ctx,wx,wy,amin,bmin,amax,bmax){
  var a,b,c;
  var sx,sy;
  sy=wy-1;
  var imgData=ctx.createImageData(wx,wy);
  for(b=bmin;b<bmax;){
    sx=0;
    for(a=amin;a<amax;){
      var x=0;
      var y=0;
      for(c=0;c<64;c++){
        var x2=x*x;
        var y2=y*y;
        var zx=x2-y2-a;
        var zy=2*x*y-b;
        x=zx;
        y=zy;
        if(4<=x2+y2)
          break;
      }
      var r1=(c & 0x3)<<6;
      var g1=(c & 0xc)<<4;
      var b1=(c & 0x30)<<2;
      var pos=(sx+sy*wx)*4;
      imgData.data[pos]=r1;
      imgData.data[pos+1]=g1;
      imgData.data[pos+2]=b1;
      imgData.data[pos+3]=255;
      a+=(amax-amin)/wx;
      ++sx;
    }
    b+=(bmax-bmin)/wy;
    --sy;
  }
  ctx.putImageData(imgData, 0, 0);
}

window.onload = function(){
  var canvas = document.getElementById('c1');
  if (canvas.getContext){
    var ctx = canvas.getContext('2d');
    mandelbrot(ctx,320,240,-1.33,-1,1.33,1);
  }
}
</script>

</body> 
</html>
ソースファイルのダウンロード(mandelbrot4.zip)