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>

CSS

canvas { border: 1px solid black; }

JavaScript

// Pat's PI-Pins
//
// 'proximates PI, propelling pins past parallels

"use strict";

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) {
    // yuck! -- canvas doesn't do raw points :-(
    ctx.fillRect(x, y, 1, 1);
}

function drawLine(x1, y1, x2, y2) {
    ctx.beginPath();
    ctx.moveTo(x1, y1);
    ctx.lineTo(x2, y2);
    ctx.stroke();
}

var LEFT_BAR = 200;
var BAR_GAP = 100;
var RIGHT_BAR = LEFT_BAR + BAR_GAP;

var PIN_LENGTH = BAR_GAP;
var PIN_RADIUS = PIN_LENGTH / 2;

// Throw a "virtual pin" between the left and right bars
// Return a bool telling me whether it hit either of them
function throwPin() {
    
    // Pick an 'x' somewhere between the bars
    var x = LEFT_BAR + rand(BAR_GAP);
    
    // The 'y' value doesn't matter. It's just cosmetic.
    var y = 150 + rand(150);
    
    // I don't want to include PI directly here,
    // 'cos it sort of feels like cheating (but isn't!),
    // so just scale by a "big number" to smooth out
    // the distribution of angles, approximately.
    var angle = rand(10000);
    
    var cos_a = Math.cos(angle);
    var sin_a = Math.sin(angle);

    // NB: force dx part to be positive,
    // to simplify later "collision detection"
    var dx = Math.abs(PIN_RADIUS * cos_a);
    var dy = PIN_RADIUS * sin_a;
    
    var isHit = false;  // safe default
    
    var oldStrokeStyle = ctx.strokeStyle;
    
    if (x-dx <= LEFT_BAR) {
        ctx.strokeStyle = "red";
        isHit = true;
    } else if (x+dx > RIGHT_BAR) {
        ctx.strokeStyle = "blue";
        isHit = true;
    } else {
        ctx.strokeStyle = "green";
        isHit = false;  // redundant, but clear
    }
    
    drawLine(x-dx, y-dy, x+dx, y+dy);
    
    ctx.strokeStyle = oldStrokeStyle;
    
    return isHit;
}

// Yeah, I know, global...