html5-canvas Polygons Render a rounded polygon.

Example

Creates a path from a set of points `[{x:?,y:?},{x:?,y:?},...,{x:?,y:?}]` with rounded corners of radius. If the corner angle is too small to fit the radius or the distance between corners does not allow room the corners radius is reduced to a best fit.

Usage Example

``````var triangle = [
{ x: 200, y : 50 },
{ x: 300, y : 200 },
{ x: 100, y : 200 }
];
ctx.lineWidth = 4;
ctx.fillStyle = "Green";
ctx.strokeStyle = "black";
ctx.beginPath(); // start a new path
ctx.fill();
ctx.stroke();
``````

Render function

``````var roundedPoly = function(points,radius){
var i, x, y, len, p1, p2, p3, v1, v2, sinA, sinA90, radDirection, drawDirection, angle, halfAngle, cRadius, lenOut;
var asVec = function (p, pp, v) { // convert points to a line with len and normalised
v.x = pp.x - p.x; // x,y as vec
v.y = pp.y - p.y;
v.len = Math.sqrt(v.x * v.x + v.y * v.y); // length of vec
v.nx = v.x / v.len; // normalised
v.ny = v.y / v.len;
v.ang = Math.atan2(v.ny, v.nx); // direction of vec
}
v1 = {};
v2 = {};
len = points.length;                         // number points
p1 = points[len - 1];                        // start at end of path
for (i = 0; i < len; i++) {                  // do each corner
p2 = points[(i) % len];                  // the corner point that is being rounded
p3 = points[(i + 1) % len];
// get the corner as vectors out away from corner
asVec(p2, p1, v1);                       // vec back from corner point
asVec(p2, p3, v2);                       // vec forward from corner point
// get corners cross product (asin of angle)
sinA = v1.nx * v2.ny - v1.ny * v2.nx;    // cross product
// get cross product of first line and perpendicular second line
sinA90 = v1.nx * v2.nx - v1.ny * -v2.ny; // cross product to normal of line 2
angle = Math.asin(sinA);                 // get the angle
drawDirection = false;                   // may need to draw the arc anticlockwise
// find the correct quadrant for circle center
if (sinA90 < 0) {
if (angle < 0) {
angle = Math.PI + angle; // add 180 to move us to the 3 quadrant
} else {
angle = Math.PI - angle; // move back into the 2nd quadrant
drawDirection = true;
}
} else {
if (angle > 0) {
drawDirection = true;
}
}
halfAngle = angle / 2;
// get distance from corner to point where round corner touches line
lenOut = Math.abs(Math.cos(halfAngle) * radius / Math.sin(halfAngle));
if (lenOut > Math.min(v1.len / 2, v2.len / 2)) { // fix if longer than half line length
lenOut = Math.min(v1.len / 2, v2.len / 2);
// ajust the radius of corner rounding to fit
cRadius = Math.abs(lenOut * Math.sin(halfAngle) / Math.cos(halfAngle));
} else {