Search code examples
graphicsgeometrypolygon

How to "soften" the edges of a polyline?


Given a line made up of several points, how do I make the line smoother/ curvier/ softer through adding intermediate points -- while keeping the original points completely intact and unmoved?

To illustrate, I want to go from the above to the below in this illustration:

enter image description here

Note how in the above picture, if we start at the bottom there will be a sharper right turn. In the bottom image however, this sharp right turn is made a bit "softer" by adding an intermediate point which is positioned in the middle of the two points, and using averages of the angles of the other lines. (Differently put, imagine the lines a race car would drive, as it couldn't abruptly change direction.) Note how, however, none of the original points was "touched", I just added more points.

Thanks!! For what it's worth, I'm implementing this using JavaScript and Canvas.


Solution

  • The following code found elsewhere here does the job for me, in the specific context of JavaScript-Canvas which I'm using -- but please see Angus' answer for a more general approach:

    var max = points.length;
    context.beginPath();
    var i = 0;
    context.moveTo(points[i].x, points[i].y);
    for (i = 1; i < max - 2; i++) {
        var xc = (points[i].x + points[i + 1].x) * .5;
        var yc = (points[i].y + points[i + 1].y) * .5;
        context.quadraticCurveTo(points[i].x, points[i].y, xc, yc);
    }
    context.quadraticCurveTo(points[max - 2].x, points[max - 2].y, points[max - 1].x,points[max - 1].y);
    context.closePath();
    context.stroke();