Fun With Bezier Curves

Bézier curves are one of the more beautiful applications of math.

Not only are they pretty to look at, but they have many practical applications as well. Bézier curves are often employed to smoothly and naturally model the animation of objects. They’re also useful in vector art, allowing an image to be scaled infinitely without loss of quality. If you’ve worked with popular graphics and design applications, such as Photoshop, Illustrator, Flash, or InDesign, you may be familiar with Bézier curves as “paths.” Paths are vector-based curves whose underlying implementation builds upon the Bézier algorithm described here.

Up until recently, Bézier curves were some mathematical wonder that could only be represented with fancy calculus equations.

And while the Wikipedia Article on Bézier Curves didn’t seem to do much to refute this perception at first, the animated examples further down the page revealed the simplicity, straightforwardness, and beauty of the algorithm, which goes something like this:

First Order Beziers

To begin, pick the order of the curve you wish to draw, from 1 to infinity. This is where you may have seen the term “quadratic Bézier” or “cubic Bézier”, these are 2nd and 3rd order curves. Then pick and plot the anchor points that will be used to draw your 1st order curves. You should select an amount of anchor points equal to your order + 1.

Starting with your 1st order curves (which are actually straight lines), and all the way until the highest order curve, step through a position on the curve from 0 to 1. You can think of this as the percentage of curve completion, 0 being no curve, and 1 being a complete curve. You should select a small number to increment the step each round, such as 0.01.

At every step, calculate what I like to call the “midpoint” of the two points one level earlier. The term “midpoint” is technically misleading but makes the concept easy to visualize: a midpoint is the point halfway between two points. Instead of the halfway mark, though, we will be calculating the at Nth percent of the way from point 1 to point 2, where N is the current step; so that when our current step is 0.3, we calculate the point 30% of the way from point 1 to point 2, for example.

We can generalize the basic midpoint function (the easy case of 0.5 or 50%):

public function findMidpoint(p1:Point, p2:Point):Point
{
return new Point((p1.x+p2.x)/2, (p1.y+p2.y)/2);
}

to:

public function findMidpoint(p1:Point, p2:Point, step:Number):Point
{
return new Point((p1.x * step) + (p2.x * (1 - step)), (p1.y * step) + (p2.y * (1 - step)));
}

This function takes two points, and returns a new point where its components are closer to the first point when the step is closer to 0, and closer to the second point when the step is closer to 1.

If we plot these points, we will have something like this:

This simple routine is the basic building block of Bézier curves.

Quadratic Beziers

A quadratic, or 2nd order Bézier curve, takes, at every step, the current midpoint values of the 1st level lines (there are two of these), and gets the midpoint between those, as seen below:

Cubic Beziers

A cubic, or 3rd order Bézier curve, pictured in white below, takes, at every step, the current midpoint of the 2nd level curves before it, pictured in red:

5th Order Beziers

We can generalize the algorithm to the following: at every step, iterate from order 1 to order O, for every point of order O at index i, take the points i and i+1 at order O-1, and find the midpoints between them. Below is a fifth order Bézier curve (white), built iteratively from the earlier orders: 1st, not pictured; 2nd, red; 3rd, green; and 4th, blue:

8th Order Beziers

Processing power is the only limit! Here’s a larger example of 8th order Bézier curves, drawn perpetually. Be forewarned, this is hypnotizing.

Source Code

The source code for the larger, generalized example, is available here.

  • http://www.agencynet.com Garett Bugda

    Hey Ebyan.

    This is a visually amazing post. I was hypnotized by the 8th order curves. Is it possible to let a user select the start and end or a number of users select points and then watch them draw…

    g

  • http://www.agencynet.com Ebyan

    Definitely! The points are placed randomly for simplicity’s sake, but the system can be made more interactive by allowing the user to plot the points or pick the order of points on the fly.

    I must say, however, that, as a fan of procedurally generated art, I’d rather let the system enthrall me with its whimsy, rather than having to tell it what do to ;)

  • inte1ekt

    brilliant. in perpetuity.

  • m.g.

    Hi Ebyan,
    I have the following problem: given are 4 anchor points (all of them are anchor points, meaning the curve goes through them). How can I calculate the equation for the curve, or find the control points in order to calculate the equation?
    Thanks!

  • http://www.agencynet.com Ebyan

    Hi M.G.,

    The algorithm described here does not generate an equation or control points that yield an equation. Instead, it iteratively plots the next segment piece by piece, moving from 0 to 1 on each weighted midpoint calculation by a predefined small increment (something like 0.01).

    Feel free to take a look at the included source code for more details!

  • http://marksalpeter.com Mark Salpeter

    I loved this article so much that I wrote a 19 point bezier demo in javascript leveraging the canvas tag. I would recommend viewing it in a webkit based browser instead of firefox as both google and apples javascript engines are faster than mozilla’s (don’t even bother if you’re on ie, this was a proof of concept script so I didn’t bother extending browser compatibility to that steaming turd).

    I based it off of the bezier summation formula so each curve is drawn independently from the others. I’m working on a version that operates more like yours. I’d venture to guess it’s much more efficient.

    Anyway, here’s the link for anyone interested:
    http://sulley.dm.ucf.edu/~ma182662/poc/bezierdrawing.html

  • http://www.agencynet.com Ebyan

    Hey Mark!

    Great job on your HTML5 implementation. Very slick.

  • L.M

    Ebyan, great article! I’m sure you or one of the math wizards who posted here could answer this:

    m.g asked a similar question above…

    Working with a limited drawing area, drawing cubic beziers in this space is working BUT, if the curve is close to the edge of the drawing area, the control-points are OFF the drawing area and cannot be seen or moved.

    My bezier equation gives me 120 points along the curve. p0 and p3 are start and end points. p1 and p2 are the intermediate control-points. I assign point[30] and point[90] as anchors, a1 and a2.

    If I move a1 or a2, I want to recalculate the respective control-point(s) p1 or p2, then recalculate all points on the curve such that the curve will go through the anchor points.

    Given p0 and p3 and a1 and a2, how can I calculated p2 and p3?

    ANY help would be much appreciated indeed!

    Anyone?

    Thanks,

    LM

  • http://www.realtorrentz.com/search.php?term=secretariat secretariat

    Interesting thanks

blog comments powered by Disqus
curve

previously