```javascript /* Return the angle between two vectors on a plane The angle is from vector 1 to vector 2, positive anticlockwise The result is between -pi -> pi */ function Angle2D(x1, y1, x2, y2) { let dtheta,theta1,theta2; theta1 = Math.atan2(y1,x1); theta2 = Math.atan2(y2,x2); dtheta = theta2 - theta1; while (dtheta > Math.PI) dtheta -= Math.PI * 2; while (dtheta < -Math.PI) dtheta += Math.PI * 2; return dtheta; } function InsidePolygon(polygon, p) { let i; let angle=0; let p1 = {}, p2 = {}; let n = polygon.points.length; for (i=0; i < n; i++) { p1.h = polygon.points[i].x - p.x; p1.v = polygon.points[i].y - p.y; p2.h = polygon.points[(i+1)%n].x - p.x; p2.v = polygon.points[(i+1)%n].y - p.y; angle += Angle2D(p1.h,p1.v,p2.h,p2.v); } if (Math.abs(angle) < Math.PI) return false else return true } ``` example of wired into mousemovement ```javascript c.onmousemove = function(e){ if (!listening) return data.innerHTML = ''; data.style.display = 'none'; mouseX = e.clientX; mouseY = e.clientY; // convert to canvas coords let cpos = getOffset(c); let cx = mouseX - cpos.rawleft; let cy = mouseY - cpos.rawtop; if (cx > 0 && cx < cpos.rawwidth && cy > 0 && cy < cpos.rawheight) { // get mouse position in polygon let inside = false; for (let i=0; i < polygons.length; i++) { if (InsidePolygon(polygons[i], { x: cx, y: cy })) { // console.log("INSIDE ", polygons[i].id) data.innerHTML = '{{ $refName }} ' + polygons[i].id; inside = true; } } if (inside) { data.style.display = 'block'; data.style.top = mouseY - 10; data.style.left = mouseX + 10; } } } ```