SEEDS Creator's Blog

3.14

HTML5のcanvasを使って絵を書いてみました。

モンテカルロ

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Canvasでお絵かき</title>
    <script type="text/javascript">
        function fig() {
            var canvas = document.getElementById('canvas');
                var context = canvas.getContext('2d');
                context.lineWidth = 2;
                // 正方形
                context.beginPath();
                context.rect(20,20,500,500);
                context.stroke();
                // 円
                context.beginPath();
                context.arc(270,270,250,0,2*Math.PI,true);
                context.stroke();
        }
        function dots() {
            var canvas    = document.getElementById('canvas');
            var context   = canvas.getContext('2d');
            for (i = 0; i < 1000; i++) {
                var x = Math.random();
                var y = Math.random();
                if (Math.pow(2 * x - 1, 2) + Math.pow(2 * y - 1, 2) <= 1) {
                    context.fillStyle = "rgb(255, 0, 0)";
                } else {
                    context.fillStyle = "rgb(0, 0, 255)";
                }
                context.beginPath();
                context.arc(20 + x * 500, 20 + y * 500, 2, 0, 2*Math.PI, true);
                context.fill();
            }
        }
    </script>
</head>
<body onLoad="fig()">
    <input type="button" value="点を打つ" onclick="dots();"><br>
    <canvas width="540" height="540" id="canvas">
    </canvas>
</body>
</html>

「点を打つ」ボタンを押すと、dotsメソッドが動いて正方形の中にランダムに点が1000個打たれます。 円の中と外で色分けもしてみました。

ところで、、

3月14日と言えばみなさん何の日かご存知ですよね。 はいそうです。みなさん正解です。円周率の日です。

永遠に続くとかで結婚とかには縁起の良い日みたいですよ!

canvasで書いた上の絵から円周率が求まります(´▽`)

円周率3.14・・・

上の絵で、円の半径をrとして正方形の面積と円の面積の比を計算すると、 比 = 円の面積 / 正方形の面積   = (π x r x r) / (2r x 2r)   = π / 4

この比は何を意味するかというと、正方形の中にランダムに点を打って円の中に入る確率に相当します。 だいたい78%くらいですかね。

そうです。赤い点の数を数えて1000で割って4倍すると円周率が求まります。 数えるのは面倒臭いので、プログラムにやらせましょう。 上で書いたJavascriptのdotsメソッドで円の中に入った時に点の数を数えるようにして、最後に計算します。

function dots() {
    var canvas    = document.getElementById('canvas');
    var context   = canvas.getContext('2d');
    for (i = 0; i < 1000; i++) {
        var x = Math.random();
        var y = Math.random();
→       var in_circle = 0;
        if (Math.pow(2 * x - 1, 2) + Math.pow(2 * y - 1, 2) <= 1) {
            context.fillStyle = "rgb(255, 0, 0)";
→           incircle += 1;
        } else {
            context.fillStyle = "rgb(0, 0, 255)";
        }
        context.beginPath();
        context.arc(20 + x * 500, 20 + y * 500, 2, 0, 2*Math.PI, true);
        context.fill();
    }var pi = 4 * in_circle / 1000;
}

こんな感じです。メチャ簡単!

実行してみましょう! pi = 3.192 pi = 3.184 pi = 3.116 pi = 3.100 pi = 3.132

精度悪い∑(゚□゚;)

サンプル数を増やしましょう。 だいたい2ケタ増やすと精度が1ケタ良くなるそうです。