JSFiddle - React, Tailwind, and code Playground
by soulwire
HTML
<canvas id="canvas"></canvas>
CoffeeScript
class Vertex
constructor: ( @x = 0.0, @y = 0.0 ) ->
# squared distance to another vertex
distanceSq: ( v ) -> (dx = v.x - @x) * dx + (dy = v.y - @y) * dy
# distance to another vertex
distance: ( v ) -> Math.sqrt (dx = v.x - @x) * dx + (dy = v.y - @y) * dy
# radian angle to another vertex
angle: ( v ) -> Math.atan2 v.y - @y, v.x - @x
# linear interpolation between this and another vertex
lerp: ( v, f ) -> new Vertex @x + (v.x - @x) * f, @y + (v.y - @y) * f
# duplicate this vertex
clone: -> new Vertex @x, @y
class Polygon
constructor: ( @vertices... ) ->
# main
canvas = document.getElementById 'canvas'
ctx = canvas.getContext '2d'
drawPoly = ( poly ) ->
do ctx.beginPath
ctx.moveTo poly.vertices[0].x, poly.vertices[0].y
for vertex in poly.vertices
ctx.lineTo vertex.x, vertex.y
do ctx.closePath
do ctx.stroke
poly = new Polygon new Vertex(50, 50), new Vertex(100, 40), new Vertex(120, 120), new Vertex(10, 90)
drawPoly poly
findAngles = ( vertices ) ->
nv = vertices.length
# cosine rule
rule = (a, b, c) -> Math.acos (a*a + b*b - c*c) / (2*a*b)
for vertex, index in vertices
prev = vertices[ (index - 1 + nv) % nv ]
next = vertices[ (index + 1 + nv) % nv ]
a = prev.distance vertex
b = next.distance vertex
c = next.distance prev
# use cosine rule (SSS)
# a^2 = b^2 + c^2 - 2bc cos A
A = rule b, c, a
B = rule c, a, b
C = Math.PI - A - B
sides = (side.toFixed 3 for side in [a, b, c])
angles = ((angle * 180 / Math.PI).toFixed 3 for angle in [A, B, C])
console.log 'sides', sides, 'angles', angles
ctx.fillText index, vertex.x, vertex.y - 10
console.log index, [ (index - 1 + nv) % nv, (index + 1 + nv) % nv ]
console.log findAngles poly.vertices