For a drawing application I'm saving the mouse movement coordinates to an array then drawing them with lineTo. The resulting line is not smooth. How can I produce a single curve between all the gathered points?
I've googled but I have only found 3 functions for drawing lines: For 2 sample points, simply use lineTo. For 3 sample points quadraticCurveTo, for 4 sample points, bezierCurveTo.
(I tried drawing a bezierCurveTo for every 4 points in the array, but this leads to kinks every 4 sample points, instead of a continuous smooth curve.)
How do I write a function to draw a smooth curve with 5 sample points and beyond?
I found this to work nicely
I decide to add on, rather than posting my solution to another post. Below are the solution that I build, may not be perfect, but so far the output are good.
Important: it will pass through all the points!
If you have any idea, to make it better, please share to me. Thanks.
Here are the comparison of before after:
Save this code to HTML to test it out.
Incredibly late but inspired by Homan's brilliantly simple answer, allow me to post a more general solution (general in the sense that Homan's solution crashes on arrays of points with less than 3 vertices):
A bit late, but for the record.
You can achieve smooth lines by using cardinal splines (aka canonical spline) to draw smooth curves that goes through the points.
I made this function for canvas - it's split into three function to increase versatility. The main wrapper function looks like this:
To draw a curve have an array with x, y points in the order:
x1,y1, x2,y2, ...xn,yn
.Use it like this:
The function above calls two sub-functions, one to calculate the smoothed points. This returns an array with new points - this is the core function which calculates the smoothed points:
And to actually draw the points as a smoothed curve (or any other segmented lines as long as you have an x,y array):
This results in this:
You can easily extend the canvas so you can call it like this instead:
Add the following to the javascript:
You can find a more optimized version of this on NPM (
npm i cardinal-spline-js
) or on GitLab.The first answer will not pass through all the points. This graph will exactly pass through all the points and will be a prefect curve with the points as points as [{x:,y:}] n such points.
Give KineticJS a try - you can define a Spline with an array of points. Here's an example:
Old url: http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-spline-tutorial/
See archive url: https://web.archive.org/web/20141204030628/http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-spline-tutorial/