vivid v0.2.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<{30.106601717798213, 21.696699141100893}>, #Vivid.Point<{19.5, 24.803300858899107}>, #Vivid.Point<{8.893398282201787, 17.303300858899107}>, #Vivid.Point<{19.5, 14.196699141100893}>]>
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 it’s center point
Rotate a shape around an origin point
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
Types
Functions
Apply a transformation pipeline returning the modified shape.
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.0, 1.0}>, #Vivid.Point<{11.0, 11.0}>, #Vivid.Point<{1.0, 11.0}>, #Vivid.Point<{1.0, 1.0}>]>
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, 0.0}>, #Vivid.Point<{40.0, 40.0}>, #Vivid.Point<{0.0, 40.0}>, #Vivid.Point<{0.0, 0.0}>]>
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, 0.0}>, #Vivid.Point<{80.0, 80.0}>, #Vivid.Point<{0.0, 80.0}>, #Vivid.Point<{0.0, 0.0}>]>
Rotate a shape around it’s center point.
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<{22.071067811865476, 16.464466094067262}>, #Vivid.Point<{15.0, 18.535533905932738}>, #Vivid.Point<{7.9289321881345245, 13.535533905932738}>, #Vivid.Point<{15.0, 11.464466094067262}>]>
rotate(shape_or_transform, degrees, Vivid.Point.t) :: Vivid.Transform.t
Rotate a shape around an origin point.
Example
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<{12.071067811865476, 13.535533905932738}>, #Vivid.Point<{5.000000000000002, 15.606601717798215}>, #Vivid.Point<{-2.0710678118654737, 10.606601717798215}>, #Vivid.Point<{5.0, 8.535533905932738}>]>
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<{12.5, 2.5}>, #Vivid.Point<{12.5, 12.5}>, #Vivid.Point<{2.5, 12.5}>, #Vivid.Point<{2.5, 2.5}>]>
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<{12.5, -2.5}>, #Vivid.Point<{12.5, 17.5}>, #Vivid.Point<{2.5, 17.5}>, #Vivid.Point<{2.5, -2.5}>]>
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, 0.0}>, #Vivid.Point<{40.0, 80.0}>, #Vivid.Point<{0.0, 80.0}>, #Vivid.Point<{0.0, 0.0}>]>
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
The example below translates a point right by half it’s width.
iex> Vivid.Box.init(Vivid.Point.init(10,10), Vivid.Point.init(20,20))
...> |> Vivid.Transform.transform(fn shape ->
...> 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<{25, 10}>, #Vivid.Point<{25, 20}>, #Vivid.Point<{15, 20}>, #Vivid.Point<{15, 10}>]>
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}>]>