1
0
mirror of https://github.com/Pomax/BezierInfo-2.git synced 2025-09-02 04:42:43 +02:00

latex color fix + section titles

This commit is contained in:
Pomax
2020-08-08 21:42:45 -07:00
parent 5a3708baa1
commit 0ab39eec07
18 changed files with 295 additions and 208 deletions

View File

@@ -39,10 +39,8 @@ draw() {
onKeyDown() { onKeyDown() {
const key = this.keyboard.currentKey; const key = this.keyboard.currentKey;
if (key === `ArrowUp`) { this.step += 0.1; }
if (key === `ArrowUp`) { this.step++; } if (key === `ArrowDown`) { this.step -= 0.1; }
if (key === `ArrowDown`) { this.step--; }
if (this.step < 1) this.step = 1; if (this.step < 1) this.step = 1;
redraw(); redraw();
} }
@@ -58,8 +56,8 @@ onMouseUp() {
onMouseMove() { onMouseMove() {
if (this.mark) { if (this.mark) {
let diff = this.mark - this.cursor.y, let diff = this.mark - this.cursor.y,
mapped = map(diff, -this.height/2, this.height/2, 1, 10, true); mapped = map(diff, -this.height/2, this.height/2, 0, 10, true);
this.step = mapped | 0; this.step = mapped;
redraw(); redraw();
} }
} }

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 20 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.9 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 16 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.7 KiB

View File

@@ -473,7 +473,7 @@
</section> </section>
<section id="chapters"> <section id="chapters">
<section id="introduction"> <section id="introduction">
<h1>A lightning introduction</h1> <h1><a href="#introduction">A lightning introduction</a></h1>
<p> <p>
Let's start with the good stuff: when we're talking about Bézier Let's start with the good stuff: when we're talking about Bézier
curves, we're talking about the things that you can see in the curves, we're talking about the things that you can see in the
@@ -529,7 +529,7 @@
</p> </p>
</section> </section>
<section id="whatis"> <section id="whatis">
<h1>So what makes a Bézier Curve?</h1> <h1><a href="#whatis">So what makes a Bézier Curve?</a></h1>
<p> <p>
Playing with the points for curves may have given you a feel for how Playing with the points for curves may have given you a feel for how
Bézier curves behave, but what <em>are</em> Bézier curves, really? Bézier curves behave, but what <em>are</em> Bézier curves, really?
@@ -607,7 +607,7 @@
</p> </p>
</section> </section>
<section id="explanation"> <section id="explanation">
<h1>The mathematics of Bézier curves</h1> <h1><a href="#explanation">The mathematics of Bézier curves</a></h1>
<p> <p>
Bézier curves are a form of "parametric" function. Mathematically Bézier curves are a form of "parametric" function. Mathematically
speaking, parametric functions are cheats: a "function" is actually speaking, parametric functions are cheats: a "function" is actually
@@ -782,9 +782,9 @@
</p> </p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/449850dead8abbdd11cd4aec1bac082e.svg" src="images/latex/e107caca1577e44293cd207388ac939c.svg"
width="903px" width="301px"
height="63px" height="60px"
loading="lazy" loading="lazy"
/> />
<p> <p>
@@ -893,7 +893,7 @@ function Bezier(3,t):
</p> </p>
</section> </section>
<section id="control"> <section id="control">
<h1>Controlling Bézier curvatures</h1> <h1><a href="#control">Controlling Bézier curvatures</a></h1>
<p> <p>
Bézier curves are, like all "splines", interpolation functions. This Bézier curves are, like all "splines", interpolation functions. This
means that they take a set of points, and generate values somewhere means that they take a set of points, and generate values somewhere
@@ -961,8 +961,8 @@ function Bezier(3,t):
</p> </p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/e4759ccbc6fd2b21dd5ac7e36c9399fd.svg" src="images/latex/c81557b87f5547db59bc47f1e96409dc.svg"
width="692px" width="473px"
height="40px" height="40px"
loading="lazy" loading="lazy"
/> />
@@ -1007,7 +1007,11 @@ function Bezier(3,t,w[]):
</div> </div>
</section> </section>
<section id="weightcontrol"> <section id="weightcontrol">
<h1>Controlling Bézier curvatures, part 2: Rational Béziers</h1> <h1>
<a href="#weightcontrol"
>Controlling Bézier curvatures, part 2: Rational Béziers</a
>
</h1>
<p> <p>
We can further control Bézier curves by "rationalising" them: that We can further control Bézier curves by "rationalising" them: that
is, adding a "ratio" value in addition to the weight value discussed is, adding a "ratio" value in addition to the weight value discussed
@@ -1028,8 +1032,8 @@ function Bezier(3,t,w[]):
<p>The function for rational Bézier curves has two more terms:</p> <p>The function for rational Bézier curves has two more terms:</p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/d0c52423259ba91a5426324338c83306.svg" src="images/latex/39364a247a023d475d107aaf7b99d80c.svg"
width="587px" width="489px"
height="44px" height="44px"
loading="lazy" loading="lazy"
/> />
@@ -1114,7 +1118,7 @@ function RationalBezier(3,t,w[],r[]):
</div> </div>
</section> </section>
<section id="extended"> <section id="extended">
<h1>The Bézier interval [0,1]</h1> <h1><a href="#extended">The Bézier interval [0,1]</a></h1>
<p> <p>
Now that we know the mathematics behind Bézier curves, there's one Now that we know the mathematics behind Bézier curves, there's one
curious thing that you may have noticed: they always run from curious thing that you may have noticed: they always run from
@@ -1206,7 +1210,7 @@ function RationalBezier(3,t,w[],r[]):
</p> </p>
</section> </section>
<section id="matrix"> <section id="matrix">
<h1>Bézier curvatures as matrix operations</h1> <h1><a href="#matrix">Bézier curvatures as matrix operations</a></h1>
<p> <p>
We can also represent Bézier curves as matrix operations, by We can also represent Bézier curves as matrix operations, by
expressing the Bézier formula as a polynomial basis function and a expressing the Bézier formula as a polynomial basis function and a
@@ -1339,7 +1343,7 @@ function RationalBezier(3,t,w[],r[]):
</p> </p>
</section> </section>
<section id="decasteljau"> <section id="decasteljau">
<h1>de Casteljau's algorithm</h1> <h1><a href="#decasteljau">de Casteljau's algorithm</a></h1>
<p> <p>
If we want to draw Bézier curves, we can run through all values of If we want to draw Bézier curves, we can run through all values of
<code>t</code> from 0 to 1 and then compute the weighted basis <code>t</code> from 0 to 1 and then compute the weighted basis
@@ -1439,7 +1443,7 @@ function RationalBezier(3,t,w[],r[]):
</p> </p>
</section> </section>
<section id="flattening"> <section id="flattening">
<h1>Simplified drawing</h1> <h1><a href="#flattening">Simplified drawing</a></h1>
<p> <p>
We can also simplify the drawing process by "sampling" the curve at We can also simplify the drawing process by "sampling" the curve at
certain points, and then joining those points up with straight certain points, and then joining those points up with straight
@@ -1509,7 +1513,7 @@ function RationalBezier(3,t,w[],r[]):
</div> </div>
</section> </section>
<section id="splitting"> <section id="splitting">
<h1>Splitting curves</h1> <h1><a href="#splitting">Splitting curves</a></h1>
<p> <p>
Using de Casteljau's algorithm, we can also find all the points we Using de Casteljau's algorithm, we can also find all the points we
need to split up a Bézier curve into two, smaller curves, which need to split up a Bézier curve into two, smaller curves, which
@@ -1571,7 +1575,7 @@ function drawCurve(points[], t):
/> />
</section> </section>
<section id="matrixsplit"> <section id="matrixsplit">
<h1>Splitting curves using matrices</h1> <h1><a href="#matrixsplit">Splitting curves using matrices</a></h1>
<p> <p>
Another way to split curves is to exploit the matrix representation Another way to split curves is to exploit the matrix representation
of a Bézier curve. In <a href="#matrix">the section on matrices</a>, of a Bézier curve. In <a href="#matrix">the section on matrices</a>,
@@ -1871,7 +1875,7 @@ function drawCurve(points[], t):
</p> </p>
</section> </section>
<section id="reordering"> <section id="reordering">
<h1>Lowering and elevating curve order</h1> <h1><a href="#reordering">Lowering and elevating curve order</a></h1>
<p> <p>
One interesting property of Bézier curves is that an One interesting property of Bézier curves is that an
<em>n<sup>th</sup></em> order curve can always be perfectly <em>n<sup>th</sup></em> order curve can always be perfectly
@@ -2110,7 +2114,7 @@ function drawCurve(points[], t):
</p> </p>
</section> </section>
<section id="derivatives"> <section id="derivatives">
<h1>Derivatives</h1> <h1><a href="#derivatives">Derivatives</a></h1>
<p> <p>
There's a number of useful things that you can do with Bézier curves There's a number of useful things that you can do with Bézier curves
based on their derivative, and one of the more amusing observations based on their derivative, and one of the more amusing observations
@@ -2235,8 +2239,8 @@ function drawCurve(points[], t):
</p> </p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/183ac1365b1075166b7066b78a17ad74.svg" src="images/latex/b7815b1502029ed9d805b6ba0801a53f.svg"
width="447px" width="300px"
height="109px" height="109px"
loading="lazy" loading="lazy"
/> />
@@ -2254,16 +2258,16 @@ function drawCurve(points[], t):
</p> </p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/950811d35cebee2a39d881e33cbfb1de.svg" src="images/latex/c7b13e6507450b3da7dc4ce3c10c370f.svg"
width="447px" width="295px"
height="71px" height="71px"
loading="lazy" loading="lazy"
/> />
<p>And that's just a summation of lower order curves:</p> <p>And that's just a summation of lower order curves:</p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/894ccddbfcec09dd3d035777e7d23245.svg" src="images/latex/89ceb6024ead6f710e3e0f09d2864f43.svg"
width="807px" width="716px"
height="36px" height="36px"
loading="lazy" loading="lazy"
/> />
@@ -2324,7 +2328,7 @@ function drawCurve(points[], t):
</p> </p>
</section> </section>
<section id="pointvectors"> <section id="pointvectors">
<h1>Tangents and normals</h1> <h1><a href="#pointvectors">Tangents and normals</a></h1>
<p> <p>
If you want to move objects along a curve, or "away from" a curve, If you want to move objects along a curve, or "away from" a curve,
the two vectors you're most interested in are the tangent vector and the two vectors you're most interested in are the tangent vector and
@@ -2460,7 +2464,7 @@ function drawCurve(points[], t):
</div> </div>
</section> </section>
<section id="pointvectors3d"> <section id="pointvectors3d">
<h1>Working with 3D normals</h1> <h1><a href="#pointvectors3d">Working with 3D normals</a></h1>
<p> <p>
Before we move on to the next section we need to spend a little bit Before we move on to the next section we need to spend a little bit
of time on the difference between 2D and 3D. While for many things of time on the difference between 2D and 3D. While for many things
@@ -2721,7 +2725,7 @@ function drawCurve(points[], t):
</p> </p>
</section> </section>
<section id="components"> <section id="components">
<h1>Component functions</h1> <h1><a href="#components">Component functions</a></h1>
<p> <p>
One of the first things people run into when they start using Bézier One of the first things people run into when they start using Bézier
curves in their own programs is "I know how to draw the curve, but curves in their own programs is "I know how to draw the curve, but
@@ -2766,7 +2770,7 @@ function drawCurve(points[], t):
/> />
</section> </section>
<section id="extremities"> <section id="extremities">
<h1>Finding extremities: root finding</h1> <h1><a href="#extremities">Finding extremities: root finding</a></h1>
<p> <p>
Now that we understand (well, superficially anyway) the component Now that we understand (well, superficially anyway) the component
functions, we can find the extremities of our Bézier curve by functions, we can find the extremities of our Bézier curve by
@@ -3100,7 +3104,7 @@ function getCubicRoots(pa, pb, pc, pd) {
/> />
</section> </section>
<section id="boundingbox"> <section id="boundingbox">
<h1>Bounding boxes</h1> <h1><a href="#boundingbox">Bounding boxes</a></h1>
<p> <p>
If we have the extremities, and the start/end points, a simple for If we have the extremities, and the start/end points, a simple for
loop that tests for min/max values for x and y means we have the loop that tests for min/max values for x and y means we have the
@@ -3147,7 +3151,7 @@ function getCubicRoots(pa, pb, pc, pd) {
</p> </p>
</section> </section>
<section id="aligning"> <section id="aligning">
<h1>Aligning curves</h1> <h1><a href="#aligning">Aligning curves</a></h1>
<p> <p>
While there are an incredible number of curves we can define by While there are an incredible number of curves we can define by
varying the x- and y-coordinates for the control points, not all varying the x- and y-coordinates for the control points, not all
@@ -3169,8 +3173,8 @@ function getCubicRoots(pa, pb, pc, pd) {
</p> </p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/eb879c2e965ff4d7c61b70c0c6e5bf87.svg" src="images/latex/d480a9aa41917e5230d432cdbd6899b1.svg"
width="671px" width="476px"
height="40px" height="40px"
loading="lazy" loading="lazy"
/> />
@@ -3181,8 +3185,8 @@ function getCubicRoots(pa, pb, pc, pd) {
</p> </p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/d6438a6372e9f910b0a3059ebfacccc6.svg" src="images/latex/50679d61424222d7b6b97eb3aa663582.svg"
width="655px" width="460px"
height="40px" height="40px"
loading="lazy" loading="lazy"
/> />
@@ -3193,16 +3197,16 @@ function getCubicRoots(pa, pb, pc, pd) {
</p> </p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/6afb072a451e06ddf4b1ff1eb8948e8a.svg" src="images/latex/a9af1c06a00bb3c4af816a138fb0a66d.svg"
width="647px" width="452px"
height="40px" height="40px"
loading="lazy" loading="lazy"
/> />
<p>If we drop all the zero-terms, this gives us:</p> <p>If we drop all the zero-terms, this gives us:</p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/1d44794e3aac3ecb881b559eb8a71fab.svg" src="images/latex/c78b203ff33e5c1606728b552505d61c.svg"
width="528px" width="387px"
height="40px" height="40px"
loading="lazy" loading="lazy"
/> />
@@ -3224,7 +3228,7 @@ function getCubicRoots(pa, pb, pc, pd) {
/> />
</section> </section>
<section id="tightbounds"> <section id="tightbounds">
<h1>Tight boxes</h1> <h1><a href="#tightbounds">Tight boxes</a></h1>
<p> <p>
With our knowledge of bounding boxes, and curve alignment, We can With our knowledge of bounding boxes, and curve alignment, We can
now form the "tight" bounding box for curves. We first align our now form the "tight" bounding box for curves. We first align our
@@ -3258,7 +3262,7 @@ function getCubicRoots(pa, pb, pc, pd) {
</p> </p>
</section> </section>
<section id="inflections"> <section id="inflections">
<h1>Curve inflections</h1> <h1><a href="#inflections">Curve inflections</a></h1>
<p> <p>
Now that we know how to align a curve, there's one more thing we can Now that we know how to align a curve, there's one more thing we can
calculate: inflection points. Imagine we have a variable size circle calculate: inflection points. Imagine we have a variable size circle
@@ -3417,7 +3421,7 @@ function getCubicRoots(pa, pb, pc, pd) {
/> />
</section> </section>
<section id="canonical"> <section id="canonical">
<h1>Canonical form (for cubic curves)</h1> <h1><a href="#canonical">Canonical form (for cubic curves)</a></h1>
<p> <p>
While quadratic curves are relatively simple curves to analyze, the While quadratic curves are relatively simple curves to analyze, the
same cannot be said of the cubic curve. As a curvature is controlled same cannot be said of the cubic curve. As a curvature is controlled
@@ -3794,7 +3798,7 @@ function getCubicRoots(pa, pb, pc, pd) {
/> />
</section> </section>
<section id="yforx"> <section id="yforx">
<h1>Finding Y, given X</h1> <h1><a href="#yforx">Finding Y, given X</a></h1>
<p> <p>
One common task that pops up in things like CSS work, or parametric One common task that pops up in things like CSS work, or parametric
equalisers, or image leveling, or any other number of applications equalisers, or image leveling, or any other number of applications
@@ -3919,7 +3923,7 @@ if (roots.length &gt; 0) {
/> />
</section> </section>
<section id="arclength"> <section id="arclength">
<h1>Arc length</h1> <h1><a href="#arclength">Arc length</a></h1>
<p> <p>
How long is a Bézier curve? As it turns out, that's not actually an How long is a Bézier curve? As it turns out, that's not actually an
easy question, because the answer requires maths that —much like easy question, because the answer requires maths that —much like
@@ -4135,7 +4139,7 @@ if (roots.length &gt; 0) {
/> />
</section> </section>
<section id="arclengthapprox"> <section id="arclengthapprox">
<h1>Approximated arc length</h1> <h1><a href="#arclengthapprox">Approximated arc length</a></h1>
<p> <p>
Sometimes, we don't actually need the precision of a true arc Sometimes, we don't actually need the precision of a true arc
length, and we can get away with simply computing the approximate length, and we can get away with simply computing the approximate
@@ -4173,7 +4177,7 @@ if (roots.length &gt; 0) {
</p> </p>
</section> </section>
<section id="curvature"> <section id="curvature">
<h1>Curvature of a curve</h1> <h1><a href="#curvature">Curvature of a curve</a></h1>
<p> <p>
Imagine we have two curves, and we want to line them in up in a way Imagine we have two curves, and we want to line them in up in a way
that "looks right". What would we use as metric to let a computer that "looks right". What would we use as metric to let a computer
@@ -4372,7 +4376,9 @@ if (roots.length &gt; 0) {
/> />
</section> </section>
<section id="tracing"> <section id="tracing">
<h1>Tracing a curve at fixed distance intervals</h1> <h1>
<a href="#tracing">Tracing a curve at fixed distance intervals</a>
</h1>
<p> <p>
Say you want to draw a curve with a dashed line, rather than a solid Say you want to draw a curve with a dashed line, rather than a solid
line, or you want to move something along the curve at fixed line, or you want to move something along the curve at fixed
@@ -4457,7 +4463,7 @@ if (roots.length &gt; 0) {
</p> </p>
</section> </section>
<section id="intersections"> <section id="intersections">
<h1>Intersections</h1> <h1><a href="#intersections">Intersections</a></h1>
<p> <p>
Let's look at some more things we will want to do with Bézier Let's look at some more things we will want to do with Bézier
curves. Almost immediately after figuring out how to get bounding curves. Almost immediately after figuring out how to get bounding
@@ -4567,7 +4573,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="curveintersection"> <section id="curveintersection">
<h1>Curve/curve intersection</h1> <h1><a href="#curveintersection">Curve/curve intersection</a></h1>
<p> <p>
Using de Casteljau's algorithm to split the curve we can now Using de Casteljau's algorithm to split the curve we can now
implement curve/curve intersection finding using a "divide and implement curve/curve intersection finding using a "divide and
@@ -4652,7 +4658,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="abc"> <section id="abc">
<h1>The projection identity</h1> <h1><a href="#abc">The projection identity</a></h1>
<p> <p>
De Casteljau's algorithm is the pivotal algorithm when it comes to De Casteljau's algorithm is the pivotal algorithm when it comes to
Bézier curves. You can use it not just to split curves, but also to Bézier curves. You can use it not just to split curves, but also to
@@ -4852,7 +4858,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="moulding"> <section id="moulding">
<h1>Manipulating a curve</h1> <h1><a href="#moulding">Manipulating a curve</a></h1>
<p> <p>
Armed with knowledge of the "ABC" relation, we can now update a Armed with knowledge of the "ABC" relation, we can now update a
curve interactively, by letting people click anywhere on the curve, curve interactively, by letting people click anywhere on the curve,
@@ -4938,7 +4944,7 @@ lli = function(line1, line2):
<p>And that's cubic curve manipulation.</p> <p>And that's cubic curve manipulation.</p>
</section> </section>
<section id="pointcurves"> <section id="pointcurves">
<h1>Creating a curve from three points</h1> <h1><a href="#pointcurves">Creating a curve from three points</a></h1>
<p> <p>
Given the preceding section on curve manipulation, we can also Given the preceding section on curve manipulation, we can also
generate quadratic and cubic curves from any three points. However, generate quadratic and cubic curves from any three points. However,
@@ -4999,7 +5005,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="curvefitting"> <section id="curvefitting">
<h1>Curve fitting</h1> <h1><a href="#curvefitting">Curve fitting</a></h1>
<p> <p>
Given the previous section, one question you might have is "what if Given the previous section, one question you might have is "what if
I don't want to guess <code>t</code> values?". After all, plenty of I don't want to guess <code>t</code> values?". After all, plenty of
@@ -5460,7 +5466,9 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="catmullconv"> <section id="catmullconv">
<h1>Bézier curves and Catmull-Rom curves</h1> <h1>
<a href="#catmullconv">Bézier curves and Catmull-Rom curves</a>
</h1>
<p> <p>
Taking an excursion to different splines, the other common design Taking an excursion to different splines, the other common design
curve is the curve is the
@@ -5815,7 +5823,11 @@ lli = function(line1, line2):
/> />
</section> </section>
<section id="catmullmoulding"> <section id="catmullmoulding">
<h1>Creating a Catmull-Rom curve from three points</h1> <h1>
<a href="#catmullmoulding"
>Creating a Catmull-Rom curve from three points</a
>
</h1>
<p> <p>
Now, we saw how to fit a Bézier curve to three points, but if Now, we saw how to fit a Bézier curve to three points, but if
Catmull-Rom curves go through points, why can't we just use those to Catmull-Rom curves go through points, why can't we just use those to
@@ -5869,7 +5881,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="polybezier"> <section id="polybezier">
<h1>Forming poly-Bézier curves</h1> <h1><a href="#polybezier">Forming poly-Bézier curves</a></h1>
<p> <p>
Much like lines can be chained together to form polygons, Bézier Much like lines can be chained together to form polygons, Bézier
curves can be chained together to form poly-Béziers, and the only curves can be chained together to form poly-Béziers, and the only
@@ -6039,7 +6051,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="shapes"> <section id="shapes">
<h1>Boolean shape operations</h1> <h1><a href="#shapes">Boolean shape operations</a></h1>
<p> <p>
We can apply the topics covered so far in this primer to effect We can apply the topics covered so far in this primer to effect
boolean shape operations: getting the union, intersection, or boolean shape operations: getting the union, intersection, or
@@ -6177,7 +6189,9 @@ lli = function(line1, line2):
</Graphic> </Graphic>
</section> </section>
<section id="projections"> <section id="projections">
<h1>Projecting a point onto a Bézier curve</h1> <h1>
<a href="#projections">Projecting a point onto a Bézier curve</a>
</h1>
<p> <p>
Say we have a Bézier curve and some point, not on the curve, of Say we have a Bézier curve and some point, not on the curve, of
which we want to know which <code>t</code> value on the curve gives which we want to know which <code>t</code> value on the curve gives
@@ -6242,7 +6256,7 @@ lli = function(line1, line2):
/> />
</section> </section>
<section id="offsetting"> <section id="offsetting">
<h1>Curve offsetting</h1> <h1><a href="#offsetting">Curve offsetting</a></h1>
<p> <p>
Perhaps you're like me, and you've been writing various small Perhaps you're like me, and you've been writing various small
programs that use Bézier curves in some way or another, and at some programs that use Bézier curves in some way or another, and at some
@@ -6450,7 +6464,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="graduatedoffset"> <section id="graduatedoffset">
<h1>Graduated curve offsetting</h1> <h1><a href="#graduatedoffset">Graduated curve offsetting</a></h1>
<p> <p>
What if we want to do graduated offsetting, starting at some What if we want to do graduated offsetting, starting at some
distance <code>s</code> but ending at some other distance distance <code>s</code> but ending at some other distance
@@ -6517,7 +6531,7 @@ lli = function(line1, line2):
/> />
</section> </section>
<section id="circles"> <section id="circles">
<h1>Circles and quadratic Bézier curves</h1> <h1><a href="#circles">Circles and quadratic Bézier curves</a></h1>
<p> <p>
Circles and Bézier curves are very different beasts, and circles are Circles and Bézier curves are very different beasts, and circles are
infinitely easier to work with than Bézier curves. Their formula is infinitely easier to work with than Bézier curves. Their formula is
@@ -6755,7 +6769,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="circles_cubic"> <section id="circles_cubic">
<h1>Circles and cubic Bézier curves</h1> <h1><a href="#circles_cubic">Circles and cubic Bézier curves</a></h1>
<p> <p>
In the previous section we tried to approximate a circular arc with In the previous section we tried to approximate a circular arc with
a quadratic curve, and it mostly made us unhappy. Cubic curves are a quadratic curve, and it mostly made us unhappy. Cubic curves are
@@ -7090,7 +7104,11 @@ lli = function(line1, line2):
/> />
</section> </section>
<section id="arcapproximation"> <section id="arcapproximation">
<h1>Approximating Bézier curves with circular arcs</h1> <h1>
<a href="#arcapproximation"
>Approximating Bézier curves with circular arcs</a
>
</h1>
<p> <p>
Let's look at doing the exact opposite of the previous section: Let's look at doing the exact opposite of the previous section:
rather than approximating circular arc using Bézier curves, let's rather than approximating circular arc using Bézier curves, let's
@@ -7274,7 +7292,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="bsplines"> <section id="bsplines">
<h1>B-Splines</h1> <h1><a href="#bsplines">B-Splines</a></h1>
<p> <p>
No discussion on Bézier curves is complete without also giving No discussion on Bézier curves is complete without also giving
mention of that other beast in the curve design space: B-Splines. mention of that other beast in the curve design space: B-Splines.
@@ -7825,12 +7843,12 @@ for(let L = 1; L &lt;= order; L++) {
* PLEASE DO NOT LOCALISE THIS FILE * PLEASE DO NOT LOCALISE THIS FILE
* *
* I can't respond to questions that aren't asked in English, so this is one of * I can't respond to questions that aren't asked in English, so this is one of
* the few cases where there is a content.en-GB.md but you shouldn't change it. * the few cases where there is a content.en-GB.md but you should not localize it.
* *
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
</script> </script>
<h1>Comments and questions</h1> <h1><a href="#comments">Comments and questions</a></h1>
<p> <p>
First off, if you enjoyed this book, or you simply found it useful First off, if you enjoyed this book, or you simply found it useful
for something you were trying to get done, and you were wondering for something you were trying to get done, and you were wondering

View File

@@ -399,7 +399,7 @@
</section> </section>
<section id="chapters"> <section id="chapters">
<section id="introduction"> <section id="introduction">
<h1>バッとした導入</h1> <h1><a href="#introduction">バッとした導入</a></h1>
<p> <p>
まずは良い例から始めましょう。ベジエ曲線というのは、下の図に表示されているもののことです。ベジエ曲線はある始点からある終点へと延びており、その曲率は1個以上の「中間」制御点に左右されています。さて、このページの図はどれもインタラクティブになっていますので、ここで曲線をちょっと操作してみましょう。点をドラッグしたとき、曲線の形がそれに応じてどう変化するのか、確かめてみてください。 まずは良い例から始めましょう。ベジエ曲線というのは、下の図に表示されているもののことです。ベジエ曲線はある始点からある終点へと延びており、その曲率は1個以上の「中間」制御点に左右されています。さて、このページの図はどれもインタラクティブになっていますので、ここで曲線をちょっと操作してみましょう。点をドラッグしたとき、曲線の形がそれに応じてどう変化するのか、確かめてみてください。
</p> </p>
@@ -447,7 +447,9 @@
</p> </p>
</section> </section>
<section id="whatis"> <section id="whatis">
<h1>ではベジエ曲線はどうやってできるのでしょう?</h1> <h1>
<a href="#whatis">ではベジエ曲線はどうやってできるのでしょう?</a>
</h1>
<p> <p>
ベジエ曲線がどのように動くのか、点を触ってみて感覚が摑めたかもしれません。では、実際のところベジエ曲線<em>とは</em>いったい何でしょうかこれを説明する方法は2通りありますが、どちらの説明でも行き着く先はまったく同じです。一方は複雑な数学を使うのに対し、もう一方はとても簡単です。というわけで……簡単な説明の方から始めましょう。 ベジエ曲線がどのように動くのか、点を触ってみて感覚が摑めたかもしれません。では、実際のところベジエ曲線<em>とは</em>いったい何でしょうかこれを説明する方法は2通りありますが、どちらの説明でも行き着く先はまったく同じです。一方は複雑な数学を使うのに対し、もう一方はとても簡単です。というわけで……簡単な説明の方から始めましょう。
</p> </p>
@@ -496,7 +498,7 @@
</p> </p>
</section> </section>
<section id="explanation"> <section id="explanation">
<h1>ベジエ曲線の数学</h1> <h1><a href="#explanation">ベジエ曲線の数学</a></h1>
<p> <p>
ベジエ曲線は「パラメトリック」関数の一種です。数学的に言えば、パラメトリック関数というのはインチキです。というのも、「関数」はきっちり定義された用語であり、いくつかの入力を<strong>1つ</strong>の出力に対応させる写像を表すものだからです。いくつかの数値を入れると、1つの数値が出てきます。入れる数値が変わっても、出てくる数値はやはり1つだけです。パラメトリック関数はインチキです。基本的には「じゃあわかった、値を複数個出したいから、関数を複数個使うことにするよ」ということです。例として、ある値<i>x</i>に何らかの操作を行い、別の値へと写す関数があるとします。 ベジエ曲線は「パラメトリック」関数の一種です。数学的に言えば、パラメトリック関数というのはインチキです。というのも、「関数」はきっちり定義された用語であり、いくつかの入力を<strong>1つ</strong>の出力に対応させる写像を表すものだからです。いくつかの数値を入れると、1つの数値が出てきます。入れる数値が変わっても、出てくる数値はやはり1つだけです。パラメトリック関数はインチキです。基本的には「じゃあわかった、値を複数個出したいから、関数を複数個使うことにするよ」ということです。例として、ある値<i>x</i>に何らかの操作を行い、別の値へと写す関数があるとします。
</p> </p>
@@ -607,9 +609,9 @@
</p> </p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/5f6e6bf033c7aa3ae00a935714d14724.svg" src="images/latex/741097d69c182e8742695af23980bd8f.svg"
width="916px" width="288px"
height="65px" height="61px"
loading="lazy" loading="lazy"
/> />
<p> <p>
@@ -693,7 +695,7 @@ function Bezier(3,t):
</p> </p>
</section> </section>
<section id="control"> <section id="control">
<h1>ベジエ曲線の曲率の制御</h1> <h1><a href="#control">ベジエ曲線の曲率の制御</a></h1>
<p> <p>
ベジエ曲線は(すべての「スプライン」と同様に)補間関数です。これは点の集合を受け取って、それらの点のどこか「内側」の値を生成するということです。(このことから、制御点同士を結んで輪郭をつくったとき、その外側に位置する点は決して生成されないことがわかります。なお、この輪郭を曲線の「包」と呼びます。お役立ち情報でした!)実際に、補間関数によって生成された値に対する、各点の寄与の大きさを可視化することができますが、これを見れば、ベジエ曲線のどの場所でどの点が重要になるのかがわかります。 ベジエ曲線は(すべての「スプライン」と同様に)補間関数です。これは点の集合を受け取って、それらの点のどこか「内側」の値を生成するということです。(このことから、制御点同士を結んで輪郭をつくったとき、その外側に位置する点は決して生成されないことがわかります。なお、この輪郭を曲線の「包」と呼びます。お役立ち情報でした!)実際に、補間関数によって生成された値に対する、各点の寄与の大きさを可視化することができますが、これを見れば、ベジエ曲線のどの場所でどの点が重要になるのかがわかります。
</p> </p>
@@ -736,8 +738,8 @@ function Bezier(3,t):
</p> </p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/e4759ccbc6fd2b21dd5ac7e36c9399fd.svg" src="images/latex/c81557b87f5547db59bc47f1e96409dc.svg"
width="692px" width="473px"
height="40px" height="40px"
loading="lazy" loading="lazy"
/> />
@@ -779,7 +781,11 @@ function Bezier(3,t,w[]):
</div> </div>
</section> </section>
<section id="weightcontrol"> <section id="weightcontrol">
<h1>Controlling Bézier curvatures, part 2: Rational Béziers</h1> <h1>
<a href="#weightcontrol"
>Controlling Bézier curvatures, part 2: Rational Béziers</a
>
</h1>
<p> <p>
We can further control Bézier curves by "rationalising" them: that We can further control Bézier curves by "rationalising" them: that
is, adding a "ratio" value in addition to the weight value discussed is, adding a "ratio" value in addition to the weight value discussed
@@ -800,8 +806,8 @@ function Bezier(3,t,w[]):
<p>The function for rational Bézier curves has two more terms:</p> <p>The function for rational Bézier curves has two more terms:</p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/d0c52423259ba91a5426324338c83306.svg" src="images/latex/39364a247a023d475d107aaf7b99d80c.svg"
width="587px" width="489px"
height="44px" height="44px"
loading="lazy" loading="lazy"
/> />
@@ -886,7 +892,7 @@ function RationalBezier(3,t,w[],r[]):
</div> </div>
</section> </section>
<section id="extended"> <section id="extended">
<h1>ベジエ曲線の区間 [0,1]</h1> <h1><a href="#extended">ベジエ曲線の区間 [0,1]</a></h1>
<p> <p>
ここまでの説明で、ベジエ曲線の裏側にある数学がわかりました。しかし、気づいているかもしれませんが、ひとつ引っかかる点があります。ベジエ曲線はいつも<code>t=0</code>から<code>t=1</code>の間を動いていますが、どうしてこの特定の区間なのでしょう? ここまでの説明で、ベジエ曲線の裏側にある数学がわかりました。しかし、気づいているかもしれませんが、ひとつ引っかかる点があります。ベジエ曲線はいつも<code>t=0</code>から<code>t=1</code>の間を動いていますが、どうしてこの特定の区間なのでしょう?
</p> </p>
@@ -951,7 +957,7 @@ function RationalBezier(3,t,w[],r[]):
</p> </p>
</section> </section>
<section id="matrix"> <section id="matrix">
<h1>行列演算としてのベジエ曲線の曲率</h1> <h1><a href="#matrix">行列演算としてのベジエ曲線の曲率</a></h1>
<p> <p>
ベジエ曲線は、行列演算の形でも表現することができます。ベジエ曲線の式を多項式基底と係数行列で表し、実際の座標も行列として表現するのです。これがどういうことを意味しているのか、3次ベジエ曲線について見てみましょう。 ベジエ曲線は、行列演算の形でも表現することができます。ベジエ曲線の式を多項式基底と係数行列で表し、実際の座標も行列として表現するのです。これがどういうことを意味しているのか、3次ベジエ曲線について見てみましょう。
</p> </p>
@@ -1063,7 +1069,7 @@ function RationalBezier(3,t,w[],r[]):
</p> </p>
</section> </section>
<section id="decasteljau"> <section id="decasteljau">
<h1>ド・カステリョのアルゴリズム</h1> <h1><a href="#decasteljau">ド・カステリョのアルゴリズム</a></h1>
<p> <p>
ベジエ曲線を描く場合は、<code>t</code>の値を0から1まで動かしながら重みつき基底関数を計算し、プロットに必要な<code>x/y</code>の値を求めます。しかし、曲線が複雑になればなるほど、計算コストがかかるようになってしまいます。そこでその代わりに、「ド・カステリョのアルゴリズム」を使って曲線を描くこともできます。こちらは幾何学的に曲線を描く方法で、実装も非常に簡単です。実際、鉛筆と定規を使って手描きすることもできるほど、とても簡単な方法なのです。 ベジエ曲線を描く場合は、<code>t</code>の値を0から1まで動かしながら重みつき基底関数を計算し、プロットに必要な<code>x/y</code>の値を求めます。しかし、曲線が複雑になればなるほど、計算コストがかかるようになってしまいます。そこでその代わりに、「ド・カステリョのアルゴリズム」を使って曲線を描くこともできます。こちらは幾何学的に曲線を描く方法で、実装も非常に簡単です。実際、鉛筆と定規を使って手描きすることもできるほど、とても簡単な方法なのです。
</p> </p>
@@ -1136,7 +1142,7 @@ function RationalBezier(3,t,w[],r[]):
/> />
</section> </section>
<section id="flattening"> <section id="flattening">
<h1>簡略化した描画</h1> <h1><a href="#flattening">簡略化した描画</a></h1>
<p> <p>
曲線を複数点で「サンプリング」し、さらにそれを直線で繫げてしまえば、描画の手順を簡略化することができます。単なる一連の直線、つまり「平坦」な線へと曲線を単純化するので、この処理は「平坦化」という名前で知られています。 曲線を複数点で「サンプリング」し、さらにそれを直線で繫げてしまえば、描画の手順を簡略化することができます。単なる一連の直線、つまり「平坦」な線へと曲線を単純化するので、この処理は「平坦化」という名前で知られています。
</p> </p>
@@ -1185,7 +1191,7 @@ function RationalBezier(3,t,w[],r[]):
</div> </div>
</section> </section>
<section id="splitting"> <section id="splitting">
<h1>曲線の分割</h1> <h1><a href="#splitting">曲線の分割</a></h1>
<p> <p>
ベジエ曲線を分割して、繫ぎ合わせたときに元に戻るような小さい2曲線にしたい場合にも、ド・カステリョのアルゴリズムを使えば、これに必要な点をすべて求めることができます。ある値<code>t</code>に対してド・カステリョの骨格を組み立てると、その<code>t</code>で曲線を分割する際に必要になる点がすべて得られます。骨格内部の点のうち、曲線上の点から見て手前側にある点によって一方の曲線が定義され、向こう側にある点によってもう一方の曲線が定義されます。 ベジエ曲線を分割して、繫ぎ合わせたときに元に戻るような小さい2曲線にしたい場合にも、ド・カステリョのアルゴリズムを使えば、これに必要な点をすべて求めることができます。ある値<code>t</code>に対してド・カステリョの骨格を組み立てると、その<code>t</code>で曲線を分割する際に必要になる点がすべて得られます。骨格内部の点のうち、曲線上の点から見て手前側にある点によって一方の曲線が定義され、向こう側にある点によってもう一方の曲線が定義されます。
</p> </p>
@@ -1232,7 +1238,7 @@ function drawCurve(points[], t):
/> />
</section> </section>
<section id="matrixsplit"> <section id="matrixsplit">
<h1>行列による曲線の分割</h1> <h1><a href="#matrixsplit">行列による曲線の分割</a></h1>
<p> <p>
曲線分割には、ベジエ曲線の行列表現を利用する方法もあります。<a 曲線分割には、ベジエ曲線の行列表現を利用する方法もあります。<a
href="#matrix" href="#matrix"
@@ -1487,7 +1493,7 @@ function drawCurve(points[], t):
</p> </p>
</section> </section>
<section id="reordering"> <section id="reordering">
<h1>曲線の次数下げと次数上げ</h1> <h1><a href="#reordering">曲線の次数下げと次数上げ</a></h1>
<p> <p>
ベジエ曲線のおもしろい性質のひとつに、「<em>n</em>次の曲線は常に、<em>n+1</em>次の曲線で完璧に表すことができる」というものがあります。このとき、制御点は新しいものになります。 ベジエ曲線のおもしろい性質のひとつに、「<em>n</em>次の曲線は常に、<em>n+1</em>次の曲線で完璧に表すことができる」というものがあります。このとき、制御点は新しいものになります。
</p> </p>
@@ -1526,7 +1532,7 @@ function drawCurve(points[], t):
</p> </p>
</section> </section>
<section id="derivatives"> <section id="derivatives">
<h1>Derivatives</h1> <h1><a href="#derivatives">Derivatives</a></h1>
<p> <p>
There's a number of useful things that you can do with Bézier curves There's a number of useful things that you can do with Bézier curves
based on their derivative, and one of the more amusing observations based on their derivative, and one of the more amusing observations
@@ -1651,8 +1657,8 @@ function drawCurve(points[], t):
</p> </p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/183ac1365b1075166b7066b78a17ad74.svg" src="images/latex/b7815b1502029ed9d805b6ba0801a53f.svg"
width="447px" width="300px"
height="109px" height="109px"
loading="lazy" loading="lazy"
/> />
@@ -1670,16 +1676,16 @@ function drawCurve(points[], t):
</p> </p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/950811d35cebee2a39d881e33cbfb1de.svg" src="images/latex/c7b13e6507450b3da7dc4ce3c10c370f.svg"
width="447px" width="295px"
height="71px" height="71px"
loading="lazy" loading="lazy"
/> />
<p>And that's just a summation of lower order curves:</p> <p>And that's just a summation of lower order curves:</p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/894ccddbfcec09dd3d035777e7d23245.svg" src="images/latex/89ceb6024ead6f710e3e0f09d2864f43.svg"
width="807px" width="716px"
height="36px" height="36px"
loading="lazy" loading="lazy"
/> />
@@ -1740,7 +1746,7 @@ function drawCurve(points[], t):
</p> </p>
</section> </section>
<section id="pointvectors"> <section id="pointvectors">
<h1>Tangents and normals</h1> <h1><a href="#pointvectors">Tangents and normals</a></h1>
<p> <p>
If you want to move objects along a curve, or "away from" a curve, If you want to move objects along a curve, or "away from" a curve,
the two vectors you're most interested in are the tangent vector and the two vectors you're most interested in are the tangent vector and
@@ -1876,7 +1882,7 @@ function drawCurve(points[], t):
</div> </div>
</section> </section>
<section id="pointvectors3d"> <section id="pointvectors3d">
<h1>Working with 3D normals</h1> <h1><a href="#pointvectors3d">Working with 3D normals</a></h1>
<p> <p>
Before we move on to the next section we need to spend a little bit Before we move on to the next section we need to spend a little bit
of time on the difference between 2D and 3D. While for many things of time on the difference between 2D and 3D. While for many things
@@ -2137,7 +2143,7 @@ function drawCurve(points[], t):
</p> </p>
</section> </section>
<section id="components"> <section id="components">
<h1>Component functions</h1> <h1><a href="#components">Component functions</a></h1>
<p> <p>
One of the first things people run into when they start using Bézier One of the first things people run into when they start using Bézier
curves in their own programs is "I know how to draw the curve, but curves in their own programs is "I know how to draw the curve, but
@@ -2182,7 +2188,7 @@ function drawCurve(points[], t):
/> />
</section> </section>
<section id="extremities"> <section id="extremities">
<h1>Finding extremities: root finding</h1> <h1><a href="#extremities">Finding extremities: root finding</a></h1>
<p> <p>
Now that we understand (well, superficially anyway) the component Now that we understand (well, superficially anyway) the component
functions, we can find the extremities of our Bézier curve by functions, we can find the extremities of our Bézier curve by
@@ -2516,7 +2522,7 @@ function getCubicRoots(pa, pb, pc, pd) {
/> />
</section> </section>
<section id="boundingbox"> <section id="boundingbox">
<h1>Bounding boxes</h1> <h1><a href="#boundingbox">Bounding boxes</a></h1>
<p> <p>
If we have the extremities, and the start/end points, a simple for If we have the extremities, and the start/end points, a simple for
loop that tests for min/max values for x and y means we have the loop that tests for min/max values for x and y means we have the
@@ -2563,7 +2569,7 @@ function getCubicRoots(pa, pb, pc, pd) {
</p> </p>
</section> </section>
<section id="aligning"> <section id="aligning">
<h1>Aligning curves</h1> <h1><a href="#aligning">Aligning curves</a></h1>
<p> <p>
While there are an incredible number of curves we can define by While there are an incredible number of curves we can define by
varying the x- and y-coordinates for the control points, not all varying the x- and y-coordinates for the control points, not all
@@ -2585,8 +2591,8 @@ function getCubicRoots(pa, pb, pc, pd) {
</p> </p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/eb879c2e965ff4d7c61b70c0c6e5bf87.svg" src="images/latex/d480a9aa41917e5230d432cdbd6899b1.svg"
width="671px" width="476px"
height="40px" height="40px"
loading="lazy" loading="lazy"
/> />
@@ -2597,8 +2603,8 @@ function getCubicRoots(pa, pb, pc, pd) {
</p> </p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/d6438a6372e9f910b0a3059ebfacccc6.svg" src="images/latex/50679d61424222d7b6b97eb3aa663582.svg"
width="655px" width="460px"
height="40px" height="40px"
loading="lazy" loading="lazy"
/> />
@@ -2609,16 +2615,16 @@ function getCubicRoots(pa, pb, pc, pd) {
</p> </p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/6afb072a451e06ddf4b1ff1eb8948e8a.svg" src="images/latex/a9af1c06a00bb3c4af816a138fb0a66d.svg"
width="647px" width="452px"
height="40px" height="40px"
loading="lazy" loading="lazy"
/> />
<p>If we drop all the zero-terms, this gives us:</p> <p>If we drop all the zero-terms, this gives us:</p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/1d44794e3aac3ecb881b559eb8a71fab.svg" src="images/latex/c78b203ff33e5c1606728b552505d61c.svg"
width="528px" width="387px"
height="40px" height="40px"
loading="lazy" loading="lazy"
/> />
@@ -2640,7 +2646,7 @@ function getCubicRoots(pa, pb, pc, pd) {
/> />
</section> </section>
<section id="tightbounds"> <section id="tightbounds">
<h1>Tight boxes</h1> <h1><a href="#tightbounds">Tight boxes</a></h1>
<p> <p>
With our knowledge of bounding boxes, and curve alignment, We can With our knowledge of bounding boxes, and curve alignment, We can
now form the "tight" bounding box for curves. We first align our now form the "tight" bounding box for curves. We first align our
@@ -2674,7 +2680,7 @@ function getCubicRoots(pa, pb, pc, pd) {
</p> </p>
</section> </section>
<section id="inflections"> <section id="inflections">
<h1>Curve inflections</h1> <h1><a href="#inflections">Curve inflections</a></h1>
<p> <p>
Now that we know how to align a curve, there's one more thing we can Now that we know how to align a curve, there's one more thing we can
calculate: inflection points. Imagine we have a variable size circle calculate: inflection points. Imagine we have a variable size circle
@@ -2833,7 +2839,7 @@ function getCubicRoots(pa, pb, pc, pd) {
/> />
</section> </section>
<section id="canonical"> <section id="canonical">
<h1>Canonical form (for cubic curves)</h1> <h1><a href="#canonical">Canonical form (for cubic curves)</a></h1>
<p> <p>
While quadratic curves are relatively simple curves to analyze, the While quadratic curves are relatively simple curves to analyze, the
same cannot be said of the cubic curve. As a curvature is controlled same cannot be said of the cubic curve. As a curvature is controlled
@@ -3210,7 +3216,7 @@ function getCubicRoots(pa, pb, pc, pd) {
/> />
</section> </section>
<section id="yforx"> <section id="yforx">
<h1>Finding Y, given X</h1> <h1><a href="#yforx">Finding Y, given X</a></h1>
<p> <p>
One common task that pops up in things like CSS work, or parametric One common task that pops up in things like CSS work, or parametric
equalisers, or image leveling, or any other number of applications equalisers, or image leveling, or any other number of applications
@@ -3335,7 +3341,7 @@ if (roots.length &gt; 0) {
/> />
</section> </section>
<section id="arclength"> <section id="arclength">
<h1>Arc length</h1> <h1><a href="#arclength">Arc length</a></h1>
<p> <p>
How long is a Bézier curve? As it turns out, that's not actually an How long is a Bézier curve? As it turns out, that's not actually an
easy question, because the answer requires maths that —much like easy question, because the answer requires maths that —much like
@@ -3551,7 +3557,7 @@ if (roots.length &gt; 0) {
/> />
</section> </section>
<section id="arclengthapprox"> <section id="arclengthapprox">
<h1>Approximated arc length</h1> <h1><a href="#arclengthapprox">Approximated arc length</a></h1>
<p> <p>
Sometimes, we don't actually need the precision of a true arc Sometimes, we don't actually need the precision of a true arc
length, and we can get away with simply computing the approximate length, and we can get away with simply computing the approximate
@@ -3589,7 +3595,7 @@ if (roots.length &gt; 0) {
</p> </p>
</section> </section>
<section id="curvature"> <section id="curvature">
<h1>Curvature of a curve</h1> <h1><a href="#curvature">Curvature of a curve</a></h1>
<p> <p>
Imagine we have two curves, and we want to line them in up in a way Imagine we have two curves, and we want to line them in up in a way
that "looks right". What would we use as metric to let a computer that "looks right". What would we use as metric to let a computer
@@ -3788,7 +3794,9 @@ if (roots.length &gt; 0) {
/> />
</section> </section>
<section id="tracing"> <section id="tracing">
<h1>Tracing a curve at fixed distance intervals</h1> <h1>
<a href="#tracing">Tracing a curve at fixed distance intervals</a>
</h1>
<p> <p>
Say you want to draw a curve with a dashed line, rather than a solid Say you want to draw a curve with a dashed line, rather than a solid
line, or you want to move something along the curve at fixed line, or you want to move something along the curve at fixed
@@ -3873,7 +3881,7 @@ if (roots.length &gt; 0) {
</p> </p>
</section> </section>
<section id="intersections"> <section id="intersections">
<h1>Intersections</h1> <h1><a href="#intersections">Intersections</a></h1>
<p> <p>
Let's look at some more things we will want to do with Bézier Let's look at some more things we will want to do with Bézier
curves. Almost immediately after figuring out how to get bounding curves. Almost immediately after figuring out how to get bounding
@@ -3983,7 +3991,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="curveintersection"> <section id="curveintersection">
<h1>Curve/curve intersection</h1> <h1><a href="#curveintersection">Curve/curve intersection</a></h1>
<p> <p>
Using de Casteljau's algorithm to split the curve we can now Using de Casteljau's algorithm to split the curve we can now
implement curve/curve intersection finding using a "divide and implement curve/curve intersection finding using a "divide and
@@ -4068,7 +4076,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="abc"> <section id="abc">
<h1>The projection identity</h1> <h1><a href="#abc">The projection identity</a></h1>
<p> <p>
De Casteljau's algorithm is the pivotal algorithm when it comes to De Casteljau's algorithm is the pivotal algorithm when it comes to
Bézier curves. You can use it not just to split curves, but also to Bézier curves. You can use it not just to split curves, but also to
@@ -4268,7 +4276,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="moulding"> <section id="moulding">
<h1>Manipulating a curve</h1> <h1><a href="#moulding">Manipulating a curve</a></h1>
<p> <p>
Armed with knowledge of the "ABC" relation, we can now update a Armed with knowledge of the "ABC" relation, we can now update a
curve interactively, by letting people click anywhere on the curve, curve interactively, by letting people click anywhere on the curve,
@@ -4354,7 +4362,7 @@ lli = function(line1, line2):
<p>And that's cubic curve manipulation.</p> <p>And that's cubic curve manipulation.</p>
</section> </section>
<section id="pointcurves"> <section id="pointcurves">
<h1>Creating a curve from three points</h1> <h1><a href="#pointcurves">Creating a curve from three points</a></h1>
<p> <p>
Given the preceding section on curve manipulation, we can also Given the preceding section on curve manipulation, we can also
generate quadratic and cubic curves from any three points. However, generate quadratic and cubic curves from any three points. However,
@@ -4415,7 +4423,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="curvefitting"> <section id="curvefitting">
<h1>Curve fitting</h1> <h1><a href="#curvefitting">Curve fitting</a></h1>
<p> <p>
Given the previous section, one question you might have is "what if Given the previous section, one question you might have is "what if
I don't want to guess <code>t</code> values?". After all, plenty of I don't want to guess <code>t</code> values?". After all, plenty of
@@ -4876,7 +4884,9 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="catmullconv"> <section id="catmullconv">
<h1>Bézier curves and Catmull-Rom curves</h1> <h1>
<a href="#catmullconv">Bézier curves and Catmull-Rom curves</a>
</h1>
<p> <p>
Taking an excursion to different splines, the other common design Taking an excursion to different splines, the other common design
curve is the curve is the
@@ -5231,7 +5241,11 @@ lli = function(line1, line2):
/> />
</section> </section>
<section id="catmullmoulding"> <section id="catmullmoulding">
<h1>Creating a Catmull-Rom curve from three points</h1> <h1>
<a href="#catmullmoulding"
>Creating a Catmull-Rom curve from three points</a
>
</h1>
<p> <p>
Now, we saw how to fit a Bézier curve to three points, but if Now, we saw how to fit a Bézier curve to three points, but if
Catmull-Rom curves go through points, why can't we just use those to Catmull-Rom curves go through points, why can't we just use those to
@@ -5285,7 +5299,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="polybezier"> <section id="polybezier">
<h1>Forming poly-Bézier curves</h1> <h1><a href="#polybezier">Forming poly-Bézier curves</a></h1>
<p> <p>
Much like lines can be chained together to form polygons, Bézier Much like lines can be chained together to form polygons, Bézier
curves can be chained together to form poly-Béziers, and the only curves can be chained together to form poly-Béziers, and the only
@@ -5455,7 +5469,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="shapes"> <section id="shapes">
<h1>Boolean shape operations</h1> <h1><a href="#shapes">Boolean shape operations</a></h1>
<p> <p>
We can apply the topics covered so far in this primer to effect We can apply the topics covered so far in this primer to effect
boolean shape operations: getting the union, intersection, or boolean shape operations: getting the union, intersection, or
@@ -5593,7 +5607,9 @@ lli = function(line1, line2):
</Graphic> </Graphic>
</section> </section>
<section id="projections"> <section id="projections">
<h1>Projecting a point onto a Bézier curve</h1> <h1>
<a href="#projections">Projecting a point onto a Bézier curve</a>
</h1>
<p> <p>
Say we have a Bézier curve and some point, not on the curve, of Say we have a Bézier curve and some point, not on the curve, of
which we want to know which <code>t</code> value on the curve gives which we want to know which <code>t</code> value on the curve gives
@@ -5658,7 +5674,7 @@ lli = function(line1, line2):
/> />
</section> </section>
<section id="offsetting"> <section id="offsetting">
<h1>Curve offsetting</h1> <h1><a href="#offsetting">Curve offsetting</a></h1>
<p> <p>
Perhaps you're like me, and you've been writing various small Perhaps you're like me, and you've been writing various small
programs that use Bézier curves in some way or another, and at some programs that use Bézier curves in some way or another, and at some
@@ -5866,7 +5882,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="graduatedoffset"> <section id="graduatedoffset">
<h1>Graduated curve offsetting</h1> <h1><a href="#graduatedoffset">Graduated curve offsetting</a></h1>
<p> <p>
What if we want to do graduated offsetting, starting at some What if we want to do graduated offsetting, starting at some
distance <code>s</code> but ending at some other distance distance <code>s</code> but ending at some other distance
@@ -5933,7 +5949,7 @@ lli = function(line1, line2):
/> />
</section> </section>
<section id="circles"> <section id="circles">
<h1>Circles and quadratic Bézier curves</h1> <h1><a href="#circles">Circles and quadratic Bézier curves</a></h1>
<p> <p>
Circles and Bézier curves are very different beasts, and circles are Circles and Bézier curves are very different beasts, and circles are
infinitely easier to work with than Bézier curves. Their formula is infinitely easier to work with than Bézier curves. Their formula is
@@ -6171,7 +6187,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="circles_cubic"> <section id="circles_cubic">
<h1>Circles and cubic Bézier curves</h1> <h1><a href="#circles_cubic">Circles and cubic Bézier curves</a></h1>
<p> <p>
In the previous section we tried to approximate a circular arc with In the previous section we tried to approximate a circular arc with
a quadratic curve, and it mostly made us unhappy. Cubic curves are a quadratic curve, and it mostly made us unhappy. Cubic curves are
@@ -6506,7 +6522,11 @@ lli = function(line1, line2):
/> />
</section> </section>
<section id="arcapproximation"> <section id="arcapproximation">
<h1>Approximating Bézier curves with circular arcs</h1> <h1>
<a href="#arcapproximation"
>Approximating Bézier curves with circular arcs</a
>
</h1>
<p> <p>
Let's look at doing the exact opposite of the previous section: Let's look at doing the exact opposite of the previous section:
rather than approximating circular arc using Bézier curves, let's rather than approximating circular arc using Bézier curves, let's
@@ -6690,7 +6710,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="bsplines"> <section id="bsplines">
<h1>B-Splines</h1> <h1><a href="#bsplines">B-Splines</a></h1>
<p> <p>
No discussion on Bézier curves is complete without also giving No discussion on Bézier curves is complete without also giving
mention of that other beast in the curve design space: B-Splines. mention of that other beast in the curve design space: B-Splines.
@@ -7241,12 +7261,12 @@ for(let L = 1; L &lt;= order; L++) {
* PLEASE DO NOT LOCALISE THIS FILE * PLEASE DO NOT LOCALISE THIS FILE
* *
* I can't respond to questions that aren't asked in English, so this is one of * I can't respond to questions that aren't asked in English, so this is one of
* the few cases where there is a content.en-GB.md but you shouldn't change it. * the few cases where there is a content.en-GB.md but you should not localize it.
* *
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
</script> </script>
<h1>Comments and questions</h1> <h1><a href="#comments">Comments and questions</a></h1>
<p> <p>
First off, if you enjoyed this book, or you simply found it useful First off, if you enjoyed this book, or you simply found it useful
for something you were trying to get done, and you were wondering for something you were trying to get done, and you were wondering

View File

@@ -29,6 +29,11 @@ h1 {
margin-right: 1em; margin-right: 1em;
} }
#chapters section > h1 > a {
text-decoration: none;
color: inherit;
}
graphics-element { graphics-element {
background: #e8e8e8; background: #e8e8e8;
} }

View File

@@ -29,7 +29,10 @@ export default async function createIndexPages(
if (content) { if (content) {
let title = content.match(/<h1>([^<]+)<\/h1>/)[1]; let title = content.match(/<h1>([^<]+)<\/h1>/)[1];
toc[section] = `<li><a href="#${section}">${title}</a></li>`; toc[section] = `<li><a href="#${section}">${title}</a></li>`;
return `<section id="${section}">${content}</section>`; // hyperlinked section titles please
return `<section id="${section}">${content
.replace(`<h1>`, `<h1><a href="#${section}">`)
.replace(`</h1>`, `</a></h1>`)}</section>`;
} }
return ``; return ``;
}); });

View File

@@ -24,6 +24,8 @@ fs.ensureDirSync(sourceDir);
* in. * in.
*/ */
export default async function latexToSVG(latex, chapter, localeStrings, block) { export default async function latexToSVG(latex, chapter, localeStrings, block) {
latex = colorPreProcess(latex);
const locale = localeStrings.getCurrentLocale(); const locale = localeStrings.getCurrentLocale();
const hash = createHash(`md5`).update(latex).digest(`hex`); const hash = createHash(`md5`).update(latex).digest(`hex`);
@@ -149,3 +151,15 @@ function runCmd(cmd, hash) {
process.exit(1); process.exit(1);
} }
} }
// This function converst things like RED[a] into real LaTeX.
function colorPreProcess(input) {
var regexp = new RegExp(`([A-Z]+)\\[([^\\]]+)\\]`, `g`);
var output = input.replace(regexp, function (_, color, content) {
if (content.indexOf(` `) !== -1) {
content = ` ${content}`;
}
return `{\\color{${color.toLowerCase()}}${content.replace(/ /g, "\\ ")}}`;
});
return output;
}

View File

@@ -388,7 +388,7 @@
</section> </section>
<section id="chapters"> <section id="chapters">
<section id="introduction"> <section id="introduction">
<h1>简单介绍</h1> <h1><a href="#introduction">简单介绍</a></h1>
<p> <p>
让我们有个好的开始:当我们在谈论贝塞尔曲线的时候,所指的就是你在如下图像看到的东西。它们从某些起点开始,到终点结束,并且受到一个或多个的“中间”控制点的影响。本页面上的图形都是可交互的,你可以拖动这些点,看看这些形状在你的操作下会怎么变化。 让我们有个好的开始:当我们在谈论贝塞尔曲线的时候,所指的就是你在如下图像看到的东西。它们从某些起点开始,到终点结束,并且受到一个或多个的“中间”控制点的影响。本页面上的图形都是可交互的,你可以拖动这些点,看看这些形状在你的操作下会怎么变化。
</p> </p>
@@ -434,7 +434,7 @@
</p> </p>
</section> </section>
<section id="whatis"> <section id="whatis">
<h1>什么构成了贝塞尔曲线?</h1> <h1><a href="#whatis">什么构成了贝塞尔曲线?</a></h1>
<p> <p>
操作点的移动,看看曲线的变化,可能让你感受到了贝塞尔曲线是如何表现的。但贝塞尔曲线究竟<em></em>什么呢?有两种方式来解释贝塞尔曲线,并且可以证明它们完全相等,但是其中一种用到了复杂的数学,另外一种比较简单。所以...我们先从简单的开始吧: 操作点的移动,看看曲线的变化,可能让你感受到了贝塞尔曲线是如何表现的。但贝塞尔曲线究竟<em></em>什么呢?有两种方式来解释贝塞尔曲线,并且可以证明它们完全相等,但是其中一种用到了复杂的数学,另外一种比较简单。所以...我们先从简单的开始吧:
</p> </p>
@@ -483,7 +483,7 @@
</p> </p>
</section> </section>
<section id="explanation"> <section id="explanation">
<h1>贝塞尔曲线的数学原理</h1> <h1><a href="#explanation">贝塞尔曲线的数学原理</a></h1>
<p> <p>
贝塞尔曲线是“参数”方程的一种形式。从数学上讲,参数方程作弊了:“方程”实际上是一个从输入到<strong>唯一</strong>输出的、良好定义的映射关系。几个输入进来,一个输出返回。改变输入变量,还是只有一个输出值。参数方程在这里作弊了。它们基本上干了这么件事,“好吧,我们想要更多的输出值,所以我们用了多个方程”。举个例子:假如我们有一个方程,通过一些计算,将假设为<i>x</i>的一些值映射到另外的值: 贝塞尔曲线是“参数”方程的一种形式。从数学上讲,参数方程作弊了:“方程”实际上是一个从输入到<strong>唯一</strong>输出的、良好定义的映射关系。几个输入进来,一个输出返回。改变输入变量,还是只有一个输出值。参数方程在这里作弊了。它们基本上干了这么件事,“好吧,我们想要更多的输出值,所以我们用了多个方程”。举个例子:假如我们有一个方程,通过一些计算,将假设为<i>x</i>的一些值映射到另外的值:
</p> </p>
@@ -592,9 +592,9 @@
</p> </p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/449850dead8abbdd11cd4aec1bac082e.svg" src="images/latex/e107caca1577e44293cd207388ac939c.svg"
width="903px" width="301px"
height="63px" height="60px"
loading="lazy" loading="lazy"
/> />
<p> <p>
@@ -676,7 +676,7 @@ function Bezier(3,t):
</p> </p>
</section> </section>
<section id="control"> <section id="control">
<h1>控制贝塞尔的曲率</h1> <h1><a href="#control">控制贝塞尔的曲率</a></h1>
<p> <p>
贝塞尔曲线是插值方程(就像所有曲线一样),这表示它们取一系列的点,生成一些处于这些点之间的值。(一个推论就是你永远无法生成一个位于这些控制点轮廓线外面的点,更普遍是称为曲线的外壳。这信息很有用!)实际上,我们可以将每个点对方程产生的曲线做出的贡献进行可视化,因此可以看出曲线上哪些点是重要的,它们处于什么位置。 贝塞尔曲线是插值方程(就像所有曲线一样),这表示它们取一系列的点,生成一些处于这些点之间的值。(一个推论就是你永远无法生成一个位于这些控制点轮廓线外面的点,更普遍是称为曲线的外壳。这信息很有用!)实际上,我们可以将每个点对方程产生的曲线做出的贡献进行可视化,因此可以看出曲线上哪些点是重要的,它们处于什么位置。
</p> </p>
@@ -719,8 +719,8 @@ function Bezier(3,t):
</p> </p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/e4759ccbc6fd2b21dd5ac7e36c9399fd.svg" src="images/latex/c81557b87f5547db59bc47f1e96409dc.svg"
width="692px" width="473px"
height="40px" height="40px"
loading="lazy" loading="lazy"
/> />
@@ -762,7 +762,11 @@ function Bezier(3,t,w[]):
</div> </div>
</section> </section>
<section id="weightcontrol"> <section id="weightcontrol">
<h1>Controlling Bézier curvatures, part 2: Rational Béziers</h1> <h1>
<a href="#weightcontrol"
>Controlling Bézier curvatures, part 2: Rational Béziers</a
>
</h1>
<p> <p>
We can further control Bézier curves by "rationalising" them: that We can further control Bézier curves by "rationalising" them: that
is, adding a "ratio" value in addition to the weight value discussed is, adding a "ratio" value in addition to the weight value discussed
@@ -783,8 +787,8 @@ function Bezier(3,t,w[]):
<p>The function for rational Bézier curves has two more terms:</p> <p>The function for rational Bézier curves has two more terms:</p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/d0c52423259ba91a5426324338c83306.svg" src="images/latex/39364a247a023d475d107aaf7b99d80c.svg"
width="587px" width="489px"
height="44px" height="44px"
loading="lazy" loading="lazy"
/> />
@@ -869,7 +873,7 @@ function RationalBezier(3,t,w[],r[]):
</div> </div>
</section> </section>
<section id="extended"> <section id="extended">
<h1>贝塞尔区间[0,1]</h1> <h1><a href="#extended">贝塞尔区间[0,1]</a></h1>
<p> <p>
既然我们知道了贝塞尔曲线背后的数学原理,你可能会注意到一件奇怪的事:它们都是从<code>t=0</code><code>t=1</code>。为什么是这个特殊区间? 既然我们知道了贝塞尔曲线背后的数学原理,你可能会注意到一件奇怪的事:它们都是从<code>t=0</code><code>t=1</code>。为什么是这个特殊区间?
</p> </p>
@@ -934,7 +938,7 @@ function RationalBezier(3,t,w[],r[]):
</p> </p>
</section> </section>
<section id="matrix"> <section id="matrix">
<h1>用矩阵运算来表示贝塞尔曲率</h1> <h1><a href="#matrix">用矩阵运算来表示贝塞尔曲率</a></h1>
<p> <p>
通过将贝塞尔公式表示成一个多项式基本方程、系数矩阵以及实际的坐标,我们也可以用矩阵运算来表示贝塞尔。让我们看一下这对三次曲线来说有什么含义: 通过将贝塞尔公式表示成一个多项式基本方程、系数矩阵以及实际的坐标,我们也可以用矩阵运算来表示贝塞尔。让我们看一下这对三次曲线来说有什么含义:
</p> </p>
@@ -1037,7 +1041,7 @@ function RationalBezier(3,t,w[],r[]):
</p> </p>
</section> </section>
<section id="decasteljau"> <section id="decasteljau">
<h1>de Casteljau's 算法</h1> <h1><a href="#decasteljau">de Casteljau's 算法</a></h1>
<p> <p>
要绘制贝塞尔曲线,我们可以从<code>0</code><code>1</code>遍历<code>t</code>的所有值,计算权重函数,得到需要画的<code>x/y</code>值。但曲线越复杂计算量也变得越大。我们可以利用“de 要绘制贝塞尔曲线,我们可以从<code>0</code><code>1</code>遍历<code>t</code>的所有值,计算权重函数,得到需要画的<code>x/y</code>值。但曲线越复杂计算量也变得越大。我们可以利用“de
Casteljau算法",这是一种几何画法,并且易于实现。实际上,你可以轻易地用笔和尺画出曲线。 Casteljau算法",这是一种几何画法,并且易于实现。实际上,你可以轻易地用笔和尺画出曲线。
@@ -1103,7 +1107,7 @@ function RationalBezier(3,t,w[],r[]):
</p> </p>
</section> </section>
<section id="flattening"> <section id="flattening">
<h1>简化绘图</h1> <h1><a href="#flattening">简化绘图</a></h1>
<p> <p>
我们可以简化绘制的过程,先在具体的位置“采样”曲线,然后用线段把这些点连接起来。由于我们是将曲线转换成一系列“平整的”直线,故将这个过程称之为“拉平(flattening)”。 我们可以简化绘制的过程,先在具体的位置“采样”曲线,然后用线段把这些点连接起来。由于我们是将曲线转换成一系列“平整的”直线,故将这个过程称之为“拉平(flattening)”。
</p> </p>
@@ -1150,7 +1154,7 @@ function RationalBezier(3,t,w[],r[]):
</div> </div>
</section> </section>
<section id="splitting"> <section id="splitting">
<h1>分割曲线</h1> <h1><a href="#splitting">分割曲线</a></h1>
<p> <p>
使用 de Casteljau 使用 de Casteljau
算法我们也可以将一条贝塞尔曲线分割成两条更小的曲线,二者拼接起来即可形成原来的曲线。当采用某个 算法我们也可以将一条贝塞尔曲线分割成两条更小的曲线,二者拼接起来即可形成原来的曲线。当采用某个
@@ -1204,7 +1208,7 @@ function drawCurve(points[], t):
/> />
</section> </section>
<section id="matrixsplit"> <section id="matrixsplit">
<h1>Splitting curves using matrices</h1> <h1><a href="#matrixsplit">Splitting curves using matrices</a></h1>
<p> <p>
Another way to split curves is to exploit the matrix representation Another way to split curves is to exploit the matrix representation
of a Bézier curve. In <a href="#matrix">the section on matrices</a>, of a Bézier curve. In <a href="#matrix">the section on matrices</a>,
@@ -1504,7 +1508,7 @@ function drawCurve(points[], t):
</p> </p>
</section> </section>
<section id="reordering"> <section id="reordering">
<h1>Lowering and elevating curve order</h1> <h1><a href="#reordering">Lowering and elevating curve order</a></h1>
<p> <p>
One interesting property of Bézier curves is that an One interesting property of Bézier curves is that an
<em>n<sup>th</sup></em> order curve can always be perfectly <em>n<sup>th</sup></em> order curve can always be perfectly
@@ -1743,7 +1747,7 @@ function drawCurve(points[], t):
</p> </p>
</section> </section>
<section id="derivatives"> <section id="derivatives">
<h1>Derivatives</h1> <h1><a href="#derivatives">Derivatives</a></h1>
<p> <p>
There's a number of useful things that you can do with Bézier curves There's a number of useful things that you can do with Bézier curves
based on their derivative, and one of the more amusing observations based on their derivative, and one of the more amusing observations
@@ -1868,8 +1872,8 @@ function drawCurve(points[], t):
</p> </p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/183ac1365b1075166b7066b78a17ad74.svg" src="images/latex/b7815b1502029ed9d805b6ba0801a53f.svg"
width="447px" width="300px"
height="109px" height="109px"
loading="lazy" loading="lazy"
/> />
@@ -1887,16 +1891,16 @@ function drawCurve(points[], t):
</p> </p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/950811d35cebee2a39d881e33cbfb1de.svg" src="images/latex/c7b13e6507450b3da7dc4ce3c10c370f.svg"
width="447px" width="295px"
height="71px" height="71px"
loading="lazy" loading="lazy"
/> />
<p>And that's just a summation of lower order curves:</p> <p>And that's just a summation of lower order curves:</p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/894ccddbfcec09dd3d035777e7d23245.svg" src="images/latex/89ceb6024ead6f710e3e0f09d2864f43.svg"
width="807px" width="716px"
height="36px" height="36px"
loading="lazy" loading="lazy"
/> />
@@ -1957,7 +1961,7 @@ function drawCurve(points[], t):
</p> </p>
</section> </section>
<section id="pointvectors"> <section id="pointvectors">
<h1>Tangents and normals</h1> <h1><a href="#pointvectors">Tangents and normals</a></h1>
<p> <p>
If you want to move objects along a curve, or "away from" a curve, If you want to move objects along a curve, or "away from" a curve,
the two vectors you're most interested in are the tangent vector and the two vectors you're most interested in are the tangent vector and
@@ -2093,7 +2097,7 @@ function drawCurve(points[], t):
</div> </div>
</section> </section>
<section id="pointvectors3d"> <section id="pointvectors3d">
<h1>Working with 3D normals</h1> <h1><a href="#pointvectors3d">Working with 3D normals</a></h1>
<p> <p>
Before we move on to the next section we need to spend a little bit Before we move on to the next section we need to spend a little bit
of time on the difference between 2D and 3D. While for many things of time on the difference between 2D and 3D. While for many things
@@ -2354,7 +2358,7 @@ function drawCurve(points[], t):
</p> </p>
</section> </section>
<section id="components"> <section id="components">
<h1>Component functions</h1> <h1><a href="#components">Component functions</a></h1>
<p> <p>
One of the first things people run into when they start using Bézier One of the first things people run into when they start using Bézier
curves in their own programs is "I know how to draw the curve, but curves in their own programs is "I know how to draw the curve, but
@@ -2399,7 +2403,7 @@ function drawCurve(points[], t):
/> />
</section> </section>
<section id="extremities"> <section id="extremities">
<h1>Finding extremities: root finding</h1> <h1><a href="#extremities">Finding extremities: root finding</a></h1>
<p> <p>
Now that we understand (well, superficially anyway) the component Now that we understand (well, superficially anyway) the component
functions, we can find the extremities of our Bézier curve by functions, we can find the extremities of our Bézier curve by
@@ -2733,7 +2737,7 @@ function getCubicRoots(pa, pb, pc, pd) {
/> />
</section> </section>
<section id="boundingbox"> <section id="boundingbox">
<h1>Bounding boxes</h1> <h1><a href="#boundingbox">Bounding boxes</a></h1>
<p> <p>
If we have the extremities, and the start/end points, a simple for If we have the extremities, and the start/end points, a simple for
loop that tests for min/max values for x and y means we have the loop that tests for min/max values for x and y means we have the
@@ -2780,7 +2784,7 @@ function getCubicRoots(pa, pb, pc, pd) {
</p> </p>
</section> </section>
<section id="aligning"> <section id="aligning">
<h1>Aligning curves</h1> <h1><a href="#aligning">Aligning curves</a></h1>
<p> <p>
While there are an incredible number of curves we can define by While there are an incredible number of curves we can define by
varying the x- and y-coordinates for the control points, not all varying the x- and y-coordinates for the control points, not all
@@ -2802,8 +2806,8 @@ function getCubicRoots(pa, pb, pc, pd) {
</p> </p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/eb879c2e965ff4d7c61b70c0c6e5bf87.svg" src="images/latex/d480a9aa41917e5230d432cdbd6899b1.svg"
width="671px" width="476px"
height="40px" height="40px"
loading="lazy" loading="lazy"
/> />
@@ -2814,8 +2818,8 @@ function getCubicRoots(pa, pb, pc, pd) {
</p> </p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/d6438a6372e9f910b0a3059ebfacccc6.svg" src="images/latex/50679d61424222d7b6b97eb3aa663582.svg"
width="655px" width="460px"
height="40px" height="40px"
loading="lazy" loading="lazy"
/> />
@@ -2826,16 +2830,16 @@ function getCubicRoots(pa, pb, pc, pd) {
</p> </p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/6afb072a451e06ddf4b1ff1eb8948e8a.svg" src="images/latex/a9af1c06a00bb3c4af816a138fb0a66d.svg"
width="647px" width="452px"
height="40px" height="40px"
loading="lazy" loading="lazy"
/> />
<p>If we drop all the zero-terms, this gives us:</p> <p>If we drop all the zero-terms, this gives us:</p>
<img <img
class="LaTeX SVG" class="LaTeX SVG"
src="images/latex/1d44794e3aac3ecb881b559eb8a71fab.svg" src="images/latex/c78b203ff33e5c1606728b552505d61c.svg"
width="528px" width="387px"
height="40px" height="40px"
loading="lazy" loading="lazy"
/> />
@@ -2857,7 +2861,7 @@ function getCubicRoots(pa, pb, pc, pd) {
/> />
</section> </section>
<section id="tightbounds"> <section id="tightbounds">
<h1>Tight boxes</h1> <h1><a href="#tightbounds">Tight boxes</a></h1>
<p> <p>
With our knowledge of bounding boxes, and curve alignment, We can With our knowledge of bounding boxes, and curve alignment, We can
now form the "tight" bounding box for curves. We first align our now form the "tight" bounding box for curves. We first align our
@@ -2891,7 +2895,7 @@ function getCubicRoots(pa, pb, pc, pd) {
</p> </p>
</section> </section>
<section id="inflections"> <section id="inflections">
<h1>Curve inflections</h1> <h1><a href="#inflections">Curve inflections</a></h1>
<p> <p>
Now that we know how to align a curve, there's one more thing we can Now that we know how to align a curve, there's one more thing we can
calculate: inflection points. Imagine we have a variable size circle calculate: inflection points. Imagine we have a variable size circle
@@ -3050,7 +3054,7 @@ function getCubicRoots(pa, pb, pc, pd) {
/> />
</section> </section>
<section id="canonical"> <section id="canonical">
<h1>Canonical form (for cubic curves)</h1> <h1><a href="#canonical">Canonical form (for cubic curves)</a></h1>
<p> <p>
While quadratic curves are relatively simple curves to analyze, the While quadratic curves are relatively simple curves to analyze, the
same cannot be said of the cubic curve. As a curvature is controlled same cannot be said of the cubic curve. As a curvature is controlled
@@ -3427,7 +3431,7 @@ function getCubicRoots(pa, pb, pc, pd) {
/> />
</section> </section>
<section id="yforx"> <section id="yforx">
<h1>Finding Y, given X</h1> <h1><a href="#yforx">Finding Y, given X</a></h1>
<p> <p>
One common task that pops up in things like CSS work, or parametric One common task that pops up in things like CSS work, or parametric
equalisers, or image leveling, or any other number of applications equalisers, or image leveling, or any other number of applications
@@ -3552,7 +3556,7 @@ if (roots.length &gt; 0) {
/> />
</section> </section>
<section id="arclength"> <section id="arclength">
<h1>Arc length</h1> <h1><a href="#arclength">Arc length</a></h1>
<p> <p>
How long is a Bézier curve? As it turns out, that's not actually an How long is a Bézier curve? As it turns out, that's not actually an
easy question, because the answer requires maths that —much like easy question, because the answer requires maths that —much like
@@ -3768,7 +3772,7 @@ if (roots.length &gt; 0) {
/> />
</section> </section>
<section id="arclengthapprox"> <section id="arclengthapprox">
<h1>Approximated arc length</h1> <h1><a href="#arclengthapprox">Approximated arc length</a></h1>
<p> <p>
Sometimes, we don't actually need the precision of a true arc Sometimes, we don't actually need the precision of a true arc
length, and we can get away with simply computing the approximate length, and we can get away with simply computing the approximate
@@ -3806,7 +3810,7 @@ if (roots.length &gt; 0) {
</p> </p>
</section> </section>
<section id="curvature"> <section id="curvature">
<h1>Curvature of a curve</h1> <h1><a href="#curvature">Curvature of a curve</a></h1>
<p> <p>
Imagine we have two curves, and we want to line them in up in a way Imagine we have two curves, and we want to line them in up in a way
that "looks right". What would we use as metric to let a computer that "looks right". What would we use as metric to let a computer
@@ -4005,7 +4009,9 @@ if (roots.length &gt; 0) {
/> />
</section> </section>
<section id="tracing"> <section id="tracing">
<h1>Tracing a curve at fixed distance intervals</h1> <h1>
<a href="#tracing">Tracing a curve at fixed distance intervals</a>
</h1>
<p> <p>
Say you want to draw a curve with a dashed line, rather than a solid Say you want to draw a curve with a dashed line, rather than a solid
line, or you want to move something along the curve at fixed line, or you want to move something along the curve at fixed
@@ -4090,7 +4096,7 @@ if (roots.length &gt; 0) {
</p> </p>
</section> </section>
<section id="intersections"> <section id="intersections">
<h1>Intersections</h1> <h1><a href="#intersections">Intersections</a></h1>
<p> <p>
Let's look at some more things we will want to do with Bézier Let's look at some more things we will want to do with Bézier
curves. Almost immediately after figuring out how to get bounding curves. Almost immediately after figuring out how to get bounding
@@ -4200,7 +4206,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="curveintersection"> <section id="curveintersection">
<h1>Curve/curve intersection</h1> <h1><a href="#curveintersection">Curve/curve intersection</a></h1>
<p> <p>
Using de Casteljau's algorithm to split the curve we can now Using de Casteljau's algorithm to split the curve we can now
implement curve/curve intersection finding using a "divide and implement curve/curve intersection finding using a "divide and
@@ -4285,7 +4291,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="abc"> <section id="abc">
<h1>The projection identity</h1> <h1><a href="#abc">The projection identity</a></h1>
<p> <p>
De Casteljau's algorithm is the pivotal algorithm when it comes to De Casteljau's algorithm is the pivotal algorithm when it comes to
Bézier curves. You can use it not just to split curves, but also to Bézier curves. You can use it not just to split curves, but also to
@@ -4485,7 +4491,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="moulding"> <section id="moulding">
<h1>Manipulating a curve</h1> <h1><a href="#moulding">Manipulating a curve</a></h1>
<p> <p>
Armed with knowledge of the "ABC" relation, we can now update a Armed with knowledge of the "ABC" relation, we can now update a
curve interactively, by letting people click anywhere on the curve, curve interactively, by letting people click anywhere on the curve,
@@ -4571,7 +4577,7 @@ lli = function(line1, line2):
<p>And that's cubic curve manipulation.</p> <p>And that's cubic curve manipulation.</p>
</section> </section>
<section id="pointcurves"> <section id="pointcurves">
<h1>Creating a curve from three points</h1> <h1><a href="#pointcurves">Creating a curve from three points</a></h1>
<p> <p>
Given the preceding section on curve manipulation, we can also Given the preceding section on curve manipulation, we can also
generate quadratic and cubic curves from any three points. However, generate quadratic and cubic curves from any three points. However,
@@ -4632,7 +4638,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="curvefitting"> <section id="curvefitting">
<h1>Curve fitting</h1> <h1><a href="#curvefitting">Curve fitting</a></h1>
<p> <p>
Given the previous section, one question you might have is "what if Given the previous section, one question you might have is "what if
I don't want to guess <code>t</code> values?". After all, plenty of I don't want to guess <code>t</code> values?". After all, plenty of
@@ -5093,7 +5099,9 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="catmullconv"> <section id="catmullconv">
<h1>Bézier curves and Catmull-Rom curves</h1> <h1>
<a href="#catmullconv">Bézier curves and Catmull-Rom curves</a>
</h1>
<p> <p>
Taking an excursion to different splines, the other common design Taking an excursion to different splines, the other common design
curve is the curve is the
@@ -5448,7 +5456,11 @@ lli = function(line1, line2):
/> />
</section> </section>
<section id="catmullmoulding"> <section id="catmullmoulding">
<h1>Creating a Catmull-Rom curve from three points</h1> <h1>
<a href="#catmullmoulding"
>Creating a Catmull-Rom curve from three points</a
>
</h1>
<p> <p>
Now, we saw how to fit a Bézier curve to three points, but if Now, we saw how to fit a Bézier curve to three points, but if
Catmull-Rom curves go through points, why can't we just use those to Catmull-Rom curves go through points, why can't we just use those to
@@ -5502,7 +5514,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="polybezier"> <section id="polybezier">
<h1>Forming poly-Bézier curves</h1> <h1><a href="#polybezier">Forming poly-Bézier curves</a></h1>
<p> <p>
Much like lines can be chained together to form polygons, Bézier Much like lines can be chained together to form polygons, Bézier
curves can be chained together to form poly-Béziers, and the only curves can be chained together to form poly-Béziers, and the only
@@ -5672,7 +5684,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="shapes"> <section id="shapes">
<h1>Boolean shape operations</h1> <h1><a href="#shapes">Boolean shape operations</a></h1>
<p> <p>
We can apply the topics covered so far in this primer to effect We can apply the topics covered so far in this primer to effect
boolean shape operations: getting the union, intersection, or boolean shape operations: getting the union, intersection, or
@@ -5810,7 +5822,9 @@ lli = function(line1, line2):
</Graphic> </Graphic>
</section> </section>
<section id="projections"> <section id="projections">
<h1>Projecting a point onto a Bézier curve</h1> <h1>
<a href="#projections">Projecting a point onto a Bézier curve</a>
</h1>
<p> <p>
Say we have a Bézier curve and some point, not on the curve, of Say we have a Bézier curve and some point, not on the curve, of
which we want to know which <code>t</code> value on the curve gives which we want to know which <code>t</code> value on the curve gives
@@ -5875,7 +5889,7 @@ lli = function(line1, line2):
/> />
</section> </section>
<section id="offsetting"> <section id="offsetting">
<h1>Curve offsetting</h1> <h1><a href="#offsetting">Curve offsetting</a></h1>
<p> <p>
Perhaps you're like me, and you've been writing various small Perhaps you're like me, and you've been writing various small
programs that use Bézier curves in some way or another, and at some programs that use Bézier curves in some way or another, and at some
@@ -6083,7 +6097,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="graduatedoffset"> <section id="graduatedoffset">
<h1>Graduated curve offsetting</h1> <h1><a href="#graduatedoffset">Graduated curve offsetting</a></h1>
<p> <p>
What if we want to do graduated offsetting, starting at some What if we want to do graduated offsetting, starting at some
distance <code>s</code> but ending at some other distance distance <code>s</code> but ending at some other distance
@@ -6150,7 +6164,7 @@ lli = function(line1, line2):
/> />
</section> </section>
<section id="circles"> <section id="circles">
<h1>Circles and quadratic Bézier curves</h1> <h1><a href="#circles">Circles and quadratic Bézier curves</a></h1>
<p> <p>
Circles and Bézier curves are very different beasts, and circles are Circles and Bézier curves are very different beasts, and circles are
infinitely easier to work with than Bézier curves. Their formula is infinitely easier to work with than Bézier curves. Their formula is
@@ -6388,7 +6402,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="circles_cubic"> <section id="circles_cubic">
<h1>Circles and cubic Bézier curves</h1> <h1><a href="#circles_cubic">Circles and cubic Bézier curves</a></h1>
<p> <p>
In the previous section we tried to approximate a circular arc with In the previous section we tried to approximate a circular arc with
a quadratic curve, and it mostly made us unhappy. Cubic curves are a quadratic curve, and it mostly made us unhappy. Cubic curves are
@@ -6723,7 +6737,11 @@ lli = function(line1, line2):
/> />
</section> </section>
<section id="arcapproximation"> <section id="arcapproximation">
<h1>Approximating Bézier curves with circular arcs</h1> <h1>
<a href="#arcapproximation"
>Approximating Bézier curves with circular arcs</a
>
</h1>
<p> <p>
Let's look at doing the exact opposite of the previous section: Let's look at doing the exact opposite of the previous section:
rather than approximating circular arc using Bézier curves, let's rather than approximating circular arc using Bézier curves, let's
@@ -6907,7 +6925,7 @@ lli = function(line1, line2):
</p> </p>
</section> </section>
<section id="bsplines"> <section id="bsplines">
<h1>B-Splines</h1> <h1><a href="#bsplines">B-Splines</a></h1>
<p> <p>
No discussion on Bézier curves is complete without also giving No discussion on Bézier curves is complete without also giving
mention of that other beast in the curve design space: B-Splines. mention of that other beast in the curve design space: B-Splines.
@@ -7458,12 +7476,12 @@ for(let L = 1; L &lt;= order; L++) {
* PLEASE DO NOT LOCALISE THIS FILE * PLEASE DO NOT LOCALISE THIS FILE
* *
* I can't respond to questions that aren't asked in English, so this is one of * I can't respond to questions that aren't asked in English, so this is one of
* the few cases where there is a content.en-GB.md but you shouldn't change it. * the few cases where there is a content.en-GB.md but you should not localize it.
* *
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
</script> </script>
<h1>Comments and questions</h1> <h1><a href="#comments">Comments and questions</a></h1>
<p> <p>
First off, if you enjoyed this book, or you simply found it useful First off, if you enjoyed this book, or you simply found it useful
for something you were trying to get done, and you were wondering for something you were trying to get done, and you were wondering