mirror of
https://github.com/Pomax/BezierInfo-2.git
synced 2025-08-26 17:54:52 +02:00
fixes
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Bézier curvatures as matrix operations
|
||||
|
||||
We can also represent Bézier curves as matrix operations, by expressing the Bézier formula as a polynomial basis function and a coefficients matrix, and the actual coordinates as a matrix. Let's look at what this means for the cubic curve:
|
||||
We can also represent Bézier curves as matrix operations, by expressing the Bézier formula as a polynomial basis function and a coefficients matrix, and the actual coordinates as a matrix. Let's look at what this means for the cubic curve, using P<sub>...</sub> to refer to coordinate values "in one or more dimensions":
|
||||
|
||||
\[
|
||||
B(t) = P_1 \cdot (1-t)^3 + P_2 \cdot 3 \cdot (1-t)^2 \cdot t + P_3 \cdot 3 \cdot (1-t) \cdot t^2 + P_4 \cdot t^3
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
Say we have a Bézier curve and some point, not on the curve, of which we want to know which `t` value on the curve gives us an on-curve point closest to our off-curve point. Or: say we want to find the projection of a random point onto a curve. How do we do that?
|
||||
|
||||
If the Bézier curve is of low enough order, we might be able to [work out the maths for how to do this](http://jazzros.blogspot.ca/2011/03/projecting-point-on-bezier-curve.html), and get a perfect `t` value back, but in general this is an incredibly hard problem and the easiest solution is, really, a numerical approach again. We'll be finding our ideal `t` value using a [binary search](https://en.wikipedia.org/wiki/Binary_search_algorithm). First, we do a coarse distance-check based on `t` values associated with the curve's "to draw" coordinates (using a lookup table, or LUT). This is pretty fast. Then we run this algorithm:
|
||||
If the Bézier curve is of low enough order, we might be able to [work out the maths for how to do this](https://web.archive.org/web/20140713004709/http://jazzros.blogspot.com/2011/03/projecting-point-on-bezier-curve.html), and get a perfect `t` value back, but in general this is an incredibly hard problem and the easiest solution is, really, a numerical approach again. We'll be finding our ideal `t` value using a [binary search](https://en.wikipedia.org/wiki/Binary_search_algorithm). First, we do a coarse distance-check based on `t` values associated with the curve's "to draw" coordinates (using a lookup table, or LUT). This is pretty fast. Then we run this algorithm:
|
||||
|
||||
1. with the `t` value we found, start with some small interval around `t` (1/length_of_LUT on either side is a reasonable start),
|
||||
2. if the distance to `t ± interval/2` is larger than the distance to `t`, try again with the interval reduced to half its original length.
|
||||
|
@@ -20,13 +20,19 @@ However, this rule also has as direct consequence that you **cannot** generally
|
||||
|
||||
However, there is a surprisingly good way to ensure that a lower order curve looks "as close as reasonably possible" to the original curve: we can optimise the "least-squares distance" between the original curve and the lower order curve, in a single operation (also explained over on [Sirver's Castle](http://www.sirver.net/blog/2011/08/23/degree-reduction-of-bezier-curves)). However, to use it, we'll need to do some calculus work and then switch over to linear algebra. As mentioned in the section on matrix representations, some things can be done much more easily with matrices than with calculus functions, and this is one of those things. So... let's go!
|
||||
|
||||
We start by taking the standard Bézier function:
|
||||
We start by taking the standard Bézier function, and condensing it a little:
|
||||
|
||||
\[
|
||||
Bézier(n,t) = \sum_{i=0}^{n} b_i B^n_i(t)
|
||||
Bézier(n,t)
|
||||
=
|
||||
\sum_{i=0}^{n} w_i B^n_i(t)
|
||||
\textit{, where }
|
||||
B^n_i(t)
|
||||
=
|
||||
\binom{n}{i} \cdot (1-t)^{n-i} \cdot t^{i}
|
||||
\]
|
||||
|
||||
And then, we apply one of those silly (actually, super useful) calculus tricks: since our `t` value is always between zero and one (inclusive), we know that `(1-t)` plus `t` always sums to 1. As such, we can express any value as a sum of `t` and `1-t`:
|
||||
Then, we apply one of those silly (actually, super useful) calculus tricks: since our `t` value is always between zero and one (inclusive), we know that `(1-t)` plus `t` always sums to 1. As such, we can express any value as a sum of `t` and `1-t`:
|
||||
|
||||
\[
|
||||
x = 1 x = \left ( (1-t) + t \right ) x = (1-t) x + t x = x (1-t) + x t
|
||||
@@ -37,7 +43,7 @@ So, with that seemingly trivial observation, we rewrite that Bézier function by
|
||||
\[
|
||||
\begin{aligned}
|
||||
Bézier(n,t) &= (1-t) B(n,t) + t B(n,t) \\
|
||||
&= \sum_{i=0}^{n} p_i (1 - t) B^n_i(t) + \sum_{i=0}^{n} p_i t B^n_i(t)
|
||||
&= \sum_{i=0}^{n} w_i (1 - t) B^n_i(t) + \sum_{i=0}^{n} w_i t B^n_i(t)
|
||||
\end{aligned}
|
||||
\]
|
||||
|
||||
@@ -69,11 +75,11 @@ Let's do this:
|
||||
|
||||
\[
|
||||
\begin{aligned}
|
||||
Bézier(n,t) &= \sum_{i=0}^{n+1} p_i (1 - t) B^n_i(t) + \sum_{i=0}^{n+1} p_i t B^n_i(t) \\
|
||||
&= \sum_{i=0}^{n+1} p_i \frac{k-i}{k} B^k_i(t) + \sum_{i=0}^{n+1} p_i \frac{i+1}{k} B^k_{i+1}(t), \textit{where } k = n + 1 \\
|
||||
&= \sum_{i=0}^{n+1} p_i \frac{k-i}{k} B^k_i(t) + \sum_{i=0}^{n+1} p_{i-1} \frac{i}{k} B^k_i(t) \\
|
||||
&= \sum_{i=0}^{n+1} \left ( p_i \frac{k-i}{k} + p_{i-1} \frac{i}{k} \right ) B^k_i(t) \\
|
||||
&= \sum_{i=0}^{n+1} \left ( p_i (1-s) + p_{i-1} s \right ) B^k_i(t), \textit{where } s = \frac{i}{k}
|
||||
Bézier(n,t) &= \sum_{i=0}^{n+1} w_i (1 - t) B^n_i(t) + \sum_{i=0}^{n+1} w_i t B^n_i(t) \\
|
||||
&= \sum_{i=0}^{n+1} w_i \frac{k-i}{k} B^k_i(t) + \sum_{i=0}^{n+1} w_i \frac{i+1}{k} B^k_{i+1}(t), \textit{where } k = n + 1 \\
|
||||
&= \sum_{i=0}^{n+1} w_i \frac{k-i}{k} B^k_i(t) + \sum_{i=0}^{n+1} p_{i-1} \frac{i}{k} B^k_i(t) \\
|
||||
&= \sum_{i=0}^{n+1} \left ( w_i \frac{k-i}{k} + p_{i-1} \frac{i}{k} \right ) B^k_i(t) \\
|
||||
&= \sum_{i=0}^{n+1} \left ( w_i (1-s) + p_{i-1} s \right ) B^k_i(t), \textit{where } s = \frac{i}{k}
|
||||
\end{aligned}
|
||||
\]
|
||||
|
||||
|
Reference in New Issue
Block a user