Last active
January 2, 2025 11:08
-
-
Save Garciat/0ec9f597e2c9b37fc868 to your computer and use it in GitHub Desktop.
PI // A very basic attempt to approximate the value of pi via a simulation.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta name="viewport" content="width=device-width, initial-scale=1" /> | |
<title>PI</title> | |
<style>html,body{margin:0;height:100%;}</style> | |
</head> | |
<body> | |
<script defer> | |
function main() { | |
var screenw = 800; | |
var screenh = 800; | |
var canvas = document.createElement('canvas'); | |
canvas.width = screenw; | |
canvas.height = screenh; | |
document.body.appendChild(canvas); | |
var result = document.createElement('div'); | |
document.body.appendChild(result); | |
var ctx = canvas.getContext('2d'); | |
var rad = Math.min(screenw, screenh); | |
var data0 = 0; | |
var data1 = 0; | |
var g = grapher(); | |
var sims = 0; | |
var step = 100; | |
function sim() { | |
for (var i = 0; i < step; ++i) { | |
var x = screenw * Math.random(); | |
var y = screenh * Math.random(); | |
if (x*x + y*y <= rad * rad) { | |
data0 += 1; | |
ctx.fillStyle = 'red'; | |
} else { | |
data1 += 1; | |
ctx.fillStyle = 'blue'; | |
} | |
ctx.fillRect(x, y, 1, 1); | |
} | |
sims += step; | |
var pi = 4 * data0 / (data0 + data1); | |
result.innerText = pi + '\nn = ' + sims; | |
g(Math.abs(Math.PI - pi)); | |
setTimeout(sim, 16); | |
} | |
setTimeout(sim, 16); | |
} | |
window.addEventListener('load', main); | |
function grapher() { | |
var MAXW = 1000; | |
var MAXH = 600; | |
var STPX = 4; | |
var canvas = document.createElement('canvas'); | |
canvas.width = MAXW; | |
canvas.height = MAXH; | |
canvas.style.border = '1px solid green'; | |
document.body.appendChild(canvas); | |
var ctx = canvas.getContext('2d'); | |
var vol = 10; | |
var ct_p = 1000; | |
var dc_p = 100; | |
var vvol = []; | |
function uniform(a, b) { | |
return a + (b - a) * Math.random(); | |
} | |
function minmax() { | |
var min = Infinity; | |
var max = -Infinity; | |
return { | |
update: function (x) { | |
min = Math.min(min, x); | |
max = Math.max(max, x); | |
}, | |
min: function () { return min; }, | |
max: function () { return max; }, | |
scale: function (x, mx) { return mx * (x - min) / (max - min); }, | |
interp: function(p) { return min + p * (max - min); } | |
}; | |
} | |
function graph(ctx, v) { | |
var i = Math.max(0, v.length - MAXW/STPX); | |
var sx = Math.max(0, MAXW - (v.length - i) * STPX); | |
var mm = minmax(); | |
v.slice(i).forEach(function (x) { | |
mm.update(x); | |
}); | |
guide(ctx, mm); | |
ctx.beginPath(); | |
ctx.moveTo(sx, MAXH - mm.scale(v[i], MAXH)); | |
for (; i < v.length - 1; ++i) { | |
var px = v[i]; | |
var x1 = sx; | |
var y1 = MAXH - mm.scale(v[i+0], MAXH); | |
var x2 = sx + STPX; | |
var y2 = MAXH - mm.scale(v[i+1], MAXH); | |
var xc = (x1 + x2) / 2; | |
var yc = (y1 + y2) / 2; | |
ctx.quadraticCurveTo(x1, y1, xc, yc); | |
sx += STPX; | |
} | |
ctx.strokeStyle = 'red'; | |
ctx.lineWidth = 2; | |
ctx.stroke(); | |
} | |
function guide(ctx, mm) { | |
var max = mm.max(); | |
var min = mm.min(); | |
var sc = Math.pow(10, Math.floor(Math.log10(Math.abs(max - min)))); | |
var dd = Math.ceil(Math.abs(max - min) / 10 / sc) * sc; | |
if (dd === 0) return; | |
horizontal(ctx, mm, 0, 'blue'); | |
for (var y = dd; y < max; y += dd) { | |
horizontal(ctx, mm, y, 'gray'); | |
} | |
if (min < 0) { | |
for (var y = -dd; y > min; y -= dd) { | |
horizontal(ctx, mm, y, 'gray'); | |
} | |
} | |
} | |
function horizontal(ctx, mm, y, c) { | |
var gy = mm.scale(y, MAXH); | |
ctx.beginPath(); | |
ctx.moveTo(0, MAXH - gy); | |
ctx.lineTo(MAXW, MAXH - gy); | |
ctx.strokeStyle = c; | |
ctx.lineWidth = 1; | |
ctx.stroke(); | |
var gt = y.toString(); | |
var tw = ctx.measureText(gt).width; | |
ctx.font = '12px Arial'; | |
ctx.fillText(gt, MAXW - tw, MAXH - gy); | |
} | |
return function (x) { | |
vvol.push(x); | |
ctx.clearRect(0, 0, MAXW, MAXH); | |
graph(ctx, vvol); | |
}; | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment