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...