vivid v0.1.1 Vivid.Transform

Creates and applies a “pipeline” of transformations to a shape. Transformation operations are collected up and only run once, when apply is called.

Examples

Take a square, rotate it 45°, scale it up 50% and center it within a frame.

iex> frame = Vivid.Frame.init(40,40)
...> Vivid.Box.init(Vivid.Point.init(0,0), Vivid.Point.init(10,10))
...> |> Vivid.Transform.rotate(45)
...> |> Vivid.Transform.scale(1.5)
...> |> Vivid.Transform.center(frame)
...> |> Vivid.Transform.apply
#Vivid.Polygon<[#Vivid.Point<{17, 11}>, #Vivid.Point<{28, 22}>, #Vivid.Point<{23, 29}>, #Vivid.Point<{12, 19}>]>

Summary

Functions

Apply a transformation pipeline returning the modified shape

Center a shape within the specified bounds

Scale a shape to the maximum size within bounds, respecting the shape’s aspect ratio

Scale a shape to completely fill bounds, respecting the shape’s aspect ratio. Thus overflowing the bounds if the shape’s aspect ratio doesn’t match that of the bounds

Rotate a shape around an origin point. The default point the shape’s center

Scale a shape around it’s center point

Stretch a shape to the maximum size within bounds, ignoring the shape’s original aspect ratio

Create an arbitrary transformation

Translate (ie move) a shape by adding x and y to each Point

Functions

apply(shape)

Apply a transformation pipeline returning the modified shape.

center(shape, bounds)

Center a shape within the specified bounds.

Examples

iex> Vivid.Box.init(Vivid.Point.init(10,10), Vivid.Point.init(20,20))
...> |> Vivid.Transform.center(Vivid.Bounds.init(0, 0, 12, 12))
...> |> Vivid.Transform.apply
#Vivid.Polygon<[#Vivid.Point<{11, 1}>, #Vivid.Point<{11, 11}>, #Vivid.Point<{1, 11}>, #Vivid.Point<{1, 1}>]>
fill(shape, bounds)

Scale a shape to the maximum size within bounds, respecting the shape’s aspect ratio.

Examples

iex> Vivid.Box.init(Vivid.Point.init(10,10), Vivid.Point.init(20,20))
...> |> Vivid.Transform.fill(Vivid.Bounds.init(0, 0, 40, 80))
...> |> Vivid.Transform.apply
#Vivid.Polygon<[#Vivid.Point<{40, 0}>, #Vivid.Point<{40, 40}>, #Vivid.Point<{0, 40}>, #Vivid.Point<{0, 0}>]>
overflow(shape, bounds)

Scale a shape to completely fill bounds, respecting the shape’s aspect ratio. Thus overflowing the bounds if the shape’s aspect ratio doesn’t match that of the bounds.

Examples

iex> Vivid.Box.init(Vivid.Point.init(10,10), Vivid.Point.init(20,20))
...> |> Vivid.Transform.overflow(Vivid.Bounds.init(0, 0, 40, 80))
...> |> Vivid.Transform.apply
#Vivid.Polygon<[#Vivid.Point<{80, 0}>, #Vivid.Point<{80, 80}>, #Vivid.Point<{0, 80}>, #Vivid.Point<{0, 0}>]>
rotate(shape, degrees)

Rotate a shape around an origin point. The default point the shape’s center.

Example

iex> Vivid.Box.init(Vivid.Point.init(10,10), Vivid.Point.init(20,20))
...> |> Vivid.Transform.rotate(45)
...> |> Vivid.Transform.apply
#Vivid.Polygon<[#Vivid.Point<{13, 9}>, #Vivid.Point<{20, 16}>, #Vivid.Point<{17, 21}>, #Vivid.Point<{10, 14}>]>

iex> Vivid.Box.init(Vivid.Point.init(10,10), Vivid.Point.init(20,20))
...> |> Vivid.Transform.rotate(45, Vivid.Point.init(5,5))
...> |> Vivid.Transform.apply
#Vivid.Polygon<[#Vivid.Point<{13, 2}>, #Vivid.Point<{20, 9}>, #Vivid.Point<{17, 14}>, #Vivid.Point<{10, 6}>]>
rotate(shape, degrees, origin)
scale(shape, uniform)

Scale a shape around it’s center point.

Examples

iex> Vivid.Box.init(Vivid.Point.init(5,5), Vivid.Point.init(10,10))
...> |> Vivid.Transform.scale(2)
...> |> Vivid.Transform.apply
#Vivid.Polygon<[#Vivid.Point<{13, 3}>, #Vivid.Point<{13, 13}>, #Vivid.Point<{3, 13}>, #Vivid.Point<{3, 3}>]>

iex> Vivid.Box.init(Vivid.Point.init(5,5), Vivid.Point.init(10,10))
...> |> Vivid.Transform.scale(2, 4)
...> |> Vivid.Transform.apply
#Vivid.Polygon<[#Vivid.Point<{13, -3}>, #Vivid.Point<{13, 18}>, #Vivid.Point<{3, 18}>, #Vivid.Point<{3, -3}>]>
scale(shape, x, y)
stretch(shape, bounds)

Stretch a shape to the maximum size within bounds, ignoring the shape’s original aspect ratio.

Examples

iex> Vivid.Box.init(Vivid.Point.init(10,10), Vivid.Point.init(20,20))
...> |> Vivid.Transform.stretch(Vivid.Bounds.init(0, 0, 40, 80))
...> |> Vivid.Transform.apply
#Vivid.Polygon<[#Vivid.Point<{40, 0}>, #Vivid.Point<{40, 80}>, #Vivid.Point<{0, 80}>, #Vivid.Point<{0, 0}>]>
transform(shape, fun)

Create an arbitrary transformation.

Takes a shape and a function which is called with a shape argument (not necessarily the shape passed-in, depending on where this transformation is in the transformation pipeline.

The function must return another function which takes and manipulates a point.

Example

iex> Vivid.Box.init(Vivid.Point.init(10,10), Vivid.Point.init(20,20))
...> |> Vivid.Transform.transform(fn shape ->
...>   # Translate a point right by half it's width
...>   width = Vivid.Bounds.width(shape)
...>   fn point ->
...>     x = point |> Vivid.Point.x
...>     y = point |> Vivid.Point.y
...>     x = x - (width / 2) |> round
...>     Vivid.Point.init(x, y)
...>   end
...> end)
...> |> Vivid.Transform.apply
#Vivid.Polygon<[#Vivid.Point<{15, 10}>, #Vivid.Point<{15, 20}>, #Vivid.Point<{5, 20}>, #Vivid.Point<{5, 10}>]>
translate(shape, x, y)

Translate (ie move) a shape by adding x and y to each Point.

Example

iex> Vivid.Box.init(Vivid.Point.init(5,5), Vivid.Point.init(10,10))
...> |> Vivid.Transform.translate(5, 5)
...> |> Vivid.Transform.apply
#Vivid.Polygon<[#Vivid.Point<{15, 10}>, #Vivid.Point<{15, 15}>, #Vivid.Point<{10, 15}>, #Vivid.Point<{10, 10}>]>