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;}