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

Very smooth, but with the drawback that the line does not actually pass through the control points.

```elixir
curve = Curves.define_b_spline([
    {0, -2},
    {3, 4},
    {6, 5},
    {7, -1},
    {10, 3},
    {5, 1},
    {12, 9}
])

# 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, "b_spline.svg")
```

![B-Spline](https://github.com/greetingsfellowhumans/curves/raw/main/assets/examples/b_spline.svg)

## How it is built

The B-spline is turned into a chain of cubic Bezier segments, one for every 3 points in a row,
and those are solved like a Bezier spline. Each segment starts at `(p0 + 4 * p1 + p2) / 6`,
which is where a B-spline crosses between segments. So `n` points give `n - 3` segments,
and `max_u` is `n - 3`.

## Stored points

The curve stores those generated Bezier points, not the points you passed in:
4 per segment, with each joint stored twice. For example, 6 points become 12.
This also affects:

* `:force_percent`, which rescales between those bounds instead of between your points.
* `Curves.Svg`, which draws the generated points as its dots.

---

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