|
| 1 | +# Bezier curve |
| 2 | + |
| 3 | +Bezier curves are used in computer graphics to draw shapes, for CSS animation and in many other places. |
| 4 | + |
| 5 | +They are actually a very simple thing, worth to study once and then feel comfortable in the world of vector graphics and advanced animations. |
| 6 | + |
| 7 | +[cut] |
| 8 | + |
| 9 | +## Control points |
| 10 | + |
| 11 | +A [bezier curve](https://en.wikipedia.org/wiki/B%C3%A9zier_curve) is defined by control points. |
| 12 | + |
| 13 | +There may be 2, 3, 4 or more. |
| 14 | + |
| 15 | +For instance, two points curve: |
| 16 | + |
| 17 | + |
| 18 | + |
| 19 | +Three points curve: |
| 20 | + |
| 21 | + |
| 22 | + |
| 23 | +Four points curve: |
| 24 | + |
| 25 | + |
| 26 | + |
| 27 | +If you look closely at these curves, you can immediately notice: |
| 28 | + |
| 29 | +1. **Points are not always on curve.** That's perfectly normal, later we'll see how the curve is built. |
| 30 | +2. **Curve order equals the number of points minus one**. |
| 31 | +For two points we have a linear curve (that's a straight line), for three points -- quadratic curve (parabolic), for three points -- cubic curve. |
| 32 | +3. **A curve is always inside the [convex hull](https://en.wikipedia.org/wiki/Convex_hull) of control points:** |
| 33 | + |
| 34 | +   |
| 35 | + |
| 36 | + Because of that last property, in computer graphics it's possible to optimize intersection tests. If convex hulls do not intersect, then curves do not either. |
| 37 | + |
| 38 | +The main value of Bezier curves for drawing -- by moving the points the curve is changing *in intuitively obvious way*. |
| 39 | + |
| 40 | +Try to move points using a mouse in the example below: |
| 41 | + |
| 42 | +[iframe src="demo.svg?nocpath=1&p=0,0,0.5,0,0.5,1,1,1" height=370] |
| 43 | + |
| 44 | +**As you can notice, the curve stretches along the tangential lines 1 -> 2 и 3 -> 4.** |
| 45 | + |
| 46 | +After some practice it becomes obvious how to place points to get the needed curve. And by connecting several curves we can get practically anything. |
| 47 | + |
| 48 | +Here are some examples: |
| 49 | + |
| 50 | +   |
| 51 | + |
| 52 | +## Maths |
| 53 | + |
| 54 | +A Bezier curve can be described using a mathematical formula. |
| 55 | + |
| 56 | +As we'll see soon -- there's no need to know it. But for completeness -- here you go. |
| 57 | + |
| 58 | +We have coordinates of control points <code>P<sub>i</sub></code>: the first control point has coordinates <code>P<sub>1</sub> = (x<sub>1</sub>, y<sub>1</sub>)</code>, the second: <code>P<sub>2</sub> = (x<sub>2</sub>, y<sub>2</sub>)</code>, and so on. |
| 59 | + |
| 60 | +Then the curve coordinates are described by the equation that depends on the parameter `t` from the segment `[0,1]`. |
| 61 | + |
| 62 | +- For two points: |
| 63 | + |
| 64 | + <code>P = (1-t)P<sub>1</sub> + tP<sub>2</sub></code> |
| 65 | +- For three points: |
| 66 | + |
| 67 | + <code>P = (1−t)<sup>2</sup>P<sub>1</sub> + 2(1−t)tP<sub>2</sub> + t<sup>2</sup>P<sub>3</sub></code> |
| 68 | +- For four points: |
| 69 | + |
| 70 | + <code>P = (1−t)<sup>3</sup>P<sub>1</sub> + 3(1−t)<sup>2</sup>tP<sub>2</sub> +3(1−t)t<sup>2</sup>P<sub>3</sub> + t<sup>3</sup>P<sub>4</sub></code> |
| 71 | + |
| 72 | +These are vector equations. |
| 73 | + |
| 74 | +We can rewrite them coordinate-by-coordinate, for instance the 3-point variant: |
| 75 | + |
| 76 | +- <code>x = (1−t)<sup>2</sup>x<sub>1</sub> + 2(1−t)tx<sub>2</sub> + t<sup>2</sup>x<sub>3</sub></code> |
| 77 | +- <code>y = (1−t)<sup>2</sup>y<sub>1</sub> + 2(1−t)ty<sub>2</sub> + t<sup>2</sup>y<sub>3</sub></code> |
| 78 | + |
| 79 | +Instead of <code>x<sub>1</sub>, y<sub>1</sub>, x<sub>2</sub>, y<sub>2</sub>, x<sub>3</sub>, y<sub>3</sub></code> we should put coordinates of 3 control points, and `t` runs from `0` to `1`. The set of values `(x,y)` for each `t` forms the curve. |
| 80 | + |
| 81 | +That's probably too scientific, not very obvious why curves look like that, and how they depend on control points. |
| 82 | + |
| 83 | +Another drawing algorithm may be easier to understand. |
| 84 | + |
| 85 | +## De Casteljau's algorithm |
| 86 | + |
| 87 | +[De Casteljau's algorithm](https://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm) is identical to the mathematical definition of the curve, but visually shows how it is built. |
| 88 | + |
| 89 | +Let's explain it on the 3-points example. |
| 90 | + |
| 91 | +Here's the demo. Points can be moved by the mouse. Press the "play" button to run it. |
| 92 | + |
| 93 | +[iframe src="demo.svg?p=0,0,0.5,1,1,0&animate=1" height=370] |
| 94 | + |
| 95 | +**De Casteljau's algorithm of building the 3-point bezier curve:** |
| 96 | + |
| 97 | +1. Draw control points. In the demo above they are labeled: `1`, `2`, `3`. |
| 98 | +2. Build segments between control points 1 -> 2 -> 3. In the demo above they are <span style="color:#825E28">brown</span>. |
| 99 | +3. The parameter `t` moves from `0` to `1`. In the example above the step `0.05` is used: the loop goes over `0, 0.05, 0.1, 0.15, ... 0.95, 1`. |
| 100 | + |
| 101 | + For each of these values of `t`: |
| 102 | + |
| 103 | + - On each <span style="color:#825E28">brown</span> segment we take a point located on the distance proportional to `t` from its beginning. As there are two segments, we have two points. |
| 104 | + |
| 105 | + For instance, for `t=0` -- both points will be at the beginning of segments, and for `t=0.25` -- on the 25% of segment length from the beginning, for `t=0.5` -- 50%(the middle), for `t=1` -- in the end of segments. |
| 106 | + |
| 107 | + - Connect the points. On the picture below the connecting segment is painted <span style="color:#167490">blue</span>. |
| 108 | + |
| 109 | + |
| 110 | +| For `t=0.25` | For `t=0.5` | |
| 111 | +| ------------------------ | ---------------------- | |
| 112 | +|  |  | |
| 113 | + |
| 114 | +4. On the <span style="color:#167490">new</span> segment we take a point on the distance proportional to `t`. That is, for `t=0.25` (the left picture) we have a point at the end of the left quarter of the segment, and for `t=0.5` (the right picture) -- in the middle of the segment. On pictures above that point is <span style="color:red">red</span>. |
| 115 | + |
| 116 | +5. As `t` runs from `0` to `1`, every value of `t` adds a point to the curve. The set of such points forms the Bezier curve. It's red and parabolic on the pictures above. |
| 117 | + |
| 118 | +That was a process for 3 points. But the same is for 4 points. |
| 119 | + |
| 120 | +The demo for 4 points (points can be moved by mouse): |
| 121 | + |
| 122 | +[iframe src="demo.svg?p=0,0,0.5,0,0.5,1,1,1&animate=1" height=370] |
| 123 | + |
| 124 | +The algorithm: |
| 125 | + |
| 126 | +- Control points are connected by segments: 1 -> 2, 2 -> 3, 3 -> 4. We have 3 <span style="color:#825E28">brown</span> segments. |
| 127 | +- For each `t` in the interval from `0` to `1`: |
| 128 | + - We take points on these segments on the distance proportional to `t` from the beginning. These points are connected, so that we have two <span style="color:#0A0">green segments</span>. |
| 129 | + - On these segments we take points proportional to `t`. We get one <span style="color:#167490">blue segment</span>. |
| 130 | + - On the blue segment we take a point proportional to `t`. On the example above it's <span style="color:red">red</span>. |
| 131 | +- These points together form the curve. |
| 132 | + |
| 133 | +The algorithm is recursive. For each `t` from `0` to `1` we have first N segments, then take points of them and connect -- N-1 segments and so on till we have one point. These make the curve. |
| 134 | + |
| 135 | +Press the "play" button in the example above to see it in action. |
| 136 | + |
| 137 | +Move examples of curves: |
| 138 | + |
| 139 | +[iframe src="demo.svg?p=0,0,0,0.75,0.25,1,1,1&animate=1" height=370] |
| 140 | + |
| 141 | +With other points: |
| 142 | + |
| 143 | +[iframe src="demo.svg?p=0,0,1,0.5,0,0.5,1,1&animate=1" height=370] |
| 144 | + |
| 145 | +Loop form: |
| 146 | + |
| 147 | +[iframe src="demo.svg?p=0,0,1,0.5,0,1,0.5,0&animate=1" height=370] |
| 148 | + |
| 149 | +Not smooth Bezier curve: |
| 150 | + |
| 151 | +[iframe src="demo.svg?p=0,0,1,1,0,1,1,0&animate=1" height=370] |
| 152 | + |
| 153 | +As the algorithm is recursive, we can build Bezier curves of any order: using 5, 6 or more control points. But on practice they are less useful. Usually we take 2-3 points, and for complex lines glue several curves together. That's simpler for support and in calculations. |
| 154 | + |
| 155 | +```smart header="How to draw a curve *through* given points?" |
| 156 | +We use control points for a Bezier curve. As we can see, they are not on the curve. Or, to be precise, the first and the last one do belong to curve, but others don't. |
| 157 | +
|
| 158 | +Sometimes we have another task: to draw a curve *through several points*, so that all of them are on a single smooth curve. That task is called [interpolation](https://en.wikipedia.org/wiki/Interpolation), and here we don't cover it. |
| 159 | +
|
| 160 | +There are mathematical formulas for such curves, for instance [Lagrange polynomial](https://en.wikipedia.org/wiki/Lagrange_polynomial). |
| 161 | +
|
| 162 | +In computer graphics [spline interpolation](https://en.wikipedia.org/wiki/Spline_interpolation) is often used to build smooth curves that connect many points. |
| 163 | +``` |
| 164 | + |
| 165 | +## Summary |
| 166 | + |
| 167 | +Bezier curves are defined by their control points. |
| 168 | + |
| 169 | +We saw two definitions of Bezier curves: |
| 170 | + |
| 171 | +1. Using a mathematical formulas. |
| 172 | +2. Using a drawing process: De Casteljau's algorithm |
| 173 | + |
| 174 | +Good properties of Bezier curves: |
| 175 | + |
| 176 | +- We can draw smooth lines with a mouse by moving around control points. |
| 177 | +- Complex shapes can be made of several Bezier curves. |
| 178 | + |
| 179 | +Usage: |
| 180 | + |
| 181 | +- In computer graphics, modeling, vector graphic editors. Fonts are described by Bezier curves. |
| 182 | +- In web development -- for graphics on Canvas and in the SVG format. By the way, "live" examples above are written in SVG. They are actually a single SVG document that is given different points as parameters. You can open it in a separate window and see the source: [demo.svg](demo.svg?p=0,0,1,0.5,0,0.5,1,1&animate=1). |
| 183 | +- In CSS animation to describe the path and speed of animation. |
0 commit comments