電電高専生日記

モンテカルロ法による円周率算出

2014/07/04 18:04

最近、下級生が情報工学の課題のモンテカルロ法による円周率算出に悪戦苦闘していました。プログラム習いたての頃にやるには少し難しいかもしれません。

自分も以前その授業でこの課題をやったので、思い出しつつやってみました。それがこれ↓です。


打つ点の数: 
円周率=

算出ボタンを押すと、四角形のキャンバスの中に、任意の数(初期設定では10000)の点がランダムな位置に打たれます。ここで、四角形の内接円があると仮定して、点が円内に打たれたかを判定します。

全て点を打ち終わった後に、打った点の数と円内に打たれた点の数の比を用いて、円周率を算出することができます。

内接円の半径をr、上記の比をx、円周率をpiとおくと、円の面積について以下の等式が成り立ちます。

(四角形×比) (2r)^2*x = r*r*pi (半径×半径×円周率)

piについて解くと、

pi = 4*x

つまり、円周率は4×円内に打たれた点の数/打たれた全ての点の数で求まります。

勿論これで算出した円周率はあくまでも近似値であって、正確ではありません。また、打つ点の数を多くするにしたがい、円周率は正確になっていきます。


ブログ上で動かしたかったので、CanvasとJavaScriptを用いて作りました。以下にソースを示します。

$("#calc_pi").click(function(){
    var cv = document.getElementById("cv");
    var ctx = cv.getContext("2d");
    var w=200, h=200, r=w/2;    //横幅、縦幅、内接円の半径
    var ox=w/2, oy=h/2;           //中心座標
    ctx.clearRect(0,0,w,h);        //キャンバスクリア

    var num_of_dot = parseInt(document.getElementById("num_of_dot").value);    //打つ点の数
    var within_circle = 0;       //円内に打たれた点の数
    var px, py, pr;
    for (var i=0; i<num_of_dot; i++){
        //ランダムな点の座標を決定
        px = Math.floor(Math.random()*w);
        py = Math.floor(Math.random()*h);
        pr = (px-ox)*(px-ox) + (py-oy)*(py-oy);  //中心からの距離の2乗
        if (pr <= r*r){    //円内に打たれた場合
            ctx.fillStyle = "rgba(192,96,96,1)";
            within_circle ++;
        } else {                //円外に打たれた場合
            ctx.fillStyle = "rgba(196,196,196,1)";
        }
        ctx.fillRect(px, py, 1, 1);
    }
    var pi = 4 * within_circle / num_of_dot;
    document.getElementById("pi").value = pi;    //出力
});
  • このエントリーをはてなブックマークに追加

最新記事

コメント(0)





プロフィール

名前:elkosendiary

性別:男

生年:1995年


2011年4月 高専入学
2016年3月 高専卒業
2016年4月 大学編入学
2018年3月 大学卒業予定

にほんブログ村 大学生日記ブログ 理系大学生へ
にほんブログ村

カテゴリ
Adsense
月別アーカイブ
ブログ内検索

おすすめ記事

「高専大学編入ログ」を作成しました

自作ゲーム「Defend PortMoresby!」バージョン3

【改良版】 RaspberryPiで作ったカメラ付き戦車ラジコン