# `Curves.Spline.Type.KochanekBartels`
[🔗](https://github.com/greetingsfellowhumans/curves/blob/main/lib/curves/spline/types/kochanek_bartels.ex#L1)

A Kochanek–Bartels spline, also called a TCB spline: a Catmull-Rom spline with three dials,
`:tension`, `:continuity` and `:bias`, that change how the curve passes through each knot.
Animation tools use it for keyframes.

You only give the knots, and the curve passes through every one of them. Each dial is a number,
usually between `-1.0` and `1.0`, and `0.0` by default. With all three at `0.0` it is exactly a
`Curves.Spline.Type.CatmullRom` spline.

| Option | Below `0.0` | Above `0.0` |
| --- | --- | --- |
| `:tension` | rounder, wider bends | tighter bends (`1.0` stops at each knot), like `Curves.Spline.Type.Cardinal` |
| `:continuity` | sharper corners: at `-1.0` it turns at each knot like a polyline | corners that bulge out: it keeps going past each knot, then turns back |
| `:bias` | turns early: the curve leans towards the next knot | turns late: the curve overshoots past each knot |

A spline with `n` knots has `n - 1` segments, like Catmull-Rom. The dials apply to every knot.

```elixir
curve = Curves.define_kochanek_bartels([{0, 0}, {2, 3}, {4, 1}, {6, 4}, {8, 2}], bias: 0.5)

# Find any point along the curve (u goes from 0.0 to Curves.max_u(curve))...
Curves.solve!(curve, 1.5)

# ...or draw the whole curve as an SVG image
Curves.Svg.save!(curve, "kochanek_bartels.svg")
```

![Kochanek-Bartels spline with bias 0.5](images/spline_kochanek_bartels.svg)

## How it is built

Unlike the other splines, the curve can arrive at a knot with one tangent and leave it with
another (that is how `:continuity` makes corners). With `t`, `c` and `b` for the three dials, and
the knot `p` between `previous` and `next`:

```text
leaving  = (1 - t)(1 + c)(1 + b) / 2 * (p - previous) + (1 - t)(1 - c)(1 - b) / 2 * (next - p)
arriving = (1 - t)(1 - c)(1 + b) / 2 * (p - previous) + (1 - t)(1 + c)(1 - b) / 2 * (next - p)
```

The first and last knots have no knot on one side, so they get a made-up one, mirrored through
the end (the same as Catmull-Rom). Each segment is then the Hermite segment between two knots,
stored as a cubic Bezier curve.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
