Curves
Introduction
Curves aims to be the best elixir framework for calculating bezier curves and splines.
curve = Curves.define_bezier(:ease_out)
{x, y} = Curves.solve!(curve, 0.25)
assert is_float(x)
assert is_float(y)
Directory
Be sure to check out the livebook for an interactive demo/tutorial.
Visual Demo
Ease in-out Bezier
The simplest way to use Curves is with the predefined ones like :ease_in_out
curves = Curves.define_bezier(:ease_in_out)
for i <- 0..1000 do
Curves.solve!(curve, i / 1000)
end
|> # render_vega_lite_chart(...)
Quadratic Bezier
Here we make an asymmetric quadratic curve
points = [
{0, 0},
{20, 50},
{100, 0}
]
curves = Curves.define_bezier(points)
Custom 4-point Bezier
points = [
{0, 0},
{0.8, 0.2},
{0.3, 2.2},
{1, 1}
]
curves = Curves.define_bezier(points)
Spline examples
The simplest spline is basically just a series of bezier curves connected to each other.
Notice we are no longer using define_bezier, but define_bezier_spline. Now it is a list of lists with 1, 2, or 3 tuples in each segment.
# points format for `define_bezier_spline/2`
[{knot_x, knot_y}]
[{knot_x, knot_y}, {cp0_x, cp0_y}]
[{knot_x, knot_y}, {cp0_x, cp0_y}, {cp1_x, cp1_y}]
Bezier Spline
points = [
# P0
[{5.0, 10.0}, # Knot
{10.0, 10.0}], # control point 0
# P1
[{10.0, 5.0}, # Knot
{5.0, 5.0}, # control point 0
{15.0, 5.0}],# control point 1
# P2
[{15.0, 10.0}, # Knot
{15.0, 6.0}, # control point 0
{15.0, 14.0} # control point 1
],
# P3
[{20.0, 15.0}, # Knot
{18.0, 15.0}, # control point 0
{23.0, 15.0}],# control point 1
# P4
[{30.0, 10.0}, # Knot
{32.0, 5.0}] # control point 0
]
curves = Curves.define_bezier_spline(points)
Cubic Hermite Spline
Sometimes we don't want to manually define every control point. The Hermite spline automatically calculates it based on the first derivative at the start and end point of each segment.
curve = Curves.define_hermite([
{5, 10},
{10, 5},
{15, 10},
{20, 10},
{25, 5},
{30, 15},
])
Catmull-Rom Spline
Similar to the Hermite spline, but now the derivative comes from the slope between the previous and next point.
curve = Curves.define_catmull_rom([
{0, 0},
{1, 0},
{1, 1},
{0, 1},
{0, 2},
{1, 2},
])
B-Spline
The smoothest of the splines featured here, but with the drawback that the line does not actually pass through the control points.
curve = Curves.define_b_spline([
{0, -2},
{3, 4},
{6, 5},
{7, -1},
{10, 3},
{5, 1},
{12, 9}
])