function roundCorners(_points) {
let corner_radius = 10
let points = Object.assign([], _points)
let vecs = points.map((pt, idx, pts) => {
let pt2 = pts[(idx+1) % points.length]
return {dx: pt2.x - pt.x, dy: pt2.y - pt.y}
})
let lengths = vecs.map(vec => Math.sqrt(Object.values(vec).reduce((s,v) => s + Math.pow(v, 2), 0)))
let normvecs = vecs.map((vec, i) => {return {dx: vec.dx/lengths[i], dy: vec.dy/lengths[i]}})
let angles = vecs.map(vec => Math.atan2(vec.dx, vec.dy))
let ext_angles = angles.map((a, i, angles) => {
let a2 = angles[(i+1) % angles.length]
return a2-a
})
let corner_setbacks = ext_angles.map(a => Math.abs(corner_radius * Math.tan(a/2)))
let setbackvecs_1 = normvecs.map((vec, i) => {return {dx: vec.dx * corner_setbacks[i],
dy: vec.dy * corner_setbacks[i]}
})
let setbackvecs_2 = normvecs.map((vec, i) => {return {dx: vec.dx * corner_setbacks[(i+points.length-1)%points.length],
dy: vec.dy * corner_setbacks[(i+points.length-1)%points.length]}
})
corner_setbacks.map((v, i) => v + corner_setbacks[(i+1)%corner_setbacks.length] < lengths[i+1])
let new_points = points.map((pt,i, points) => [{x: pt.x + setbackvecs_2[i].dx,
y: pt.y + setbackvecs_2[i].dy},
{x: points[(i+1)%points.length].x - setbackvecs_1[i].dx,
y: points[(i+1)%points.length].y - setbackvecs_1[i].dy}
])
let ctx = d3.path()
ctx.moveTo(new_points[0][0].x, new_points[0][0].y)
new_points.forEach((point_pair, i, new_points) => {
ctx.lineTo(point_pair[1].x, point_pair[1].y)
ctx.arcTo(points[(i+1)%points.length].x,
points[(i+1)%points.length].y,
new_points[(i+1)%new_points.length][0].x,
new_points[(i+1)%new_points.length][0].y,
corner_radius)
})
return ctx.toString()
}