This notebook is part of https://github.com/AudioSceneDescriptionFormat/splines, see also https://splines.readthedocs.io/.

[back to overview](bezier.ipynb)

# Non-Uniform Bézier Splines

Very commonly,
Bézier splines are used with a parameter range of $0 \le t \le 1$,
which has also been used to derive the basis polynomials and basis matrices in
[the notebook about De Casteljau's algorithm](bezier-de-casteljau.ipynb).

The parameter range can be re-scaled to any desired parameter range,
but since the shape of a Bézier curve is fully defined by its control polygon,
this will not change the shape of the curve,
but only its speed, and therefore its tangent vectors.

To derive equations for non-uniform tangent vectors,
let us quickly re-implement De Casteljau's algorithm:


```python
def lerp(one, two, t):
    return (1 - t) * one + t * two
```


```python
def de_casteljau(points, t):
    while len(points) > 1:
        points = [lerp(a, b, t) for a, b in zip(points, points[1:])]
    return points[0]
```


```python
import sympy as sp
sp.init_printing()
```

We'll also use our trusty SymPy tools from [utility.py](utility.py):


```python
from utility import NamedExpression
```

In this notebook we are only looking at cubic Bézier splines.
More specifically, we are looking at the fifth spline segment,
from $\boldsymbol{x}_4$ to $\boldsymbol{x}_5$
within a parameter range from $t_4$ to $t_5$,
but later we can easily generalize this.


```python
control_points = sp.symbols('xbm4 xtildebm4^(+) xtildebm5^(-) xbm5')
control_points
```


```python
t, t4, t5 = sp.symbols('t t4 t5')
```

As before,
we are using De Casteljau's algorithm,
but this time we are re-scaling the parameter range using the transformation
$t \to \frac{t - t_i}{t_{i+1} - t_i}$:


```python
p4 = NamedExpression(
    'pbm4',
    de_casteljau(control_points, (t - t4) / (t5 - t4)))
```

## Tangent Vectors

As always,
the tangent vectors can be obtained by means of the first derivative:


```python
pd4 = p4.diff(t)
```


```python
pd4.evaluated_at(t, t4)
```

This expression for the outgoing tangent vector at
$\boldsymbol{x}_4$
can be generalized to

\begin{equation*}
\boldsymbol{\dot{x}}_i^{(+)} =
\frac
{3 \left(\boldsymbol{\tilde{x}^{(+)}}_i - \boldsymbol{x}_i\right)}
{\Delta_i},
\end{equation*}

where $\Delta_i = t_{i+1} - t_i$.

Similarly,
the incoming tangent vector at $\boldsymbol{x}_5$ ...


```python
pd4.evaluated_at(t, t5)
```

... can be generalized to

\begin{equation*}
\boldsymbol{\dot{x}}_i^{(-)} =
\frac
{3 \left(\boldsymbol{x}_i - \boldsymbol{\tilde{x}^{(-)}}_i\right)}
{\Delta_{i-1}}.
\end{equation*}

This is similar to the
[uniform case](bezier-de-casteljau.ipynb#Cubic-Tangent-Vectors),
the tangent vectors are just divided by the parameter interval.

## Control Points From Tangent Vectors

If the tangent vectors are given in the first place
(i.e. when a non-uniform [Hermite spline](hermite.ipynb) is given),
the cubic Bézier control points can be calculated like this:

\begin{align*}
\boldsymbol{\tilde{x}^{(+)}}_i &=
\boldsymbol{x}_i + \frac{\Delta_i \boldsymbol{\dot{x}}_i^{(+)}}{3} \\
\boldsymbol{\tilde{x}^{(-)}}_i &=
\boldsymbol{x}_i - \frac{\Delta_{i-1} \boldsymbol{\dot{x}}_i^{(-)}}{3}
\end{align*}

715d1703407f3b1f6f86c1ee59df4966a041b2c6
ipynb
Jupyter Notebook
doc/euclidean/bezier-non-uniform.ipynb
AudioSceneDescriptionFormat/splines
0faf87ffddf3be01087959f80d9c43a4da2ae862
MIT
2021-06-21T11:41:02.000Z
2022-02-15T19:18:47.000Z
doc/euclidean/bezier-non-uniform.ipynb
AudioSceneDescriptionFormat/splines
0faf87ffddf3be01087959f80d9c43a4da2ae862
MIT
2018-07-09T17:47:29.000Z
2022-01-28T19:55:55.000Z
doc/euclidean/bezier-non-uniform.ipynb
AudioSceneDescriptionFormat/splines
0faf87ffddf3be01087959f80d9c43a4da2ae862
MIT
2020-05-15T18:34:42.000Z
2021-12-28T06:29:54.000Z
Qwen/Qwen-72B
1. YES
2. YES