Working with CanvasShapes: Part 2


BezierCurve

Drawing Bezier Curves

I’ve always wondered how drawing curves work. Recently, I’ve been learning about canvas elements by building my own rendering library called CanvasShapes (check out some examples here).

HTML Canvas element provides an interface to draw bezier curves of 1st and 2nd degrees (having 1 and 2 control points respectively). Indeed, most of the time we won’t need anything more complex, but… I like math, and I often find myself interested in knowing how things work. So with that, I decided to learn how to draw bezier curves of the n-th degree. I used many sources, but here are a few I need to mention, as I relied heavily on them:

Basics – factorial and binomial coefficient

I will briefly discuss factorial and binomial coefficients, both of which are needed to compute the Bernstein polynomial value, as I think they’re really trivial and reading Wikipedia is probably all you need to do to understand everything you need. Just a reminder; a factorial of a non-negative integer n is defined as follows:

non-negative integar n

In JS, the most natural way to write a factorial function is by using recursion. A very common way of achieving this is by caching the factorial value for the first 100 integers, e.g.: Recursion Image By knowing how to compute the factorial value, we can easily obtain the binomial coefficient using this formula: Computing the factorial value The value can also be taken from Pascal’s triangle. Binomial coefficient can be interpreted as the number of ways you can choose k-element subsets from n-element sets. Besides polynomials, they have a wide application in combinatorics. JS function could look like this: JS Function

Bernstein polynomial

If you want to get really deep into the subject, I would strongly suggest reading this article: Bernstein Polynomials by Kenneth I. Joy. It explains very clearly what a Bernstein polynomial is and also outlines its properties. It is defined as follows: Bernstein polynomial definition The JS way to define and compute Bernstein basis polynomial’s value is: JS Bernstein Polynomial Value

Bezier curve

Bezier curves are defined as the sum of Bernstein polynomials multiplied by the control point: Bezier Curve E.g. for n=3 we have: Correct Bernstein Polynomial Equation Now there’s only one more mystery to solve – values of a t parameter. We’ve already established that we’re looking for t ∈ [0, 1]. Those values must be dense enough for your plotted curve to be smooth. Its smoothness will depend on the rasterisation. Our curve will in fact be a path of segments, but short enough to give an impression of curviness. Also there is no point in having it too low, as there’s no point in rendering a segment with a length lower than 1px. The method below does this job very well. The incremental step is computed based on the sum of distances between control points. Values of a t parameter For every control point Pn you will need to run the formula twice (in 2-dimensional coordinate system) – once per coordinate x and y. Here is the ready to use function: Ready to Use Function At this point we have everything we need for a Bezier curve to be rendered. To do that, we draw segments between each generated point. Segments are short enough to give you an impression of curviness. The render function could look like the below: Segments Let’s take a look at some working examples. Within CanvasShapes, all the shapes must have a working collision detection that can also be animated. Here are the point coordinates I’ve used for my 8-th degree Bezier curve (note: starting and ending points don’t count): Working Examples I hope this article will help at least some of you to grasp the concept of drawing Bezier curves. This article was originally published on my personal blogKarol Circle

(animated gif source: https://commons.wikimedia.org/wiki/File:BezierCurve.gif)


This post was posted in , , , by on