JSFiddle - React, Tailwind, and code Playground

by PerroAZUL

HTML

<canvas width="600" height="600"></canvas>

CSS

html,body,canvas{margin:0;padding:0;display:block;}

JavaScript

sin = Math.sin;

context = document.querySelector("canvas").getContext("2d");
context.translate(300, 300);
context.scale(1, -1);
context.fillStyle = "#CCC";

var camera = normalize(vec2(0, 1));
var turret = normalize(vec2(1, 0));

window.addEventListener("mousemove", function(event) {
    var dx = event.clientX - 300;
    var dy = -(event.clientY - 300);
    camera = normalize(vec2(dx, dy));
});

requestAnimationFrame(frame);

show_angle(vec2(1421,875), vec2(1518,570), vec2(1547,1157));
show_angle(vec2(1421,1083), vec2(1599,1061), vec2(1384,1234));
show_angle(vec2(1424,880), vec2(1528,1108), vec2(1301,1415));
show_angle(vec2(1496,1042), vec2(1422,873), vec2(1250,1402));

function show_angle(center, a, b)
{
    var p = normalize(sub(a, center));
    var q = normalize(sub(b, center));
    console.log((Math.acos(dot(p, q)) / Math.PI * 180).toFixed(2));
}

function frame()
{
    context.fillRect(-300, -300, 600, 600);
    draw_vector(turret);
    draw_vector(camera);
    
    turret = slerp(turret, camera, 0.1);
    
    requestAnimationFrame(frame);
}

function draw_vector(v)
{
    var length = 50;
    context.beginPath();
    context.moveTo(0, 0);
    context.lineTo(v.x * length, v.y * length);
    context.stroke();
}

function slerp(p0, p1, t)
{
    var a = Math.acos(dot(p0, p1));
    var s = sin(a);
    
    if (s < 0.00001)
        return p1;
    
    return add(mul(p0, sin((1 - t) * a) / s), mul(p1, sin(t*a) / s));
}

function vec2(x, y) {return {x: x, y: y};}
function normalize(v) {var l = length(v); return vec2(v.x / l, v.y / l); }
function length(v) {return Math.sqrt(sqr(v.x) + sqr(v.y));}
function dot(a, b) {return a.x * b.x + a.y * b.y; }
function mul(v, x) {return vec2(v.x * x, v.y * x);}
function add(a, b) {return vec2(a.x + b.x, a.y + b.y);}
function sub(a, b) {return vec2(a.x - b.x, a.y - b.y);}
function sqr(x) {return x*x;}