2015-12-20 15:19:50 -08:00
<!doctype html>
< html >
< head >
< meta charset = "utf-8" >
< title > A Primer on Bézier Curves< / title >
2016-02-20 17:50:30 -08:00
<!-- mobile optimize -->
< meta name = "viewport" content = "width=800, initial-scale=1.0" >
2015-12-20 15:19:50 -08:00
<!-- opengraph information -->
< meta property = "og:title" content = "A Primer on Bézier Curves" >
< meta property = "og:type" content = "text" >
< meta property = "og:url" content = "http://pomax.github.io/bezierinfo" >
< meta property = "og:description" content = "A detailed explanation of Bézier curves, and how to do the many things that we commonly want to do with them." >
< meta property = "og:locale" content = "en_GB" >
< meta property = "og:type" content = "article" >
< meta property = "og:published_time" content = "2013-06-13 12:00:00" >
< meta property = "og:author" content = "Mike 'Pomax' Kamermans" >
< meta property = "og:section" content = "Bézier Curves" >
< meta property = "og:tag" content = "Bézier Curves" >
2016-01-03 16:07:56 -08:00
< style >
2016-01-05 23:08:39 -08:00
html, body, article { height: 100%; margin: 0; }
2016-01-12 18:55:20 -08:00
body { width: 800px; margin: auto; font-size: 4.25mm!important; }
2016-01-03 16:07:56 -08:00
< / style >
2016-01-22 17:43:40 -08:00
< link rel = "stylesheet" href = "stylesheets/style.css" >
2015-12-20 15:19:50 -08:00
< / head >
< body >
2017-02-05 11:39:58 -08:00
2016-01-12 18:55:20 -08:00
< div class = "dev" >
< style >
div.dev {
background: rgb(43, 49, 95);
color: rgb(81, 181, 255);
position: fixed;
transform: rotate(-45deg);
width: 22em;
text-align: center;
top: 4em;
left: -6em;
font-variant: small-caps;
font-weight: bolder;
font-family: Helvetica;
box-shadow: 0px 5px 7px 2px rgba(0, 0, 0, 0.3);
}
< / style >
DEV PREVIEW ONLY
< / div >
2016-01-07 23:11:56 -08:00
2016-03-20 10:15:52 -07:00
<!-- Because people probably want to share this article -->
< div class = "sharebuttons" >
< style >
div.sharebuttons {
position: fixed;
top: 1rem;
left: 1rem;
padding: 0.1em;
background: white;
}
div.sharebuttons img {
min-width: 1.25rem;
min-height: 1.25rem;
max-height: 1.25rem;
}
}
< / style >
2016-03-20 10:22:12 -07:00
< a href = "https://www.reddit.com/submit?url=https://pomax.github.io/bezierinfo&title=A Primer on Bézier Curves&text=A free, online book for when you really need to know how to do Bézier things." >
2016-03-20 10:15:52 -07:00
< img src = "https://www.redditstatic.com/spreddit1.gif" alt = "submit to reddit" title = "submit to reddit" >
< / a >
2016-03-20 10:22:12 -07:00
< a href = "https://news.ycombinator.com/submitlink?u=https://pomax.github.io/bezierinfo&t=A Primer on Bézier Curves" >
2016-03-20 10:15:52 -07:00
< img src = "https://news.ycombinator.com/y18.gif" alt = "submit to hacker news" title = "submit to hacker news" >
< / a >
< a href = "https://twitter.com/intent/tweet?hashtags=bezier,curves,maths&original_referer=https://pomax.github.io/bezierinfo&text=Reading%20%22A%20Primer%20on%20Bezier%20Curves%22%20by%20@TheRealPomax%20over%20on%20https://pomax.github.io/bezierinfo" >
2017-02-07 08:55:03 -08:00
< img src = "images/twitter.ico" alt = "tweet your read" title = "tweet your read" >
2016-03-20 10:15:52 -07:00
< / a >
< / div >
2016-02-20 17:50:30 -08:00
<!-- referral tracking, because I like knowing who's linking to my book -->
< script src = "lib/site/referrer.js" async > < / script >
2015-12-20 15:19:50 -08:00
< article >
2016-01-16 17:57:16 -08:00
< div id = "article" >
<!-- these rules will get overwritten by the style in the article.js React bundle -->
< style >
header h1, header h2 { text-align: center; }
header h1 { font-size: 300%; margin: 0.2em; }
p.jsnote { margin: 2em; text-align: justify; }
p.jsnote:first-child { width: 13em; margin: auto; }
< / style >
2016-01-12 18:55:20 -08:00
2016-01-16 17:57:16 -08:00
< header >
< h1 > A Primer on Bézier Curves< / h1 >
< h2 > A free, online book for when you really need to know how to do Bézier things.< / h2 >
< / header >
2015-12-20 15:19:50 -08:00
2016-01-05 23:08:39 -08:00
<!-- This content only shows for as long as JS/React hasn't loaded the page content -->
2016-02-20 17:50:30 -08:00
< section >
< p class = "jsnote" > Loading the article< span id = "loader" > ...< / span > < / p >
2016-01-05 23:08:39 -08:00
2016-02-20 17:50:30 -08:00
< p class = "enabling jsnote" > If you have JavaScript disabled, you'll have to enable it, as this book heavily relies on JS rendering, both for the base content (it's been written as a React application) and all the interactive graphics, which rely on JS not just for the user interaction but also for the live-drawing (none of the graphics in this book are flat images, they're all live-rendered).< / p >
2016-01-05 23:08:39 -08:00
2016-02-20 17:50:30 -08:00
< script > var n = document . querySelector ( ".enabling" ) ; n . parentNode . removeChild ( n ) ; ( function update ( el , str ) { str = ( str . length === 3 ) ? '' : str + '.' ; el . textContent = str ; setTimeout ( function ( ) { update ( el , str ) ; } , 333 ) ; } ( document . querySelector ( "#loader" ) , "..." ) ) ; < / script >
< / section >
2016-02-01 10:56:16 -08:00
2016-02-20 17:50:30 -08:00
< section >
< h2 id = "preface" > Preface< / h2 >
2016-02-01 10:56:16 -08:00
2016-02-20 17:50:30 -08:00
< p > In order to draw things in 2D, we usually rely on lines, which typically get classified
into two categories: straight lines, and curves. The first of these are as easy to draw as they
are easy to make a computer draw. Give a computer the first and last point in the line, and
BAM! straight line. No questions asked.< / p >
2015-12-20 15:19:50 -08:00
2016-02-20 17:50:30 -08:00
< p > Curves, however, are a much bigger problem. While we can draw curves with ridiculous ease
freehand, computers are a bit handicapped in that they can't draw curves unless there is a
mathematical function that describes how it should be drawn. In fact, they even need this for
straight lines, but the function is ridiculously easy, so we tend to ignore that as far as
computers are concerned, all lines are "functions", regardless of whether they're straight
or curves. However, that does mean that we need to come up with fast-to-compute functions that
lead to nice looking curves on a computer. There's a number of these, and in this article
we'll focus on a particular function that has received quite a bit of attention, and is used
in pretty much anything that can draw curves: "Bézier" curves< / p >
< p > They're named after < a href = "https://en.wikipedia.org/wiki/Pierre_B%C3%A9zier" > Pierre
Bézier< / a > , who is principally responsible for getting them known to the world as a curve
well-suited for design work (working for Renault and publishing his investigations in 1962),
although he was not the first, or only one, to "invent" these type of curves.
One might be tempted to say that the mathematician < a href = "https://en.wikipedia.org/wiki/Paul_de_Casteljau" > Paul
de Casteljau< / a > was first, investigating the nature of these curves in 1959 while working at
Citroën, coming up with a really elegant way of figuring out how to draw them. However, de
Casteljau did not publish his work, making the question "who was first" hard to answer in
any absolute sense. Or is it? Bézier curves are, at their core, "Bernstein polynomials", a family
of mathematical functions investigated
by < a href = "https://en.wikipedia.org/wiki/Sergei_Natanovich_Bernstein" > Sergei Natanovich Bernstein< / a > ,
with publications on them at least as far back as 1912. Anyway, that's mostly trivia, what
you are more likely to care about is that these curves are handy: you can link up multiple
Bézier curves so that the combination looks like a single curve. If you've ever drawn Photoshop
"paths" or worked with vector drawing programs like Flash, Illustrator or Inkscape, those curves
you've been drawing are Bézier curves.< / p >
< p > So, what if you need to program them yourself? What are the pitfalls? How do you draw them?
What are the bounding boxes, how do you determine intersections, how can you extrude a curve,
in short: how do you do everything that you might want when you do with these curves? That's
what this page is for. Prepare to be mathed!< / p >
< p > —Pomax (or in the tweetworld, < a href = "https://twitter.com/TheRealPomax" > @TheRealPomax< / a > )< / p >
< div className = "note" >
< h2 > This book is open source.< / h2 >
< p > This book is an open source software project, and lives on two github repositorites. The
first is < a href = "https://github.com/pomax/bezierinfo" > https://github.com/pomax/bezierinfo< / a > and
is the purely-for-presentation version you are viewing right now. The other repository is
< a href = "https://github.com/pomax/BezierInfo-2" > https://github.com/pomax/BezierInfo-2< / a > , which
is the development version, housing all the html, javascript, and css. You can fork either
of these, and pretty much do with them as you please, except for passing it off as your
own work wholesale, of course =)< / p >
< h2 > Questions, comments:< / h2 >
2017-02-07 09:58:56 -08:00
< p > If you have suggestions for new sections, hit up the < a href = "https://github.com/pomax/BezierInfo-2/issues" > github
2016-02-20 17:50:30 -08:00
issue tracker< / a > (also reachable from the repo linked to in the upper right). If you have
questions about the material, there's currently no comment section while I'm doing the rewrite,
but you can use the issue tracker for that as well. Once the rewrite is done, I'll add a general
comment section back in, and maybe a more topical "select this section of text and hit the
2017-02-07 09:58:56 -08:00
'question' button to ask a question about it" system. We'll see.< / p >
2016-02-20 17:50:30 -08:00
< / div >
< / section >
< / div >
< / article >
2016-01-16 17:57:16 -08:00
2017-02-07 08:50:42 -08:00
<!-- let's try localization -->
< script src = "https://localize-bezierinfo.herokuapp.com/static/js/jquery-1.11.1.min.js" > < / script >
2017-02-05 11:41:48 -08:00
< script src = "https://localize-bezierinfo.herokuapp.com/pontoon.js" > < / script >
2016-01-16 17:57:16 -08:00
<!-- the actual article is a JS bundle -->
< script src = "article.js" async > < / script >
2015-12-20 15:19:50 -08:00
< / body >
< / html >