Mix.install(
  [
    {:curves, "~> 0.2.5"},
    {:tucan, "~> 0.6.0"},
    {:vega_lite, "~> 0.1.0"},
    {:kino_vega_lite, "~> 0.1.0"},
  ])

Curves (Bezier) tutorial

# The usual workflow is very simple:

# 1. Define a curve
curve = Curves.define_bezier(:ease_in)

# 2. Find the {x, y} coordinates for a given percentage along the curve
Curves.solve!(curve, 0.25)
# To visualize this, we use VegaLite and Tucan.
# Below we are plotting 10 points, evenly spaced along the curve
# (i.e. 10%, 20%, 30% ... 100%)

# Go ahead, experiment with increasing this number. The default is 1000
count = 10

Curves.define_bezier(:ease_in)
|> Curves.Utils.Plotting.curve_to_scatterplot(count: count)
|> Tucan.scatter("x", "y")
|> Tucan.color_by("label")
|> Tucan.fill_by("label")
# There are many more curve types you can use. Let's turn them into a select box.
types = Curves.Bezier.Predefined.list()
        |> Enum.map(&{&1, &1})

bezier_type = Kino.Input.select("Curve Type", types, default: :ease_in_out)
# Now evaluate THIS code block to display a graph of the curve type you selected above.
Kino.Input.read(bezier_type)
|> Curves.define_bezier()
|> Curves.Utils.Plotting.curve_to_scatterplot()
|> Tucan.scatter("x", "y")
|> Tucan.color_by("label")
|> Tucan.fill_by("label")


# Go ahead and play around with the select list to see the various predefined curves.
## Advanced Usage

# We can define our own curves manualy. 
# At a minimum, you can supply 2 points to get a linear 'curve'
curve = Curves.define_bezier([
  {0, 0},
  {100, 100}
])

curve
|> Curves.Utils.Plotting.curve_to_scatterplot(label: "Linear")
|> Tucan.scatter("x", "y")
|> Tucan.color_by("label")
|> Tucan.fill_by("label")
# With 3 points, we get a quadratic curve
start = {0, 0}
control_point = {20, 50}
stop = {100, 0}

curve = Curves.define_bezier([start, control_point, stop])

curve
|> Curves.Utils.Plotting.curve_to_scatterplot(label: "Quadratic")
|> Tucan.scatter("x", "y")
|> Tucan.color_by("label")
|> Tucan.fill_by("label")
# And finally the one most people think of when they hear "bezier curve"; The cubic bezier.
curve = Curves.define_bezier([
  {0, 0},
  {0.8, 0},
  {0.3, 1.2},
  {1, 1}
])

curve
|> Curves.Utils.Plotting.curve_to_scatterplot(label: "Cubic")
|> Tucan.scatter("x", "y")
|> Tucan.color_by("label")
|> Tucan.fill_by("label")