Pat's PI-Pins
'proximates PI, propelling pins past parallels.
HTML
<canvas id="myCanvas" width="400" height="400" >
Your browser does not support the HTML5 canvas tag.
</canvas>
<div id="output"></div>
CSS
canvas { border: 1px solid black; }
JavaScript
// Pat's PI-Pins
//
// 'proximates PI, propelling pins past parallels
//
// * Now with SPEED_SCALE Technology (TM)
// to accelerate convergence
//
// * Unit Tested for extra robustness!
/*jslint browser: true, devel: true, white: true */
"use strict";
var SPEED_SCALE = 100;
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
// Return a random double from 0 to 'limit'
// (Inclusive of 0; non-inclusive of 'limit')
function rand(limit) {
return Math.random() * limit;
}
function drawPoint(x, y, color) {
// yuck! -- canvas doesn't do raw points :-(
var oldFillStyle = ctx.fillStyle;
ctx.fillStyle = color;
ctx.fillRect(x, y, 1, 1);
ctx.fillStyle = oldFillStyle;
}
function drawLine(x1, y1, x2, y2) {
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
}
// A testable "pure functional" core for `throwPin`
//
// Throws a unit-length "virtual pin" in
// a normalised unit space.
//
// "Normed" vars should be in the range:
// 0 (incl) to 1 (excl)
//
function throwPin_core(xNormed, yNormed, angle) {
// Abbreviate vars internally
var x = xNormed;
var y = yNormed;
var cos_a = Math.cos(angle);
var sin_a = Math.sin(angle);
// NB: force the `dx` part to be positive,
// to simplify later "collision detection"
var dx = Math.abs(cos_a) / 2;
var dy = sin_a / 2;
var isHit = false; // safe default
var color = "black"; // sentinel
if (x-dx <= 0) {
color = "red";
isHit = true;
} else if (x+dx > 1) {
color = "blue";
isHit = true;
} else {
color = "green";
isHit = false; // redundant, but clear
}
return {
isHit: isHit,
color: color,
leftCoords: [x-dx, y-dy],
rightCoords: [x+dx, y+dy]
};
}
var LEFT_BAR = 200;
var DRAW_SCALE = 100;
var RIGHT_BAR = LEFT_BAR + DRAW_SCALE;
var Y_BASE = 175;
// Throw a "virtual...