Vivid.Bezier (vivid v1.0.0)

Copy Markdown View Source

This module represents a Bézier curve of arbitrary degree, defined by a list of control points.

Three control points describe a quadratic curve, four a cubic one, and any number greater than two is evaluated by de Casteljau's algorithm. The curve passes through the first and last control points and is pulled towards the ones between.

Example

iex> use Vivid
...> Bezier.init([Point.init(0,0), Point.init(0,10), Point.init(10,0), Point.init(10,10)])
...> |> to_string()
"@@@@@@@@@@@@@\n" <>
"@@@@@@@@@@@ @\n" <>
"@@@@@@@@@@@ @\n" <>
"@@@@@@@@@@@ @\n" <>
"@@@@@@@@@@@ @\n" <>
"@@@@@@@@@  @@\n" <>
"@@@@     @@@@\n" <>
"@@  @@@@@@@@@\n" <>
"@@ @@@@@@@@@@\n" <>
"@ @@@@@@@@@@@\n" <>
"@ @@@@@@@@@@@\n" <>
"@ @@@@@@@@@@@\n" <>
"@@@@@@@@@@@@@\n"

Summary

Functions

Returns the control points of a bezier curve.

Changes the control_points of bezier.

Creates a Bézier curve.

Returns the point on bezier at position t, where t is a number between 0 (the first control point) and 1 (the last).

Returns the number of steps in the bezier curve.

Changes the number of steps in bezier.

Converts the bezier curve into a Path, which is used for a bunch of things like Transforms, Bounds calculation, Rasterization, etc.

Types

t()

@type t() :: %Vivid.Bezier{control_points: [Vivid.Point.t()], steps: integer()}

Functions

control_points(bezier)

@spec control_points(t()) :: [Vivid.Point.t()]

Returns the control points of a bezier curve.

Example

iex> Vivid.Bezier.init([Vivid.Point.init(0,0), Vivid.Point.init(5,10), Vivid.Point.init(10,0)])
...> |> Vivid.Bezier.control_points
[Vivid.Point.init(0, 0), Vivid.Point.init(5, 10), Vivid.Point.init(10, 0)]

control_points(bezier, control_points)

@spec control_points(t(), [Vivid.Point.t()]) :: t()

Changes the control_points of bezier.

Example

iex> Vivid.Bezier.init([Vivid.Point.init(0,0), Vivid.Point.init(5,10), Vivid.Point.init(10,0)])
...> |> Vivid.Bezier.control_points([Vivid.Point.init(0, 0), Vivid.Point.init(10, 10)])
...> |> Vivid.Bezier.control_points
[Vivid.Point.init(0, 0), Vivid.Point.init(10, 10)]

init(control_points, steps \\ 12)

@spec init([Vivid.Point.t()], integer()) :: t()

Creates a Bézier curve.

  • control_points is a list of at least two Points.
  • steps the curve is drawn by dividing it into a number of lines. Defaults to 12.

Examples

iex> Vivid.Bezier.init([Vivid.Point.init(0,0), Vivid.Point.init(5,10), Vivid.Point.init(10,0)])
%Vivid.Bezier{
  control_points: [
    %Vivid.Point{x: 0, y: 0},
    %Vivid.Point{x: 5, y: 10},
    %Vivid.Point{x: 10, y: 0}
  ],
  steps: 12
}

point_at(bezier, t)

@spec point_at(t(), number()) :: Vivid.Point.t()

Returns the point on bezier at position t, where t is a number between 0 (the first control point) and 1 (the last).

Examples

iex> Vivid.Bezier.init([Vivid.Point.init(0,0), Vivid.Point.init(5,10), Vivid.Point.init(10,0)])
...> |> Vivid.Bezier.point_at(0.5)
Vivid.Point.init(5.0, 5.0)

iex> Vivid.Bezier.init([Vivid.Point.init(0,0), Vivid.Point.init(5,10), Vivid.Point.init(10,0)])
...> |> Vivid.Bezier.point_at(0)
Vivid.Point.init(0, 0)

steps(bezier)

@spec steps(t()) :: integer()

Returns the number of steps in the bezier curve.

Example

iex> Vivid.Bezier.init([Vivid.Point.init(0,0), Vivid.Point.init(5,10), Vivid.Point.init(10,0)])
...> |> Vivid.Bezier.steps
12

steps(bezier, steps)

@spec steps(t(), integer()) :: t()

Changes the number of steps in bezier.

Example

iex> Vivid.Bezier.init([Vivid.Point.init(0,0), Vivid.Point.init(5,10), Vivid.Point.init(10,0)])
...> |> Vivid.Bezier.steps(24)
...> |> Vivid.Bezier.steps
24

to_path(bezier)

@spec to_path(t()) :: Vivid.Path.t()

Converts the bezier curve into a Path, which is used for a bunch of things like Transforms, Bounds calculation, Rasterization, etc.

The vertices are deliberately left unrounded, so that the flattened curve agrees with the rasterized border when it's used as part of a filled shape.

Example

iex> Vivid.Bezier.init([Vivid.Point.init(0,0), Vivid.Point.init(5,10), Vivid.Point.init(10,0)], 4)
...> |> Vivid.Bezier.to_path
Vivid.Path.init([
  Vivid.Point.init(0.0, 0.0),
  Vivid.Point.init(2.5, 3.75),
  Vivid.Point.init(5.0, 5.0),
  Vivid.Point.init(7.5, 3.75),
  Vivid.Point.init(10.0, 0.0)
])