Run mix format
This commit is contained in:
parent
472887e1da
commit
7fe467268e
|
@ -4,17 +4,21 @@ defimpl Collectable, for: Vivid.Frame do
|
|||
@doc """
|
||||
Collect an enumerable into a Frame.
|
||||
"""
|
||||
@spec into(Frame.t) :: {list, function}
|
||||
@spec into(Frame.t()) :: {list, function}
|
||||
def into(%Frame{shapes: shapes} = frame) do
|
||||
{shapes, fn
|
||||
[], {:cont, {_shape, _colour} = shape} ->
|
||||
[shape]
|
||||
new_shapes, {:cont, {_shape, _colour} = shape} ->
|
||||
[shape | new_shapes]
|
||||
new_shapes, :done ->
|
||||
%{frame | shapes: shapes ++ Enum.reverse(new_shapes)}
|
||||
_, :halt ->
|
||||
:ok
|
||||
end}
|
||||
{shapes,
|
||||
fn
|
||||
[], {:cont, {_shape, _colour} = shape} ->
|
||||
[shape]
|
||||
|
||||
new_shapes, {:cont, {_shape, _colour} = shape} ->
|
||||
[shape | new_shapes]
|
||||
|
||||
new_shapes, :done ->
|
||||
%{frame | shapes: shapes ++ Enum.reverse(new_shapes)}
|
||||
|
||||
_, :halt ->
|
||||
:ok
|
||||
end}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,12 +9,13 @@ defimpl Collectable, for: Vivid.Group do
|
|||
iex> [Vivid.Point.init(1,1)] |> Enum.into(Vivid.Group.init)
|
||||
%Vivid.Group{shapes: MapSet.new([%Vivid.Point{x: 1, y: 1}])}
|
||||
"""
|
||||
@spec into(Group.t) :: {list, function}
|
||||
@spec into(Group.t()) :: {list, function}
|
||||
def into(%Group{shapes: shapes}) do
|
||||
{shapes, fn
|
||||
new_shapes, {:cont, shape} -> MapSet.put(new_shapes, shape)
|
||||
new_shapes, :done -> Group.init(MapSet.union(shapes, new_shapes))
|
||||
_, :halt -> :ok
|
||||
end}
|
||||
{shapes,
|
||||
fn
|
||||
new_shapes, {:cont, shape} -> MapSet.put(new_shapes, shape)
|
||||
new_shapes, :done -> Group.init(MapSet.union(shapes, new_shapes))
|
||||
_, :halt -> :ok
|
||||
end}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,12 +9,13 @@ defimpl Collectable, for: Vivid.Path do
|
|||
iex> [Vivid.Point.init(1,1)] |> Enum.into(Vivid.Path.init)
|
||||
%Vivid.Path{vertices: [%Vivid.Point{x: 1, y: 1}]}
|
||||
"""
|
||||
@spec into(Path.t) :: {list, function}
|
||||
@spec into(Path.t()) :: {list, function}
|
||||
def into(%Path{vertices: points}) do
|
||||
{[], fn
|
||||
list, {:cont, %Point{} = point} -> [point | list]
|
||||
list, :done -> Path.init(points ++ list)
|
||||
_, :halt -> :ok
|
||||
end}
|
||||
{[],
|
||||
fn
|
||||
list, {:cont, %Point{} = point} -> [point | list]
|
||||
list, :done -> Path.init(points ++ list)
|
||||
_, :halt -> :ok
|
||||
end}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,12 +9,13 @@ defimpl Collectable, for: Vivid.Polygon do
|
|||
iex> [Vivid.Point.init(1,1)] |> Enum.into(Vivid.Polygon.init)
|
||||
%Vivid.Polygon{vertices: [%Vivid.Point{x: 1, y: 1}]}
|
||||
"""
|
||||
@spec into(Polygon.t) :: {list, function}
|
||||
@spec into(Polygon.t()) :: {list, function}
|
||||
def into(%Polygon{vertices: points, fill: fill}) do
|
||||
{[], fn
|
||||
list, {:cont, %Point{} = point} -> [point | list]
|
||||
list, :done -> Polygon.init(points ++ list, fill)
|
||||
_, :halt -> :ok
|
||||
end}
|
||||
{[],
|
||||
fn
|
||||
list, {:cont, %Point{} = point} -> [point | list]
|
||||
list, :done -> Polygon.init(points ++ list, fill)
|
||||
_, :halt -> :ok
|
||||
end}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,25 +8,27 @@ defimpl Enumerable, for: Vivid.Buffer do
|
|||
@doc """
|
||||
Returns the number of pixels in a buffer.
|
||||
"""
|
||||
@spec count(Buffer.t) :: {:ok, non_neg_integer}
|
||||
@spec count(Buffer.t()) :: {:ok, non_neg_integer}
|
||||
def count(%Buffer{buffer: buffer}), do: {:ok, Enum.count(buffer)}
|
||||
|
||||
@doc """
|
||||
Returns whether a colour is a member of a buffer.
|
||||
This is mostly useless, but it's part of the Enumerable protocol.
|
||||
"""
|
||||
@spec member?(Buffer.t, RGBA.t) :: {:ok, boolean}
|
||||
@spec member?(Buffer.t(), RGBA.t()) :: {:ok, boolean}
|
||||
def member?(%Buffer{buffer: buffer}, colour), do: {:ok, Enum.member?(buffer, colour)}
|
||||
|
||||
@doc """
|
||||
Reduce the buffer into an accumulator.
|
||||
"""
|
||||
@spec reduce(Buffer.t, Collectable.t, (any, Collectable.t -> Collectable.t)) :: Collectable.t
|
||||
@spec reduce(Buffer.t(), Collectable.t(), (any, Collectable.t() -> Collectable.t())) ::
|
||||
Collectable.t()
|
||||
def reduce(%Buffer{buffer: buffer}, acc, fun), do: Enumerable.List.reduce(buffer, acc, fun)
|
||||
|
||||
@doc """
|
||||
Slice the buffer.
|
||||
"""
|
||||
@spec slice(Buffer.t) :: {:ok, size :: non_neg_integer(), Enumerable.slicing_fun()} | {:error, module()}
|
||||
@spec slice(Buffer.t()) ::
|
||||
{:ok, size :: non_neg_integer(), Enumerable.slicing_fun()} | {:error, module()}
|
||||
def slice(%Buffer{buffer: buffer}), do: Enumerable.List.slice(buffer)
|
||||
end
|
||||
|
|
|
@ -14,7 +14,7 @@ defimpl Enumerable, for: Vivid.Frame do
|
|||
...> |> Enum.count
|
||||
2
|
||||
"""
|
||||
@spec count(Frame.t) :: {:ok, non_neg_integer}
|
||||
@spec count(Frame.t()) :: {:ok, non_neg_integer}
|
||||
def count(%Frame{shapes: shapes}), do: {:ok, Enum.count(shapes)}
|
||||
|
||||
@doc """
|
||||
|
@ -30,7 +30,7 @@ defimpl Enumerable, for: Vivid.Frame do
|
|||
...> |> Enum.member?(Vivid.Point.init(2,2))
|
||||
false
|
||||
"""
|
||||
@spec member?(Frame.t, Shape.t) :: {:ok, boolean}
|
||||
@spec member?(Frame.t(), Shape.t()) :: {:ok, boolean}
|
||||
def member?(%Frame{shapes: shapes}, shape), do: {:ok, Enum.member?(shapes, shape)}
|
||||
|
||||
@doc """
|
||||
|
@ -41,12 +41,14 @@ defimpl Enumerable, for: Vivid.Frame do
|
|||
iex> Vivid.Frame.init([Vivid.Point.init(1,2), Vivid.Point.init(2,4)]) |> Enum.reduce(%{}, fn (%Vivid.Point{x: x, y: y}, acc) -> Map.put(acc, x, y) end)
|
||||
%{1 => 2, 2 => 4}
|
||||
"""
|
||||
@spec reduce(Frame.t, Collectable.t, (any, Collectable.t -> Collectable.t)) :: Collectable.t
|
||||
@spec reduce(Frame.t(), Collectable.t(), (any, Collectable.t() -> Collectable.t())) ::
|
||||
Collectable.t()
|
||||
def reduce(%Frame{shapes: shapes}, acc, fun), do: Enumerable.List.reduce(shapes, acc, fun)
|
||||
|
||||
@doc """
|
||||
Slice the frame.
|
||||
"""
|
||||
@spec slice(Frame.t) :: {:ok, size :: non_neg_integer(), Enumerable.slicing_fun()} | {:error, module()}
|
||||
@spec slice(Frame.t()) ::
|
||||
{:ok, size :: non_neg_integer(), Enumerable.slicing_fun()} | {:error, module()}
|
||||
def slice(%Frame{shapes: shapes}), do: Enumerable.List.slice(shapes)
|
||||
end
|
||||
|
|
|
@ -14,7 +14,7 @@ defimpl Enumerable, for: Vivid.Group do
|
|||
...> |> Enum.count
|
||||
2
|
||||
"""
|
||||
@spec count(Group.t) :: {:ok, non_neg_integer}
|
||||
@spec count(Group.t()) :: {:ok, non_neg_integer}
|
||||
def count(%Group{shapes: shapes}), do: {:ok, Enum.count(shapes)}
|
||||
|
||||
@doc """
|
||||
|
@ -30,7 +30,7 @@ defimpl Enumerable, for: Vivid.Group do
|
|||
...> |> Enum.member?(Vivid.Point.init(2,2))
|
||||
false
|
||||
"""
|
||||
@spec member?(Group.t, Shape.t) :: {:ok, boolean}
|
||||
@spec member?(Group.t(), Shape.t()) :: {:ok, boolean}
|
||||
def member?(%Group{shapes: shapes}, shape), do: {:ok, Enum.member?(shapes, shape)}
|
||||
|
||||
@doc """
|
||||
|
@ -41,12 +41,14 @@ defimpl Enumerable, for: Vivid.Group do
|
|||
iex> Vivid.Group.init([Vivid.Point.init(1,2), Vivid.Point.init(2,4)]) |> Enum.reduce(%{}, fn (%Vivid.Point{x: x, y: y}, acc) -> Map.put(acc, x, y) end)
|
||||
%{1 => 2, 2 => 4}
|
||||
"""
|
||||
@spec reduce(Group.t, Collectable.t, (Shape.t, Collectable.t -> Collectable.t)) :: Collectable.t
|
||||
@spec reduce(Group.t(), Collectable.t(), (Shape.t(), Collectable.t() -> Collectable.t())) ::
|
||||
Collectable.t()
|
||||
def reduce(%Group{shapes: shapes}, acc, fun), do: Enumerable.MapSet.reduce(shapes, acc, fun)
|
||||
|
||||
@doc """
|
||||
Slice the group.
|
||||
"""
|
||||
@spec slice(Group.t) :: {:ok, size :: non_neg_integer(), Enumerable.slicing_fun()} | {:error, module()}
|
||||
@spec slice(Group.t()) ::
|
||||
{:ok, size :: non_neg_integer(), Enumerable.slicing_fun()} | {:error, module()}
|
||||
def slice(%Group{shapes: shapes}), do: Enumerable.MapSet.slice(shapes)
|
||||
end
|
||||
|
|
|
@ -15,7 +15,7 @@ defimpl Enumerable, for: Vivid.Line do
|
|||
...> |> Enum.count
|
||||
2
|
||||
"""
|
||||
@spec count(Line.t) :: non_neg_integer
|
||||
@spec count(Line.t()) :: non_neg_integer
|
||||
def count(%Line{}), do: {:ok, 2}
|
||||
|
||||
@doc """
|
||||
|
@ -34,7 +34,7 @@ defimpl Enumerable, for: Vivid.Line do
|
|||
...> |> Enum.member?(Point.init(2,2))
|
||||
true
|
||||
"""
|
||||
@spec member?(Line.t, Point.t) :: boolean
|
||||
@spec member?(Line.t(), Point.t()) :: boolean
|
||||
def member?(%Line{origin: p0}, point) when p0 == point, do: {:ok, true}
|
||||
def member?(%Line{termination: p0}, point) when p0 == point, do: {:ok, true}
|
||||
def member?(_line, _point), do: {:ok, false}
|
||||
|
@ -49,12 +49,15 @@ defimpl Enumerable, for: Vivid.Line do
|
|||
...> |> Enum.reduce(%{}, fn point, points -> Map.put(points, Point.x(point), Point.y(point)) end)
|
||||
%{1 => 2, 2 => 4}
|
||||
"""
|
||||
@spec reduce(Line.t, Collectable.t, (Point.t, Collectable.t -> Collectable.t)) :: Collectable.t
|
||||
def reduce(%Line{origin: p0, termination: p1}, acc, fun), do: Enumerable.List.reduce([p0, p1], acc, fun)
|
||||
@spec reduce(Line.t(), Collectable.t(), (Point.t(), Collectable.t() -> Collectable.t())) ::
|
||||
Collectable.t()
|
||||
def reduce(%Line{origin: p0, termination: p1}, acc, fun),
|
||||
do: Enumerable.List.reduce([p0, p1], acc, fun)
|
||||
|
||||
@doc """
|
||||
Slices the line.
|
||||
"""
|
||||
@spec slice(Line.t) :: {:ok, size :: non_neg_integer(), Enumerable.slicing_fun()} | {:error, module()}
|
||||
@spec slice(Line.t()) ::
|
||||
{:ok, size :: non_neg_integer(), Enumerable.slicing_fun()} | {:error, module()}
|
||||
def slice(%Line{origin: p0, termination: p1}), do: Enumerable.List.slice([p0, p1])
|
||||
end
|
||||
|
|
|
@ -13,7 +13,7 @@ defimpl Enumerable, for: Vivid.Path do
|
|||
iex> Vivid.Path.init([Vivid.Point.init(1,1), Vivid.Point.init(2,2)]) |> Enum.count
|
||||
2
|
||||
"""
|
||||
@spec count(Path.t) :: {:ok, non_neg_integer}
|
||||
@spec count(Path.t()) :: {:ok, non_neg_integer}
|
||||
def count(%Path{vertices: points}), do: {:ok, Enum.count(points)}
|
||||
|
||||
@doc """
|
||||
|
@ -28,7 +28,7 @@ defimpl Enumerable, for: Vivid.Path do
|
|||
iex> Vivid.Path.init([Vivid.Point.init(1,1)]) |> Enum.member?(Vivid.Point.init(2,2))
|
||||
false
|
||||
"""
|
||||
@spec member?(Path.t, Point.t) :: {:ok, boolean}
|
||||
@spec member?(Path.t(), Point.t()) :: {:ok, boolean}
|
||||
def member?(%Path{vertices: points}, %Point{} = point), do: {:ok, Enum.member?(points, point)}
|
||||
|
||||
@doc """
|
||||
|
@ -39,12 +39,14 @@ defimpl Enumerable, for: Vivid.Path do
|
|||
iex> Vivid.Path.init([Vivid.Point.init(1,2), Vivid.Point.init(2,4)]) |> Enum.reduce(%{}, fn (%Vivid.Point{x: x, y: y}, acc) -> Map.put(acc, x, y) end)
|
||||
%{1 => 2, 2 => 4}
|
||||
"""
|
||||
@spec reduce(Path.t, Collectable.t, (Point.t, Collectable.t -> Collectable.t)) :: Collectable.t
|
||||
@spec reduce(Path.t(), Collectable.t(), (Point.t(), Collectable.t() -> Collectable.t())) ::
|
||||
Collectable.t()
|
||||
def reduce(%Path{vertices: points}, acc, fun), do: Enumerable.List.reduce(points, acc, fun)
|
||||
|
||||
@doc """
|
||||
Slices the Path.
|
||||
"""
|
||||
@spec slice(Path.t) :: {:ok, size :: non_neg_integer(), Enumerable.slicing_fun()} | {:error, module()}
|
||||
@spec slice(Path.t()) ::
|
||||
{:ok, size :: non_neg_integer(), Enumerable.slicing_fun()} | {:error, module()}
|
||||
def slice(%Path{vertices: points}), do: Enumerable.List.slice(points)
|
||||
end
|
||||
|
|
|
@ -13,7 +13,7 @@ defimpl Enumerable, for: Vivid.Polygon do
|
|||
iex> Vivid.Polygon.init([Vivid.Point.init(1,1), Vivid.Point.init(2,2)]) |> Enum.count
|
||||
2
|
||||
"""
|
||||
@spec count(Polygon.t) :: {:ok, non_neg_integer}
|
||||
@spec count(Polygon.t()) :: {:ok, non_neg_integer}
|
||||
def count(%Polygon{vertices: points}), do: {:ok, Enum.count(points)}
|
||||
|
||||
@doc """
|
||||
|
@ -28,8 +28,9 @@ defimpl Enumerable, for: Vivid.Polygon do
|
|||
iex> Vivid.Polygon.init([Vivid.Point.init(1,1)]) |> Enum.member?(Vivid.Point.init(2,2))
|
||||
false
|
||||
"""
|
||||
@spec member?(Polygon.t, Point.t) :: {:ok, boolean}
|
||||
def member?(%Polygon{vertices: points}, %Point{} = point), do: {:ok, Enum.member?(points, point)}
|
||||
@spec member?(Polygon.t(), Point.t()) :: {:ok, boolean}
|
||||
def member?(%Polygon{vertices: points}, %Point{} = point),
|
||||
do: {:ok, Enum.member?(points, point)}
|
||||
|
||||
@doc """
|
||||
Reduces the Polygon's vertices into an accumulator.
|
||||
|
@ -39,12 +40,14 @@ defimpl Enumerable, for: Vivid.Polygon do
|
|||
iex> Vivid.Polygon.init([Vivid.Point.init(1,2), Vivid.Point.init(2,4)]) |> Enum.reduce(%{}, fn (%Vivid.Point{x: x, y: y}, acc) -> Map.put(acc, x, y) end)
|
||||
%{1 => 2, 2 => 4}
|
||||
"""
|
||||
@spec reduce(Polygon.t, Collectable.t, (Point.t, Collectable.t -> Collectable.t)) :: Collectable.t
|
||||
@spec reduce(Polygon.t(), Collectable.t(), (Point.t(), Collectable.t() -> Collectable.t())) ::
|
||||
Collectable.t()
|
||||
def reduce(%Polygon{vertices: points}, acc, fun), do: Enumerable.List.reduce(points, acc, fun)
|
||||
|
||||
@doc """
|
||||
Slices the Polygon.
|
||||
"""
|
||||
@spec slice(Polygon.t) :: {:ok, size :: non_neg_integer(), Enumerable.slicing_fun()} | {:error, module()}
|
||||
@spec slice(Polygon.t()) ::
|
||||
{:ok, size :: non_neg_integer(), Enumerable.slicing_fun()} | {:error, module()}
|
||||
def slice(%Polygon{vertices: points}), do: Enumerable.List.slice(points)
|
||||
end
|
||||
|
|
|
@ -3,20 +3,22 @@ defimpl Inspect, for: Vivid.Arc do
|
|||
import Inspect.Algebra
|
||||
|
||||
@doc false
|
||||
@spec inspect(Arc.t, any) :: String.t
|
||||
@spec inspect(Arc.t(), any) :: String.t()
|
||||
def inspect(arc, opts) do
|
||||
center = arc |> Arc.center
|
||||
radius = arc |> Arc.radius
|
||||
start_angle = arc |> Arc.start_angle
|
||||
range = arc |> Arc.range
|
||||
steps = arc |> Arc.steps
|
||||
center = arc |> Arc.center()
|
||||
radius = arc |> Arc.radius()
|
||||
start_angle = arc |> Arc.start_angle()
|
||||
range = arc |> Arc.range()
|
||||
steps = arc |> Arc.steps()
|
||||
|
||||
details = [
|
||||
center: center,
|
||||
radius: radius,
|
||||
center: center,
|
||||
radius: radius,
|
||||
start_angle: start_angle,
|
||||
range: range,
|
||||
steps: steps
|
||||
range: range,
|
||||
steps: steps
|
||||
]
|
||||
concat ["#Vivid.Arc<", to_doc(details, opts), ">"]
|
||||
|
||||
concat(["#Vivid.Arc<", to_doc(details, opts), ">"])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,8 +5,8 @@ defimpl Inspect, for: Vivid.Bounds do
|
|||
@doc """
|
||||
Defines the inspect protocol for `Bounds`.
|
||||
"""
|
||||
@spec inspect(Bounds.t, any) :: String.t
|
||||
@spec inspect(Bounds.t(), any) :: String.t()
|
||||
def inspect(%Bounds{min: min, max: max}, opts) do
|
||||
concat ["#Vivid.Bounds<", to_doc([min: min, max: max], opts), ">"]
|
||||
concat(["#Vivid.Bounds<", to_doc([min: min, max: max], opts), ">"])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,12 +5,12 @@ defimpl Inspect, for: Vivid.Box do
|
|||
@doc """
|
||||
Defines the inspect protocol for `Box`.
|
||||
"""
|
||||
@spec inspect(Box.t, any) :: String.t
|
||||
@spec inspect(Box.t(), any) :: String.t()
|
||||
def inspect(%Box{bottom_left: bl, top_right: tr, fill: true}, opts) do
|
||||
concat ["#Vivid.Box<", to_doc([:filled, bottom_left: bl, top_right: tr], opts), ">"]
|
||||
concat(["#Vivid.Box<", to_doc([:filled, bottom_left: bl, top_right: tr], opts), ">"])
|
||||
end
|
||||
|
||||
def inspect(%Box{bottom_left: bl, top_right: tr}, opts) do
|
||||
concat ["#Vivid.Box<", to_doc([bottom_left: bl, top_right: tr], opts), ">"]
|
||||
concat(["#Vivid.Box<", to_doc([bottom_left: bl, top_right: tr], opts), ">"])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,8 +5,8 @@ defimpl Inspect, for: Vivid.Buffer do
|
|||
@doc """
|
||||
Defines the inspect protocol for `Buffer`.
|
||||
"""
|
||||
@spec inspect(Buffer.t, any) :: String.t
|
||||
@spec inspect(Buffer.t(), any) :: String.t()
|
||||
def inspect(%Buffer{rows: r, columns: c}, opts) do
|
||||
concat ["#Vivid.Buffer<", to_doc([rows: r, columns: c, size: r * c], opts), ">"]
|
||||
concat(["#Vivid.Buffer<", to_doc([rows: r, columns: c, size: r * c], opts), ">"])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,14 +5,14 @@ defimpl Inspect, for: Vivid.Circle do
|
|||
@doc """
|
||||
Defines the inspect protocol for `Circle`.
|
||||
"""
|
||||
@spec inspect(Cirlcle.t, any) :: String.t
|
||||
@spec inspect(Cirlcle.t(), any) :: String.t()
|
||||
def inspect(%Circle{center: c, radius: r, fill: true}, opts) do
|
||||
details = [center: c, radius: r, fill: true]
|
||||
concat ["#Vivid.Circle<", to_doc(details, opts), ">"]
|
||||
concat(["#Vivid.Circle<", to_doc(details, opts), ">"])
|
||||
end
|
||||
|
||||
def inspect(%Circle{center: c, radius: r}, opts) do
|
||||
details = [center: c, radius: r]
|
||||
concat ["#Vivid.Circle<", to_doc(details, opts), ">"]
|
||||
concat(["#Vivid.Circle<", to_doc(details, opts), ">"])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,14 +5,16 @@ defimpl Inspect, for: Vivid.Frame do
|
|||
@doc """
|
||||
Defines the inspect protocol for `Frame`.
|
||||
"""
|
||||
@spec inspect(Frame.t, any) :: String.t
|
||||
@spec inspect(Frame.t(), any) :: String.t()
|
||||
def inspect(frame, opts) do
|
||||
width = Frame.width(frame)
|
||||
width = Frame.width(frame)
|
||||
height = Frame.height(frame)
|
||||
colour = Frame.background_colour(frame)
|
||||
concat ["#Vivid.Frame<", to_doc([width: width,
|
||||
height: height,
|
||||
background_colour: colour
|
||||
], opts), ">"]
|
||||
|
||||
concat([
|
||||
"#Vivid.Frame<",
|
||||
to_doc([width: width, height: height, background_colour: colour], opts),
|
||||
">"
|
||||
])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,9 +5,9 @@ defimpl Inspect, for: Vivid.Group do
|
|||
@doc """
|
||||
Defines the inspect protocol for `Group`.
|
||||
"""
|
||||
@spec inspect(Group.t, any) :: String.t
|
||||
@spec inspect(Group.t(), any) :: String.t()
|
||||
def inspect(%Group{shapes: shapes}, opts) do
|
||||
shapes = shapes |> Enum.to_list
|
||||
concat ["#Vivid.Group<", to_doc(shapes, opts), ">"]
|
||||
shapes = shapes |> Enum.to_list()
|
||||
concat(["#Vivid.Group<", to_doc(shapes, opts), ">"])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,12 +5,13 @@ defimpl Inspect, for: Vivid.Line do
|
|||
@doc """
|
||||
Defines the inspect protocol for `Line`.
|
||||
"""
|
||||
@spec inspect(Line.t, any) :: String.t
|
||||
@spec inspect(Line.t(), any) :: String.t()
|
||||
def inspect(line, opts) do
|
||||
details = [
|
||||
origin: Line.origin(line),
|
||||
origin: Line.origin(line),
|
||||
termination: Line.termination(line)
|
||||
]
|
||||
concat ["#Vivid.Line<", to_doc(details, opts), ">"]
|
||||
|
||||
concat(["#Vivid.Line<", to_doc(details, opts), ">"])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,8 +5,8 @@ defimpl Inspect, for: Vivid.Path do
|
|||
@doc """
|
||||
Defines the inspect protocol for `Path`.
|
||||
"""
|
||||
@spec inspect(Path.t, any) :: String.t
|
||||
@spec inspect(Path.t(), any) :: String.t()
|
||||
def inspect(%Path{vertices: points}, opts) do
|
||||
concat ["#Vivid.Path<", to_doc(points, opts), ">"]
|
||||
concat(["#Vivid.Path<", to_doc(points, opts), ">"])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,10 +5,10 @@ defimpl Inspect, for: Vivid.Point do
|
|||
@doc """
|
||||
Defines the inspect protocol for `Point`.
|
||||
"""
|
||||
@spec inspect(Point.t, any) :: String.t
|
||||
@spec inspect(Point.t(), any) :: String.t()
|
||||
def inspect(point, opts) do
|
||||
x = point |> Point.x
|
||||
y = point |> Point.y
|
||||
concat ["#Vivid.Point<", to_doc({x, y}, opts), ">"]
|
||||
x = point |> Point.x()
|
||||
y = point |> Point.y()
|
||||
concat(["#Vivid.Point<", to_doc({x, y}, opts), ">"])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,12 +5,12 @@ defimpl Inspect, for: Vivid.Polygon do
|
|||
@doc """
|
||||
Defines the inspect protocol for `Polygon`.
|
||||
"""
|
||||
@spec inspect(Polygon.t, any) :: String.t
|
||||
@spec inspect(Polygon.t(), any) :: String.t()
|
||||
def inspect(%Polygon{vertices: points, fill: true}, opts) do
|
||||
concat ["#Vivid.Polygon<", to_doc([:filled | points], opts), ">"]
|
||||
concat(["#Vivid.Polygon<", to_doc([:filled | points], opts), ">"])
|
||||
end
|
||||
|
||||
def inspect(%Polygon{vertices: points}, opts) do
|
||||
concat ["#Vivid.Polygon<", to_doc(points, opts), ">"]
|
||||
concat(["#Vivid.Polygon<", to_doc(points, opts), ">"])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,12 +5,12 @@ defimpl Inspect, for: Vivid.RGBA do
|
|||
@doc """
|
||||
Defines the inspect protocol for `RGBA`.
|
||||
"""
|
||||
@spec inspect(RGBA.t, any) :: String.t
|
||||
@spec inspect(RGBA.t(), any) :: String.t()
|
||||
def inspect(colour, opts) do
|
||||
red = RGBA.red(colour)
|
||||
red = RGBA.red(colour)
|
||||
green = RGBA.green(colour)
|
||||
blue = RGBA.blue(colour)
|
||||
blue = RGBA.blue(colour)
|
||||
alpha = RGBA.alpha(colour)
|
||||
concat ["#Vivid.RGBA<", to_doc({red, green, blue, alpha}, opts), ">"]
|
||||
concat(["#Vivid.RGBA<", to_doc({red, green, blue, alpha}, opts), ">"])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,11 +6,13 @@ defimpl Inspect, for: Vivid.Transform do
|
|||
@doc """
|
||||
Defines the inspect protocol for `Transform`.
|
||||
"""
|
||||
@spec inspect(Transform.t, any) :: String.t
|
||||
@spec inspect(Transform.t(), any) :: String.t()
|
||||
def inspect(%Transform{operations: operations, shape: shape}, opts) do
|
||||
operations = operations
|
||||
operations =
|
||||
operations
|
||||
|> Stream.map(fn %Operation{name: name} -> name end)
|
||||
|> Enum.reverse
|
||||
concat ["#Vivid.Transform<", to_doc([operations: operations, shape: shape], opts), ">"]
|
||||
|> Enum.reverse()
|
||||
|
||||
concat(["#Vivid.Transform<", to_doc([operations: operations, shape: shape], opts), ">"])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,18 +4,20 @@ defimpl String.Chars, for: Vivid.Buffer do
|
|||
@doc """
|
||||
Convert a `buffer` into a `string` for `IO.puts`, etc.
|
||||
"""
|
||||
@spec to_string(Buffer.t) :: String.t
|
||||
@spec to_string(Buffer.t()) :: String.t()
|
||||
def to_string(%Buffer{buffer: buffer, columns: columns} = _buffer) do
|
||||
s = buffer
|
||||
|> Enum.reverse
|
||||
s =
|
||||
buffer
|
||||
|> Enum.reverse()
|
||||
|> Enum.chunk(columns)
|
||||
|> Enum.map(fn (row) ->
|
||||
|> Enum.map(fn row ->
|
||||
row
|
||||
|> Enum.reverse
|
||||
|> Enum.reverse()
|
||||
|> Enum.map(&RGBA.to_ascii(&1))
|
||||
|> Enum.join
|
||||
|> Enum.join()
|
||||
end)
|
||||
|> Enum.join("\n")
|
||||
|
||||
s <> "\n"
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,10 +4,10 @@ defimpl String.Chars, for: Vivid.Frame do
|
|||
@doc """
|
||||
Convert a `frame` into a `string` for `IO.puts`, etc.
|
||||
"""
|
||||
@spec to_string(Frame.t) :: String.t
|
||||
@spec to_string(Frame.t()) :: String.t()
|
||||
def to_string(%Frame{} = frame) do
|
||||
frame
|
||||
|> Frame.buffer
|
||||
|> Kernel.to_string
|
||||
|> Frame.buffer()
|
||||
|> Kernel.to_string()
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,25 +8,27 @@ defmodule Vivid.ShapeToString do
|
|||
@doc """
|
||||
Convert a `shape` into a `string` for `IO.puts`, etc.
|
||||
"""
|
||||
@spec to_string(Shape.t) :: String.t
|
||||
@spec to_string(Shape.t()) :: String.t()
|
||||
def to_string(shape) do
|
||||
bounds = Bounds.bounds(shape)
|
||||
width = round(Bounds.width(bounds) + 3)
|
||||
width = round(Bounds.width(bounds) + 3)
|
||||
height = round(Bounds.height(bounds) + 3)
|
||||
frame = Frame.init(width, height, RGBA.white)
|
||||
frame = Frame.init(width, height, RGBA.white())
|
||||
|
||||
shape = shape
|
||||
shape =
|
||||
shape
|
||||
|> Transform.center(frame)
|
||||
|> Transform.apply
|
||||
|> Transform.apply()
|
||||
|
||||
frame
|
||||
|> Frame.push(shape, RGBA.black)
|
||||
|> Kernel.to_string
|
||||
|> Frame.push(shape, RGBA.black())
|
||||
|> Kernel.to_string()
|
||||
end
|
||||
end
|
||||
|
||||
Enum.each(~w(Arc Box Circle Group Line Path Polygon), fn type ->
|
||||
mod = Module.concat(Vivid, type)
|
||||
|
||||
defimpl String.Chars, for: mod do
|
||||
@moduledoc """
|
||||
Convert a shape into a string.
|
||||
|
@ -35,7 +37,7 @@ Enum.each(~w(Arc Box Circle Group Line Path Polygon), fn type ->
|
|||
@doc """
|
||||
Convert `shape` into a `string` for `IO.puts`, etc.
|
||||
"""
|
||||
@spec to_string(Shape.t) :: String.t
|
||||
@spec to_string(Shape.t()) :: String.t()
|
||||
def to_string(shape), do: Vivid.ShapeToString.to_string(shape)
|
||||
end
|
||||
end)
|
||||
|
|
23
lib/vivid.ex
23
lib/vivid.ex
|
@ -1,9 +1,26 @@
|
|||
defmodule Vivid do
|
||||
defmacro __using__(_opts) do
|
||||
quote do
|
||||
alias Vivid.{Arc, Bounds, Buffer, Circle, Font, Frame, Group, Font, Frame,
|
||||
Group, Line, Path, Point, Polygon, Rasterize, RGBA,
|
||||
Transform, Box}
|
||||
alias Vivid.{
|
||||
Arc,
|
||||
Bounds,
|
||||
Buffer,
|
||||
Circle,
|
||||
Font,
|
||||
Frame,
|
||||
Group,
|
||||
Font,
|
||||
Frame,
|
||||
Group,
|
||||
Line,
|
||||
Path,
|
||||
Point,
|
||||
Polygon,
|
||||
Rasterize,
|
||||
RGBA,
|
||||
Transform,
|
||||
Box
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ defmodule Vivid.Arc do
|
|||
|
||||
"""
|
||||
|
||||
@opaque t :: %Arc{center: Point.t, radius: number, start_angle: number, steps: integer}
|
||||
@opaque t :: %Arc{center: Point.t(), radius: number, start_angle: number, steps: integer}
|
||||
|
||||
@doc ~S"""
|
||||
Creates an Arc.
|
||||
|
@ -46,19 +46,15 @@ defmodule Vivid.Arc do
|
|||
steps: 12
|
||||
}
|
||||
"""
|
||||
@spec init(Point.t, number, number, number, integer) :: Arc.t
|
||||
@spec init(Point.t(), number, number, number, integer) :: Arc.t()
|
||||
def init(%Point{} = center, radius, start_angle, range, steps \\ 12)
|
||||
when is_number(radius)
|
||||
and is_number(start_angle)
|
||||
and is_number(range)
|
||||
and is_integer(steps)
|
||||
do
|
||||
when is_number(radius) and is_number(start_angle) and is_number(range) and is_integer(steps) do
|
||||
%Arc{
|
||||
center: center,
|
||||
radius: radius,
|
||||
center: center,
|
||||
radius: radius,
|
||||
start_angle: start_angle,
|
||||
range: range,
|
||||
steps: steps
|
||||
range: range,
|
||||
steps: steps
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -71,7 +67,7 @@ defmodule Vivid.Arc do
|
|||
...> |> Vivid.Arc.center
|
||||
#Vivid.Point<{10, 10}>
|
||||
"""
|
||||
@spec center(Arc.t) :: Point.t
|
||||
@spec center(Arc.t()) :: Point.t()
|
||||
def center(%Arc{center: p} = _arc), do: p
|
||||
|
||||
@doc """
|
||||
|
@ -84,7 +80,7 @@ defmodule Vivid.Arc do
|
|||
...> |> Vivid.Arc.center
|
||||
#Vivid.Point<{15, 15}>
|
||||
"""
|
||||
@spec center(Arc.t, Point.t) :: Arc.t
|
||||
@spec center(Arc.t(), Point.t()) :: Arc.t()
|
||||
def center(%Arc{} = arc, %Point{} = point), do: %{arc | center: point}
|
||||
|
||||
@doc """
|
||||
|
@ -96,7 +92,7 @@ defmodule Vivid.Arc do
|
|||
...> |> Vivid.Arc.radius
|
||||
5
|
||||
"""
|
||||
@spec radius(Arc.t) :: number
|
||||
@spec radius(Arc.t()) :: number
|
||||
def radius(%Arc{radius: r} = _arc), do: r
|
||||
|
||||
@doc """
|
||||
|
@ -109,7 +105,7 @@ defmodule Vivid.Arc do
|
|||
...> |> Vivid.Arc.radius
|
||||
10
|
||||
"""
|
||||
@spec radius(Arc.t, number) :: Arc.t
|
||||
@spec radius(Arc.t(), number) :: Arc.t()
|
||||
def radius(%Arc{} = arc, radius) when is_number(radius), do: %{arc | radius: radius}
|
||||
|
||||
@doc """
|
||||
|
@ -121,7 +117,7 @@ defmodule Vivid.Arc do
|
|||
...> |> Vivid.Arc.start_angle
|
||||
0
|
||||
"""
|
||||
@spec start_angle(Arc.t) :: number
|
||||
@spec start_angle(Arc.t()) :: number
|
||||
def start_angle(%Arc{start_angle: a} = _arc), do: a
|
||||
|
||||
@doc """
|
||||
|
@ -134,7 +130,7 @@ defmodule Vivid.Arc do
|
|||
...> |> Vivid.Arc.start_angle
|
||||
45
|
||||
"""
|
||||
@spec start_angle(Arc.t, number) :: Arc.t
|
||||
@spec start_angle(Arc.t(), number) :: Arc.t()
|
||||
def start_angle(%Arc{} = arc, theta), do: %{arc | start_angle: theta}
|
||||
|
||||
@doc """
|
||||
|
@ -146,7 +142,7 @@ defmodule Vivid.Arc do
|
|||
...> |> Vivid.Arc.range
|
||||
90
|
||||
"""
|
||||
@spec range(Arc.t) :: number
|
||||
@spec range(Arc.t()) :: number
|
||||
def range(%Arc{range: r} = _arc), do: r
|
||||
|
||||
@doc """
|
||||
|
@ -159,7 +155,7 @@ defmodule Vivid.Arc do
|
|||
...> |> Vivid.Arc.range
|
||||
270
|
||||
"""
|
||||
@spec range(Arc.t, number) :: Arc.t
|
||||
@spec range(Arc.t(), number) :: Arc.t()
|
||||
def range(%Arc{} = arc, theta) when is_number(theta), do: %{arc | range: theta}
|
||||
|
||||
@doc """
|
||||
|
@ -171,7 +167,7 @@ defmodule Vivid.Arc do
|
|||
...> |> Vivid.Arc.steps
|
||||
12
|
||||
"""
|
||||
@spec steps(Arc.t) :: integer
|
||||
@spec steps(Arc.t()) :: integer
|
||||
def steps(%Arc{steps: s} = _arc), do: s
|
||||
|
||||
@doc """
|
||||
|
@ -184,7 +180,7 @@ defmodule Vivid.Arc do
|
|||
...> |> Vivid.Arc.steps
|
||||
19
|
||||
"""
|
||||
@spec steps(Arc.t, integer) :: Arc.t
|
||||
@spec steps(Arc.t(), integer) :: Arc.t()
|
||||
def steps(%Arc{} = arc, steps) when is_integer(steps), do: %{arc | steps: steps}
|
||||
|
||||
@doc """
|
||||
|
@ -197,25 +193,29 @@ defmodule Vivid.Arc do
|
|||
...> |> Vivid.Arc.to_path
|
||||
#Vivid.Path<[#Vivid.Point<{5, 10}>, #Vivid.Point<{6, 13}>, #Vivid.Point<{8, 14}>, #Vivid.Point<{10, 15}>]>
|
||||
"""
|
||||
@spec to_path(Arc.t) :: Path.t
|
||||
def to_path(%Arc{center: center, radius: radius, start_angle: start_angle, range: range, steps: steps} = _arc) do
|
||||
h = center |> Point.x
|
||||
k = center |> Point.y
|
||||
@spec to_path(Arc.t()) :: Path.t()
|
||||
def to_path(
|
||||
%Arc{center: center, radius: radius, start_angle: start_angle, range: range, steps: steps} =
|
||||
_arc
|
||||
) do
|
||||
h = center |> Point.x()
|
||||
k = center |> Point.y()
|
||||
|
||||
step_degree = range / steps
|
||||
start_angle = start_angle - 180
|
||||
|
||||
points = Enum.map(0..steps, fn(step) ->
|
||||
theta = (step_degree * step) + start_angle
|
||||
theta = degrees_to_radians(theta)
|
||||
points =
|
||||
Enum.map(0..steps, fn step ->
|
||||
theta = step_degree * step + start_angle
|
||||
theta = degrees_to_radians(theta)
|
||||
|
||||
x = round(h + radius * cos(theta))
|
||||
y = round(k - radius * sin(theta))
|
||||
x = round(h + radius * cos(theta))
|
||||
y = round(k - radius * sin(theta))
|
||||
|
||||
Point.init(x, y)
|
||||
end)
|
||||
Point.init(x, y)
|
||||
end)
|
||||
|
||||
points
|
||||
|> Path.init
|
||||
|> Path.init()
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,7 +13,7 @@ defmodule Vivid.Bounds do
|
|||
#Vivid.Bounds<[min: #Vivid.Point<{5, 10}>, max: #Vivid.Point<{15, 20}>]>
|
||||
"""
|
||||
|
||||
@opaque t :: %Bounds{min: Point.t, max: Point.t}
|
||||
@opaque t :: %Bounds{min: Point.t(), max: Point.t()}
|
||||
|
||||
@doc """
|
||||
Initialise arbitrary bounds.
|
||||
|
@ -28,7 +28,7 @@ defmodule Vivid.Bounds do
|
|||
iex> Vivid.Bounds.init(0, 0, 5, 5)
|
||||
#Vivid.Bounds<[min: #Vivid.Point<{0, 0}>, max: #Vivid.Point<{5, 5}>]>
|
||||
"""
|
||||
@spec init(number, number, number, number) :: Bounds.t
|
||||
@spec init(number, number, number, number) :: Bounds.t()
|
||||
def init(x0, y0, x1, y1), do: %Bounds{min: Point.init(x0, y0), max: Point.init(x1, y1)}
|
||||
|
||||
@doc """
|
||||
|
@ -42,8 +42,9 @@ defmodule Vivid.Bounds do
|
|||
...> |> Vivid.Bounds.bounds
|
||||
#Vivid.Bounds<[min: #Vivid.Point<{0.0, 0.0}>, max: #Vivid.Point<{20.0, 20.0}>]>
|
||||
"""
|
||||
@spec bounds(Shape.t) :: Bounds.t
|
||||
@spec bounds(Shape.t()) :: Bounds.t()
|
||||
def bounds(%Bounds{} = shape), do: shape
|
||||
|
||||
def bounds(shape) do
|
||||
{min, max} = Of.bounds(shape)
|
||||
%Bounds{min: min, max: max}
|
||||
|
@ -60,7 +61,7 @@ defmodule Vivid.Bounds do
|
|||
...> |> Vivid.Bounds.width
|
||||
20.0
|
||||
"""
|
||||
@spec width(Shape.t) :: number
|
||||
@spec width(Shape.t()) :: number
|
||||
def width(%Bounds{min: %Point{x: x0}, max: %Point{x: x1}} = _shape), do: abs(x1 - x0)
|
||||
def width(shape), do: shape |> bounds |> width
|
||||
|
||||
|
@ -75,7 +76,7 @@ defmodule Vivid.Bounds do
|
|||
...> |> Vivid.Bounds.height
|
||||
20.0
|
||||
"""
|
||||
@spec height(Shape.t) :: number
|
||||
@spec height(Shape.t()) :: number
|
||||
def height(%Bounds{min: %Point{y: y0}, max: %Point{y: y1}}), do: abs(y1 - y0)
|
||||
def height(shape), do: shape |> bounds |> height
|
||||
|
||||
|
@ -90,7 +91,7 @@ defmodule Vivid.Bounds do
|
|||
...> |> Vivid.Bounds.min
|
||||
#Vivid.Point<{0.0, 0.0}>
|
||||
"""
|
||||
@spec min(Shape.t) :: Point.t
|
||||
@spec min(Shape.t()) :: Point.t()
|
||||
def min(%Bounds{min: min} = _shape), do: min
|
||||
def min(shape), do: shape |> bounds |> min
|
||||
|
||||
|
@ -105,7 +106,7 @@ defmodule Vivid.Bounds do
|
|||
...> |> Vivid.Bounds.max
|
||||
#Vivid.Point<{20.0, 20.0}>
|
||||
"""
|
||||
@spec max(Shape.t) :: Point.t
|
||||
@spec max(Shape.t()) :: Point.t()
|
||||
def max(%Bounds{max: max}), do: max
|
||||
def max(shape), do: shape |> bounds |> max
|
||||
|
||||
|
@ -121,12 +122,13 @@ defmodule Vivid.Bounds do
|
|||
...> |> Vivid.Bounds.center_of
|
||||
#Vivid.Point<{10.0, 10.0}>
|
||||
"""
|
||||
@spec center_of(Shape.t) :: Point.t
|
||||
@spec center_of(Shape.t()) :: Point.t()
|
||||
def center_of(%Bounds{min: %Point{x: x0, y: y0}, max: %Point{x: x1, y: y1}}) do
|
||||
x = x0 + (x1 - x0) / 2
|
||||
y = y0 + (y1 - y0) / 2
|
||||
Point.init(x, y)
|
||||
end
|
||||
|
||||
def center_of(shape), do: shape |> bounds |> center_of
|
||||
|
||||
@doc """
|
||||
|
@ -161,7 +163,13 @@ defmodule Vivid.Bounds do
|
|||
...> |> Vivid.Bounds.contains?(Vivid.Point.init(11, 11))
|
||||
false
|
||||
"""
|
||||
@spec contains?(Shape.t, Point.t) :: boolean
|
||||
def contains?(%Bounds{min: %Point{x: x0, y: y0}, max: %Point{x: x1, y: y1}} = _shape, %Point{x: x, y: y} = _point) when x0 <= x and x <= x1 and y0 <= y and y <= y1, do: true
|
||||
@spec contains?(Shape.t(), Point.t()) :: boolean
|
||||
def contains?(
|
||||
%Bounds{min: %Point{x: x0, y: y0}, max: %Point{x: x1, y: y1}} = _shape,
|
||||
%Point{x: x, y: y} = _point
|
||||
)
|
||||
when x0 <= x and x <= x1 and y0 <= y and y <= y1,
|
||||
do: true
|
||||
|
||||
def contains?(_shape, _point), do: false
|
||||
end
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
defprotocol Vivid.Bounds.Of do
|
||||
alias Vivid.{Shape, Point}
|
||||
|
||||
@moduledoc """
|
||||
This protocol is used to calculate the bounds of a given shape.
|
||||
|
||||
|
@ -10,6 +11,6 @@ defprotocol Vivid.Bounds.Of do
|
|||
Return the bounds of a Shape as a two element tuple of bottom-left and
|
||||
top-right points.
|
||||
"""
|
||||
@spec bounds(Shape.t) :: {Point.t, Point.t}
|
||||
@spec bounds(Shape.t()) :: {Point.t(), Point.t()}
|
||||
def bounds(shape)
|
||||
end
|
||||
|
|
|
@ -6,10 +6,10 @@ defimpl Vivid.Bounds.Of, for: Vivid.Arc do
|
|||
|
||||
Returns a two-element tuple of the bottom-left and top-right points.
|
||||
"""
|
||||
@spec bounds(Arc.t) :: {Point.t, Point.t}
|
||||
@spec bounds(Arc.t()) :: {Point.t(), Point.t()}
|
||||
def bounds(arc) do
|
||||
arc
|
||||
|> Arc.to_path
|
||||
|> Bounds.Of.bounds
|
||||
|> Arc.to_path()
|
||||
|> Bounds.Of.bounds()
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,6 +6,6 @@ defimpl Vivid.Bounds.Of, for: Vivid.Bounds do
|
|||
|
||||
Returns a two-element tuple of the bottom-left and top-right points.
|
||||
"""
|
||||
@spec bounds(Bounds.t) :: {Point.t, Point.t}
|
||||
@spec bounds(Bounds.t()) :: {Point.t(), Point.t()}
|
||||
def bounds(%Bounds{min: min, max: max} = _bounds), do: {min, max}
|
||||
end
|
||||
|
|
|
@ -6,6 +6,6 @@ defimpl Vivid.Bounds.Of, for: Vivid.Box do
|
|||
|
||||
Returns a two-element tuple of the bottom-left and top-right points.
|
||||
"""
|
||||
@spec bounds(Box.t) :: {Point.t, Point.t}
|
||||
@spec bounds(Box.t()) :: {Point.t(), Point.t()}
|
||||
def bounds(%Box{bottom_left: bl, top_right: tr} = _box), do: {bl, tr}
|
||||
end
|
||||
|
|
|
@ -6,10 +6,10 @@ defimpl Vivid.Bounds.Of, for: Vivid.Circle do
|
|||
|
||||
Returns a two-element tuple of the bottom-left and top-right points.
|
||||
"""
|
||||
@spec bounds(Circle.t) :: {Point.t, Point.t}
|
||||
@spec bounds(Circle.t()) :: {Point.t(), Point.t()}
|
||||
def bounds(circle) do
|
||||
circle
|
||||
|> Circle.to_polygon
|
||||
|> Bounds.Of.bounds
|
||||
|> Circle.to_polygon()
|
||||
|> Bounds.Of.bounds()
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,7 +6,7 @@ defimpl Vivid.Bounds.Of, for: Vivid.Frame do
|
|||
|
||||
Returns a two-element tuple of the bottom-left and top-right points.
|
||||
"""
|
||||
@spec bounds(Frame.t) :: {Point.t, Point.t}
|
||||
@spec bounds(Frame.t()) :: {Point.t(), Point.t()}
|
||||
def bounds(%Frame{width: w, height: h} = _frame) do
|
||||
{Point.init(0, 0), Point.init(w - 1, h - 1)}
|
||||
end
|
||||
|
|
|
@ -6,12 +6,14 @@ defimpl Vivid.Bounds.Of, for: Vivid.Group do
|
|||
|
||||
Returns a two-element tuple of the bottom-left and top-right points.
|
||||
"""
|
||||
@spec bounds(Group.t) :: {Point.t, Point.t}
|
||||
@spec bounds(Group.t()) :: {Point.t(), Point.t()}
|
||||
def bounds(%Vivid.Group{shapes: shapes} = _group) do
|
||||
shapes
|
||||
|> Enum.map(&Vivid.Bounds.Of.bounds(&1))
|
||||
|> Enum.reduce(fn
|
||||
{min, max}, nil -> {min, max}
|
||||
{min, max}, nil ->
|
||||
{min, max}
|
||||
|
||||
{pmin, pmax}, {min, max} ->
|
||||
min = if pmin.x < min.x, do: Point.init(pmin.x, min.y), else: min
|
||||
min = if pmin.y < min.y, do: Point.init(min.x, pmin.y), else: min
|
||||
|
|
|
@ -6,6 +6,6 @@ defimpl Vivid.Bounds.Of, for: Vivid.Line do
|
|||
|
||||
Returns a two-element tuple of the line-ends, left to right.
|
||||
"""
|
||||
@spec bounds(Line.t) :: {Point.t, Point.t}
|
||||
@spec bounds(Line.t()) :: {Point.t(), Point.t()}
|
||||
def bounds(%Line{origin: p0, termination: p1} = _line), do: Vivid.Bounds.Of.bounds([p0, p1])
|
||||
end
|
||||
|
|
|
@ -6,10 +6,12 @@ defimpl Vivid.Bounds.Of, for: List do
|
|||
|
||||
Returns a two-element tuple of the bottom-left and top-right points.
|
||||
"""
|
||||
@spec bounds([Point.t, ...]) :: {Point.t, Point.t}
|
||||
@spec bounds([Point.t(), ...]) :: {Point.t(), Point.t()}
|
||||
def bounds(points) do
|
||||
Enum.reduce(points, nil, fn
|
||||
point, nil -> {point, point}
|
||||
point, nil ->
|
||||
{point, point}
|
||||
|
||||
point, {min, max} ->
|
||||
x = Point.x(point)
|
||||
y = Point.y(point)
|
||||
|
|
|
@ -6,6 +6,6 @@ defimpl Vivid.Bounds.Of, for: Vivid.Path do
|
|||
|
||||
Returns a two-element tuple of the bottom-left and top-right points.
|
||||
"""
|
||||
@spec bounds(Path.t) :: {Point.t, Point.t}
|
||||
@spec bounds(Path.t()) :: {Point.t(), Point.t()}
|
||||
def bounds(%Path{vertices: points} = _path), do: Vivid.Bounds.Of.bounds(points)
|
||||
end
|
||||
|
|
|
@ -7,6 +7,6 @@ defimpl Vivid.Bounds.Of, for: Vivid.Point do
|
|||
Since the bounds of a point are simply the point, it returns the point
|
||||
twice.
|
||||
"""
|
||||
@spec bounds(Point.t) :: {Point.t, Point.t}
|
||||
@spec bounds(Point.t()) :: {Point.t(), Point.t()}
|
||||
def bounds(point), do: {point, point}
|
||||
end
|
||||
|
|
|
@ -6,6 +6,6 @@ defimpl Vivid.Bounds.Of, for: Vivid.Polygon do
|
|||
|
||||
Returns a two-element tuple of the bottom-left and top-right points.
|
||||
"""
|
||||
@spec bounds(Polygon.t) :: {Point.t, Point.t}
|
||||
@spec bounds(Polygon.t()) :: {Point.t(), Point.t()}
|
||||
def bounds(%Polygon{vertices: points} = _polygon), do: Vivid.Bounds.Of.bounds(points)
|
||||
end
|
||||
|
|
|
@ -28,7 +28,7 @@ defmodule Vivid.Box do
|
|||
"@@@@@@@@@@@@@\n"
|
||||
"""
|
||||
|
||||
@opaque t :: Box.t
|
||||
@opaque t :: Box.t()
|
||||
|
||||
@doc """
|
||||
Initialize an unfilled Box from it's bottom left and top right points.
|
||||
|
@ -42,7 +42,7 @@ defmodule Vivid.Box do
|
|||
...> Box.init(Point.init(1,1), Point.init(4,4))
|
||||
#Vivid.Box<[bottom_left: #Vivid.Point<{1, 1}>, top_right: #Vivid.Point<{4, 4}>]>
|
||||
"""
|
||||
@spec init(Point.t, Point.t) :: Box.t
|
||||
@spec init(Point.t(), Point.t()) :: Box.t()
|
||||
def init(%Point{} = bottom_left, %Point{} = top_right), do: init(bottom_left, top_right, false)
|
||||
|
||||
@doc """
|
||||
|
@ -58,8 +58,9 @@ defmodule Vivid.Box do
|
|||
...> Box.init(Point.init(1,1), Point.init(4,4))
|
||||
#Vivid.Box<[bottom_left: #Vivid.Point<{1, 1}>, top_right: #Vivid.Point<{4, 4}>]>
|
||||
"""
|
||||
@spec init(Point.t, Point.t, boolean) :: Box.t
|
||||
def init(%Point{} = bottom_left, %Point{} = top_right, fill) when is_boolean(fill), do: %Box{bottom_left: bottom_left, top_right: top_right, fill: fill}
|
||||
@spec init(Point.t(), Point.t(), boolean) :: Box.t()
|
||||
def init(%Point{} = bottom_left, %Point{} = top_right, fill) when is_boolean(fill),
|
||||
do: %Box{bottom_left: bottom_left, top_right: top_right, fill: fill}
|
||||
|
||||
@doc """
|
||||
Initialize a box from the bounds of an arbitrary shape.
|
||||
|
@ -71,11 +72,11 @@ defmodule Vivid.Box do
|
|||
...> |> Box.init_from_bounds
|
||||
#Vivid.Box<[bottom_left: #Vivid.Point<{0.0, 0.2447174185242318}>, top_right: #Vivid.Point<{10.0, 9.755282581475768}>]>
|
||||
"""
|
||||
@spec init_from_bounds(Shape.t, boolean) :: Box.t
|
||||
@spec init_from_bounds(Shape.t(), boolean) :: Box.t()
|
||||
def init_from_bounds(shape, fill \\ false) do
|
||||
bounds = shape |> Bounds.bounds
|
||||
min = bounds |> Bounds.min
|
||||
max = bounds |> Bounds.max
|
||||
bounds = shape |> Bounds.bounds()
|
||||
min = bounds |> Bounds.min()
|
||||
max = bounds |> Bounds.max()
|
||||
init(min, max, fill)
|
||||
end
|
||||
|
||||
|
@ -89,7 +90,7 @@ defmodule Vivid.Box do
|
|||
...> |> Box.bottom_left
|
||||
#Vivid.Point<{1, 1}>
|
||||
"""
|
||||
@spec bottom_left(Box.t) :: Point.t
|
||||
@spec bottom_left(Box.t()) :: Point.t()
|
||||
def bottom_left(%Box{bottom_left: bl}), do: bl
|
||||
|
||||
@doc """
|
||||
|
@ -102,7 +103,7 @@ defmodule Vivid.Box do
|
|||
...> |> Box.top_left
|
||||
#Vivid.Point<{1, 4}>
|
||||
"""
|
||||
@spec top_left(Box.t) :: Point.t
|
||||
@spec top_left(Box.t()) :: Point.t()
|
||||
def top_left(%Box{bottom_left: bl, top_right: tr}), do: Point.init(bl.x, tr.y)
|
||||
|
||||
@doc """
|
||||
|
@ -115,7 +116,7 @@ defmodule Vivid.Box do
|
|||
...> |> Box.top_right
|
||||
#Vivid.Point<{4, 4}>
|
||||
"""
|
||||
@spec top_right(Box.t) :: Point.t
|
||||
@spec top_right(Box.t()) :: Point.t()
|
||||
def top_right(%Box{top_right: tr}), do: tr
|
||||
|
||||
@doc """
|
||||
|
@ -128,7 +129,7 @@ defmodule Vivid.Box do
|
|||
...> |> Box.bottom_right
|
||||
#Vivid.Point<{4, 1}>
|
||||
"""
|
||||
@spec bottom_right(Box.t) :: Point.t
|
||||
@spec bottom_right(Box.t()) :: Point.t()
|
||||
def bottom_right(%Box{bottom_left: bl, top_right: tr}), do: Point.init(tr.x, bl.y)
|
||||
|
||||
@doc """
|
||||
|
@ -141,13 +142,16 @@ defmodule Vivid.Box do
|
|||
...> |> Box.to_polygon
|
||||
#Vivid.Polygon<[#Vivid.Point<{1, 1}>, #Vivid.Point<{1, 4}>, #Vivid.Point<{4, 4}>, #Vivid.Point<{4, 1}>]>
|
||||
"""
|
||||
@spec to_polygon(Box.t) :: Polygon.t
|
||||
@spec to_polygon(Box.t()) :: Polygon.t()
|
||||
def to_polygon(%Box{fill: fill} = box) do
|
||||
Polygon.init([
|
||||
bottom_left(box),
|
||||
top_left(box),
|
||||
top_right(box),
|
||||
bottom_right(box)
|
||||
], fill)
|
||||
Polygon.init(
|
||||
[
|
||||
bottom_left(box),
|
||||
top_left(box),
|
||||
top_right(box),
|
||||
bottom_right(box)
|
||||
],
|
||||
fill
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -35,7 +35,7 @@ defmodule Vivid.Buffer do
|
|||
"@@@@@@@@@@@@@@@@@@@@"
|
||||
"""
|
||||
|
||||
@opaque t :: %Buffer{buffer: [RGBA.t], rows: integer, columns: integer}
|
||||
@opaque t :: %Buffer{buffer: [RGBA.t()], rows: integer, columns: integer}
|
||||
|
||||
@doc ~S"""
|
||||
Render the buffer horizontally, ie across rows then up columns.
|
||||
|
@ -53,11 +53,11 @@ defmodule Vivid.Buffer do
|
|||
"@@@@@\n" <>
|
||||
"@@@@@\n"
|
||||
"""
|
||||
@spec horizontal(Frame.t) :: [RGBA.t]
|
||||
@spec horizontal(Frame.t()) :: [RGBA.t()]
|
||||
def horizontal(%Frame{shapes: shapes, width: w, height: h} = frame) do
|
||||
empty_buffer = allocate(frame)
|
||||
bounds = Bounds.bounds(frame)
|
||||
buffer = Enum.reduce(shapes, empty_buffer, &horizontal_reducer(&1, &2, bounds, w))
|
||||
bounds = Bounds.bounds(frame)
|
||||
buffer = Enum.reduce(shapes, empty_buffer, &horizontal_reducer(&1, &2, bounds, w))
|
||||
%Buffer{buffer: buffer, rows: h, columns: w}
|
||||
end
|
||||
|
||||
|
@ -77,11 +77,11 @@ defmodule Vivid.Buffer do
|
|||
"@@ @@\n" <>
|
||||
"@@ @@\n"
|
||||
"""
|
||||
@spec vertical(Frame.t) :: [RGBA.t]
|
||||
@spec vertical(Frame.t()) :: [RGBA.t()]
|
||||
def vertical(%Frame{shapes: shapes, width: w, height: h} = frame) do
|
||||
bounds = Bounds.bounds(frame)
|
||||
bounds = Bounds.bounds(frame)
|
||||
empty_buffer = allocate(frame)
|
||||
buffer = Enum.reduce(shapes, empty_buffer, &vertical_reducer(&1, &2, bounds, h))
|
||||
buffer = Enum.reduce(shapes, empty_buffer, &vertical_reducer(&1, &2, bounds, h))
|
||||
|
||||
%Buffer{buffer: buffer, rows: w, columns: h}
|
||||
end
|
||||
|
@ -100,8 +100,9 @@ defmodule Vivid.Buffer do
|
|||
|
||||
defp horizontal_reducer({shape, colour}, buffer, bounds, width) do
|
||||
points = Rasterize.rasterize(shape, bounds)
|
||||
Enum.reduce(points, buffer, fn(%Point{x: x, y: y}, buf) ->
|
||||
pos = (y * width) + x
|
||||
|
||||
Enum.reduce(points, buffer, fn %Point{x: x, y: y}, buf ->
|
||||
pos = y * width + x
|
||||
existing = Enum.at(buf, pos)
|
||||
List.replace_at(buf, pos, RGBA.over(existing, colour))
|
||||
end)
|
||||
|
@ -109,15 +110,17 @@ defmodule Vivid.Buffer do
|
|||
|
||||
defp vertical_reducer({shape, colour}, buffer, bounds, width) do
|
||||
points = Rasterize.rasterize(shape, bounds)
|
||||
Enum.reduce(points, buffer, fn(point, buf) ->
|
||||
|
||||
Enum.reduce(points, buffer, fn point, buf ->
|
||||
point = Point.swap_xy(point)
|
||||
pos = (point.y * width) + point.x
|
||||
pos = point.y * width + point.x
|
||||
existing = Enum.at(buf, pos)
|
||||
List.replace_at(buf, pos, RGBA.over(existing, colour))
|
||||
end)
|
||||
end
|
||||
|
||||
defp allocate(%Frame{width: w, height: h, background_colour: bg}), do: generate_buffer([], w * h, bg)
|
||||
defp allocate(%Frame{width: w, height: h, background_colour: bg}),
|
||||
do: generate_buffer([], w * h, bg)
|
||||
|
||||
defp generate_buffer(buffer, 0, _colour), do: buffer
|
||||
defp generate_buffer(buffer, i, colour), do: generate_buffer([colour | buffer], i - 1, colour)
|
||||
|
|
|
@ -35,7 +35,7 @@ defmodule Vivid.Circle do
|
|||
"@@@@@@@@ @@@@@@@@\n" <>
|
||||
"@@@@@@@@@@@@@@@@@@@@@@@\n"
|
||||
"""
|
||||
@opaque t :: %Circle{center: Point.t, radius: number, fill: boolean}
|
||||
@opaque t :: %Circle{center: Point.t(), radius: number, fill: boolean}
|
||||
|
||||
@doc """
|
||||
Creates a circle from a point in 2D space and a radius.
|
||||
|
@ -45,20 +45,19 @@ defmodule Vivid.Circle do
|
|||
iex> Vivid.Circle.init(Vivid.Point.init(5,5), 4)
|
||||
#Vivid.Circle<[center: #Vivid.Point<{5, 5}>, radius: 4]>
|
||||
"""
|
||||
@spec init(Point.t, number) :: Circle.t
|
||||
@spec init(Point.t(), number) :: Circle.t()
|
||||
def init(%Point{} = point, radius)
|
||||
when is_number(radius) and radius > 0,
|
||||
do: init(point, radius, false)
|
||||
when is_number(radius) and radius > 0,
|
||||
do: init(point, radius, false)
|
||||
|
||||
@doc false
|
||||
@spec init(Point.t, number, boolean) :: Circle.t
|
||||
@spec init(Point.t(), number, boolean) :: Circle.t()
|
||||
def init(%Point{} = point, radius, fill)
|
||||
when is_number(radius) and is_boolean(fill) and radius > 0
|
||||
do
|
||||
when is_number(radius) and is_boolean(fill) and radius > 0 do
|
||||
%Circle{
|
||||
center: point,
|
||||
radius: radius,
|
||||
fill: fill
|
||||
fill: fill
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -71,7 +70,7 @@ defmodule Vivid.Circle do
|
|||
...> |> Vivid.Circle.radius
|
||||
4
|
||||
"""
|
||||
@spec radius(Cricle.t) :: number
|
||||
@spec radius(Cricle.t()) :: number
|
||||
def radius(%Circle{radius: r}), do: r
|
||||
|
||||
@doc """
|
||||
|
@ -82,7 +81,7 @@ defmodule Vivid.Circle do
|
|||
...> |> Vivid.Circle.center
|
||||
%Vivid.Point{x: 5, y: 5}
|
||||
"""
|
||||
@spec center(Circle.t) :: Point.t
|
||||
@spec center(Circle.t()) :: Point.t()
|
||||
def center(%Circle{center: point}), do: point
|
||||
|
||||
@doc """
|
||||
|
@ -94,8 +93,8 @@ defmodule Vivid.Circle do
|
|||
...> |> Vivid.Circle.circumference
|
||||
25.132741228718345
|
||||
"""
|
||||
@spec circumference(Circle.t) :: number
|
||||
def circumference(%Circle{radius: radius}), do: 2 * :math.pi * radius
|
||||
@spec circumference(Circle.t()) :: number
|
||||
def circumference(%Circle{radius: radius}), do: 2 * :math.pi() * radius
|
||||
|
||||
@doc ~S"""
|
||||
Convert the `circle` into a Polygon.
|
||||
|
@ -127,7 +126,7 @@ defmodule Vivid.Circle do
|
|||
"@@@@ @@@@\n" <>
|
||||
"@@@@@@@@@@@@@\n"
|
||||
"""
|
||||
@spec to_polygon(Circle.t) :: Polygon.t
|
||||
@spec to_polygon(Circle.t()) :: Polygon.t()
|
||||
def to_polygon(%Circle{radius: radius} = circle), do: to_polygon(circle, round(radius * 2))
|
||||
|
||||
@doc ~S"""
|
||||
|
@ -156,21 +155,22 @@ defmodule Vivid.Circle do
|
|||
"@ @@@@@@@@@\n" <>
|
||||
"@@@@@@@@@@@\n"
|
||||
"""
|
||||
@spec to_polygon(Circle.t, number) :: Polygon.t
|
||||
@spec to_polygon(Circle.t(), number) :: Polygon.t()
|
||||
def to_polygon(%Circle{center: center, radius: radius, fill: fill}, steps) do
|
||||
h = center |> Point.x
|
||||
k = center |> Point.y
|
||||
h = center |> Point.x()
|
||||
k = center |> Point.y()
|
||||
step_degree = 360 / steps
|
||||
|
||||
points = Enum.map(0..steps - 1, fn(step) ->
|
||||
theta = step_degree * step
|
||||
theta = degrees_to_radians(theta)
|
||||
points =
|
||||
Enum.map(0..(steps - 1), fn step ->
|
||||
theta = step_degree * step
|
||||
theta = degrees_to_radians(theta)
|
||||
|
||||
x = h + radius * cos(theta)
|
||||
y = k - radius * sin(theta)
|
||||
x = h + radius * cos(theta)
|
||||
y = k - radius * sin(theta)
|
||||
|
||||
Point.init(x, y)
|
||||
end)
|
||||
Point.init(x, y)
|
||||
end)
|
||||
|
||||
points
|
||||
|> Polygon.init(fill)
|
||||
|
|
|
@ -44,27 +44,28 @@ defmodule Vivid.Font do
|
|||
"@ @@@@@@@@ @@@@@@@@ @@@@@@@ @@@@@ @@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@ @@@@@ @@@@@@@@@@ @@@@@@@@ @@@@@@@@@ @@@@@@@@ @@ @\n" <>
|
||||
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
|
||||
"""
|
||||
@spec line(String.t, number) :: Shape.t
|
||||
@spec line(String.t(), number) :: Shape.t()
|
||||
def line(str, scale \\ 1.0) do
|
||||
font = rowmans()
|
||||
|
||||
str
|
||||
|> String.split("")
|
||||
|> Stream.reject(fn c -> c == "" end)
|
||||
|> Enum.reduce([], fn
|
||||
letter, [] ->
|
||||
char = Map.get(font, letter)
|
||||
lpad = Char.left_pad(char, scale)
|
||||
[{char, lpad}]
|
||||
letter, [{lchar, lpad} | _] = letters ->
|
||||
char = Map.get(font, letter)
|
||||
lpad =
|
||||
Char.left_pad(char, scale) +
|
||||
Char.right_pad(lchar, scale) +
|
||||
lpad
|
||||
[{char, lpad} | letters]
|
||||
end)
|
||||
|> Enum.map(fn {char, lpad} -> Char.to_shape(char, Point.init(lpad, @font_vertical_offset), scale) end)
|
||||
|> Enum.into(Group.init)
|
||||
|> String.split("")
|
||||
|> Stream.reject(fn c -> c == "" end)
|
||||
|> Enum.reduce([], fn
|
||||
letter, [] ->
|
||||
char = Map.get(font, letter)
|
||||
lpad = Char.left_pad(char, scale)
|
||||
[{char, lpad}]
|
||||
|
||||
letter, [{lchar, lpad} | _] = letters ->
|
||||
char = Map.get(font, letter)
|
||||
lpad = Char.left_pad(char, scale) + Char.right_pad(lchar, scale) + lpad
|
||||
[{char, lpad} | letters]
|
||||
end)
|
||||
|> Enum.map(fn {char, lpad} ->
|
||||
Char.to_shape(char, Point.init(lpad, @font_vertical_offset), scale)
|
||||
end)
|
||||
|> Enum.into(Group.init())
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
@ -74,12 +75,101 @@ defmodule Vivid.Font do
|
|||
@spec rowmans() :: map
|
||||
def rowmans do
|
||||
[
|
||||
" ", "!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "↑", ".",
|
||||
"/", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", ":", ";", "<", "=", ">",
|
||||
"?", "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N",
|
||||
"O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "\\", "]", "↑",
|
||||
"-", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n",
|
||||
"o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~"
|
||||
" ",
|
||||
"!",
|
||||
"\"",
|
||||
"#",
|
||||
"$",
|
||||
"%",
|
||||
"&",
|
||||
"'",
|
||||
"(",
|
||||
")",
|
||||
"*",
|
||||
"+",
|
||||
",",
|
||||
"↑",
|
||||
".",
|
||||
"/",
|
||||
"0",
|
||||
"1",
|
||||
"2",
|
||||
"3",
|
||||
"4",
|
||||
"5",
|
||||
"6",
|
||||
"7",
|
||||
"8",
|
||||
"9",
|
||||
":",
|
||||
";",
|
||||
"<",
|
||||
"=",
|
||||
">",
|
||||
"?",
|
||||
"@",
|
||||
"A",
|
||||
"B",
|
||||
"C",
|
||||
"D",
|
||||
"E",
|
||||
"F",
|
||||
"G",
|
||||
"H",
|
||||
"I",
|
||||
"J",
|
||||
"K",
|
||||
"L",
|
||||
"M",
|
||||
"N",
|
||||
"O",
|
||||
"P",
|
||||
"Q",
|
||||
"R",
|
||||
"S",
|
||||
"T",
|
||||
"U",
|
||||
"V",
|
||||
"W",
|
||||
"X",
|
||||
"Y",
|
||||
"Z",
|
||||
"[",
|
||||
"\\",
|
||||
"]",
|
||||
"↑",
|
||||
"-",
|
||||
"`",
|
||||
"a",
|
||||
"b",
|
||||
"c",
|
||||
"d",
|
||||
"e",
|
||||
"f",
|
||||
"g",
|
||||
"h",
|
||||
"i",
|
||||
"j",
|
||||
"k",
|
||||
"l",
|
||||
"m",
|
||||
"n",
|
||||
"o",
|
||||
"p",
|
||||
"q",
|
||||
"r",
|
||||
"s",
|
||||
"t",
|
||||
"u",
|
||||
"v",
|
||||
"w",
|
||||
"x",
|
||||
"y",
|
||||
"z",
|
||||
"{",
|
||||
"|",
|
||||
"}",
|
||||
"~"
|
||||
]
|
||||
|> Enum.zip(font("rowmans"))
|
||||
|> Enum.into(%{})
|
||||
|
@ -87,7 +177,7 @@ defmodule Vivid.Font do
|
|||
|
||||
defp font(name) do
|
||||
name
|
||||
|> Hershey.definitions
|
||||
|> Enum.to_list
|
||||
|> Hershey.definitions()
|
||||
|> Enum.to_list()
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,31 +14,31 @@ defmodule Vivid.Font.Char do
|
|||
This is not the maximum width of the character, as some go beyond or don't reach their documented bounds.
|
||||
I assume this is for kerning. I may be wrong.
|
||||
"""
|
||||
@spec width(Char.t, number) :: number
|
||||
@spec width(Char.t(), number) :: number
|
||||
def width(%Char{left_pos: l, right_pos: r}, scale \\ 1.0), do: round((abs(l) + abs(r)) * scale)
|
||||
|
||||
@doc """
|
||||
Returns the left padding specified for this character.
|
||||
"""
|
||||
@spec left_pad(Char.t, number) :: number
|
||||
@spec left_pad(Char.t(), number) :: number
|
||||
def left_pad(%Char{left_pos: l}, scale \\ 1.0), do: round(abs(l) * scale)
|
||||
|
||||
@doc """
|
||||
Returns the right padding specified for this character.
|
||||
"""
|
||||
@spec right_pad(Char.t, number) :: number
|
||||
@spec right_pad(Char.t(), number) :: number
|
||||
def right_pad(%Char{right_pos: r}, scale \\ 1.0), do: round(abs(r) * scale)
|
||||
|
||||
@doc """
|
||||
Rendered width of a character.
|
||||
"""
|
||||
@spec rendered_width(Char.t, number) :: number
|
||||
@spec rendered_width(Char.t(), number) :: number
|
||||
def rendered_width(%Char{} = char, scale \\ 1.0), do: rendered_dimension(char, scale, 0)
|
||||
|
||||
@doc """
|
||||
Rendered height of a character.
|
||||
"""
|
||||
@spec rendered_height(Char.t, number) :: number
|
||||
@spec rendered_height(Char.t(), number) :: number
|
||||
def rendered_height(%Char{} = char, scale \\ 1.0), do: rendered_dimension(char, scale, 1)
|
||||
|
||||
@doc """
|
||||
|
@ -48,32 +48,36 @@ defmodule Vivid.Font.Char do
|
|||
* `center` the center `%Point{}` around which to render the character.
|
||||
* `scale` how much to scale the character by.
|
||||
"""
|
||||
@spec to_shape(Char.t, Point.t, number) :: Shape.t
|
||||
@spec to_shape(Char.t(), Point.t(), number) :: Shape.t()
|
||||
def to_shape(%Char{coordinates: coords}, %Point{} = center, scale \\ 1.0) do
|
||||
x_center = center |> Point.x
|
||||
y_center = center |> Point.y
|
||||
x_center = center |> Point.x()
|
||||
y_center = center |> Point.y()
|
||||
|
||||
coords
|
||||
|> Enum.reduce([[]], fn
|
||||
:pen_up, acc -> [[] | acc]
|
||||
:pen_up, acc ->
|
||||
[[] | acc]
|
||||
|
||||
{x, y}, [last | rest] ->
|
||||
x = round(x_center + (x * scale))
|
||||
y = round(y_center + (y * scale))
|
||||
x = round(x_center + x * scale)
|
||||
y = round(y_center + y * scale)
|
||||
[[Point.init(x, y) | last] | rest]
|
||||
end)
|
||||
end)
|
||||
|> Enum.map(&Path.init(&1))
|
||||
|> Group.init
|
||||
|> Group.init()
|
||||
end
|
||||
|
||||
defp rendered_dimension(%Char{coordinates: coords}, scale, i) do
|
||||
coords = coords
|
||||
coords =
|
||||
coords
|
||||
|> Enum.reject(fn c -> c == :pen_up end)
|
||||
|> Enum.map(&elem(&1, i))
|
||||
|
||||
if coords == [] do
|
||||
0
|
||||
else
|
||||
max = coords |> Enum.max
|
||||
min = coords |> Enum.min
|
||||
max = coords |> Enum.max()
|
||||
min = coords |> Enum.min()
|
||||
round((max - min) * scale)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -39,8 +39,7 @@ defmodule Vivid.Frame do
|
|||
"@@@@@@@@@@@@@@@@@@@@@@@@\n"
|
||||
"""
|
||||
|
||||
@opaque t :: %Frame{width: integer, height: integer,
|
||||
background_colour: RGBA.t, shapes: []}
|
||||
@opaque t :: %Frame{width: integer, height: integer, background_colour: RGBA.t(), shapes: []}
|
||||
|
||||
@doc """
|
||||
Initialize a frame buffer.
|
||||
|
@ -54,10 +53,9 @@ defmodule Vivid.Frame do
|
|||
iex> Vivid.Frame.init(4, 4)
|
||||
#Vivid.Frame<[width: 4, height: 4, background_colour: #Vivid.RGBA<{0, 0, 0, 0}>]>
|
||||
"""
|
||||
@spec init(integer(), integer(), Range.t) :: Frame.t
|
||||
@spec init(integer(), integer(), Range.t()) :: Frame.t()
|
||||
def init(width \\ 128, height \\ 64, %RGBA{} = colour \\ RGBA.init(0, 0, 0, 0))
|
||||
when is_integer(width) and is_integer(height) and width > 0 and height > 0
|
||||
do
|
||||
when is_integer(width) and is_integer(height) and width > 0 and height > 0 do
|
||||
%Frame{width: width, height: height, background_colour: colour, shapes: []}
|
||||
end
|
||||
|
||||
|
@ -136,7 +134,7 @@ defmodule Vivid.Frame do
|
|||
" @ \n" <>
|
||||
"@ \n"
|
||||
"""
|
||||
@spec push(Frame.t, Shape.t, RGBA.t) :: Frame.t
|
||||
@spec push(Frame.t(), Shape.t(), RGBA.t()) :: Frame.t()
|
||||
def push(%Frame{shapes: shapes} = frame, shape, colour) do
|
||||
%{frame | shapes: [{shape, colour} | shapes]}
|
||||
end
|
||||
|
@ -144,7 +142,7 @@ defmodule Vivid.Frame do
|
|||
@doc """
|
||||
Clear the `frame` of any shapes.
|
||||
"""
|
||||
@spec clear(Frame.t) :: Frame.t
|
||||
@spec clear(Frame.t()) :: Frame.t()
|
||||
def clear(%Frame{} = frame) do
|
||||
%{frame | shapes: []}
|
||||
end
|
||||
|
@ -157,7 +155,7 @@ defmodule Vivid.Frame do
|
|||
iex> Vivid.Frame.init(80, 25) |> Vivid.Frame.width
|
||||
80
|
||||
"""
|
||||
@spec width(Frame.t) :: integer()
|
||||
@spec width(Frame.t()) :: integer()
|
||||
def width(%Frame{width: w}), do: w
|
||||
|
||||
@doc """
|
||||
|
@ -168,7 +166,7 @@ defmodule Vivid.Frame do
|
|||
iex> Vivid.Frame.init(80, 25) |> Vivid.Frame.height
|
||||
25
|
||||
"""
|
||||
@spec height(Frame.t) :: integer()
|
||||
@spec height(Frame.t()) :: integer()
|
||||
def height(%Frame{height: h}), do: h
|
||||
|
||||
@doc """
|
||||
|
@ -179,7 +177,7 @@ defmodule Vivid.Frame do
|
|||
iex> Vivid.Frame.init(80, 25) |> Vivid.Frame.background_colour
|
||||
#Vivid.RGBA<{0, 0, 0, 0}>
|
||||
"""
|
||||
@spec background_colour(Frame.t) :: RGBA.t
|
||||
@spec background_colour(Frame.t()) :: RGBA.t()
|
||||
def background_colour(%Frame{background_colour: c}), do: c
|
||||
|
||||
@doc """
|
||||
|
@ -192,8 +190,9 @@ defmodule Vivid.Frame do
|
|||
...> |> Vivid.Frame.background_colour
|
||||
#Vivid.RGBA<{1, 1, 1, 1}>
|
||||
"""
|
||||
@spec background_colour(Frame.t, RGBA.t) :: Frame.t
|
||||
def background_colour(%Frame{} = frame, %RGBA{} = colour), do: %{frame | background_colour: colour}
|
||||
@spec background_colour(Frame.t(), RGBA.t()) :: Frame.t()
|
||||
def background_colour(%Frame{} = frame, %RGBA{} = colour),
|
||||
do: %{frame | background_colour: colour}
|
||||
|
||||
@doc """
|
||||
Render a `frame` into a buffer for display horizontally.
|
||||
|
@ -201,7 +200,7 @@ defmodule Vivid.Frame do
|
|||
Returns a one-dimensional List of `RGBA` colours with alpha-compositing
|
||||
completed.
|
||||
"""
|
||||
@spec buffer(Frame.t) :: [RGBA.t]
|
||||
@spec buffer(Frame.t()) :: [RGBA.t()]
|
||||
def buffer(%Frame{} = frame), do: Buffer.horizontal(frame)
|
||||
|
||||
@doc """
|
||||
|
@ -215,7 +214,7 @@ defmodule Vivid.Frame do
|
|||
Returns a one-dimensional List of `RGBA` colours with alpha-compositing
|
||||
completed.
|
||||
"""
|
||||
@spec buffer(Frame.t, :horizontal | :vertical) :: [RGBA.t]
|
||||
@spec buffer(Frame.t(), :horizontal | :vertical) :: [RGBA.t()]
|
||||
def buffer(%Frame{} = frame, :horizontal), do: Buffer.horizontal(frame)
|
||||
def buffer(%Frame{} = frame, :vertical), do: Buffer.vertical(frame)
|
||||
def buffer(%Frame{} = frame, :vertical), do: Buffer.vertical(frame)
|
||||
end
|
||||
|
|
|
@ -39,7 +39,7 @@ defmodule Vivid.Group do
|
|||
"@@@@@@@@@@@@@@@@@@@@@@@\n"
|
||||
"""
|
||||
|
||||
@opaque t :: %Group{shapes: [Shape.t]}
|
||||
@opaque t :: %Group{shapes: [Shape.t()]}
|
||||
|
||||
@doc """
|
||||
Initialize an empty group.
|
||||
|
@ -49,7 +49,7 @@ defmodule Vivid.Group do
|
|||
iex> Vivid.Group.init
|
||||
#Vivid.Group<[]>
|
||||
"""
|
||||
@spec init() :: Group.t
|
||||
@spec init() :: Group.t()
|
||||
def init, do: %Group{shapes: MapSet.new()}
|
||||
|
||||
@doc """
|
||||
|
@ -62,9 +62,9 @@ defmodule Vivid.Group do
|
|||
...> Vivid.Group.init([circle, line])
|
||||
#Vivid.Group<[#Vivid.Line<[origin: #Vivid.Point<{1, 1}>, termination: #Vivid.Point<{10, 10}>]>, #Vivid.Circle<[center: #Vivid.Point<{5, 5}>, radius: 5]>]>
|
||||
"""
|
||||
@spec init([Shape.t]) :: Group.t
|
||||
@spec init([Shape.t()]) :: Group.t()
|
||||
def init(shapes) do
|
||||
%Group{shapes: Enum.into(shapes, MapSet.new)}
|
||||
%Group{shapes: Enum.into(shapes, MapSet.new())}
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
@ -77,7 +77,7 @@ defmodule Vivid.Group do
|
|||
...> |> Vivid.Group.delete(line)
|
||||
%Vivid.Group{shapes: MapSet.new()}
|
||||
"""
|
||||
@spec delete(Group.t, Shape.t) :: Group.t
|
||||
@spec delete(Group.t(), Shape.t()) :: Group.t()
|
||||
def delete(%Group{shapes: shapes}, shape), do: shapes |> MapSet.delete(shape) |> init
|
||||
|
||||
@doc """
|
||||
|
@ -92,6 +92,6 @@ defmodule Vivid.Group do
|
|||
%Vivid.Line{origin: %Vivid.Point{x: 1, y: 1}, termination: %Vivid.Point{x: 10, y: 10}}
|
||||
])}
|
||||
"""
|
||||
@spec put(Group.t, Shape.t) :: Group.t
|
||||
@spec put(Group.t(), Shape.t()) :: Group.t()
|
||||
def put(%Group{shapes: shapes}, shape), do: shapes |> MapSet.put(shape) |> init
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
defmodule Vivid.Hershey do
|
||||
require Logger
|
||||
alias Vivid.Font.Char
|
||||
@mid_point 'R' |> List.first
|
||||
@mid_point 'R' |> List.first()
|
||||
|
||||
@moduledoc """
|
||||
Supports reading the Hershey Vector Font format and converting them into paths.
|
||||
|
@ -11,18 +11,20 @@ defmodule Vivid.Hershey do
|
|||
Returns a map of "character IDs" to %Char{} structs, which can
|
||||
be passed to `char_to_shape` to turn into renderable shapes.
|
||||
"""
|
||||
@spec definitions(String.t) :: Enumerable.t
|
||||
@spec definitions(String.t()) :: Enumerable.t()
|
||||
def definitions(file) do
|
||||
file
|
||||
|> get_path
|
||||
|> File.stream!
|
||||
|> File.stream!()
|
||||
|> Stream.transform(nil, &fix_wrapped_lines(&1, &2))
|
||||
|> Stream.map(&parse_line(&1))
|
||||
end
|
||||
|
||||
defp fix_wrapped_lines(next, nil), do: {[], String.replace(next, ~r/[\r\n]+/, "")}
|
||||
|
||||
defp fix_wrapped_lines(next, last) do
|
||||
next = next |> String.replace(~r/[\n\r]+/, "")
|
||||
|
||||
if Regex.match?(~r/^\ *[0-9]+/, next) do
|
||||
{[last], next}
|
||||
else
|
||||
|
@ -31,26 +33,30 @@ defmodule Vivid.Hershey do
|
|||
end
|
||||
end
|
||||
|
||||
defp parse_line(<< char::binary-size(5), vertices::binary-size(3), l_pos::binary-size(1), r_pos::binary-size(1), coords::binary >>) do
|
||||
char = char |> String.trim_leading |> String.to_integer
|
||||
vertices = vertices |> String.trim_leading |> String.to_integer
|
||||
l_pos = l_pos |> String.to_charlist |> List.first
|
||||
r_pos = r_pos |> String.to_charlist |> List.first
|
||||
coords = parse_coords([], coords)
|
||||
defp parse_line(
|
||||
<<char::binary-size(5), vertices::binary-size(3), l_pos::binary-size(1),
|
||||
r_pos::binary-size(1), coords::binary>>
|
||||
) do
|
||||
char = char |> String.trim_leading() |> String.to_integer()
|
||||
vertices = vertices |> String.trim_leading() |> String.to_integer()
|
||||
l_pos = l_pos |> String.to_charlist() |> List.first()
|
||||
r_pos = r_pos |> String.to_charlist() |> List.first()
|
||||
coords = parse_coords([], coords)
|
||||
|
||||
%Char{
|
||||
character: char,
|
||||
vertices: vertices,
|
||||
left_pos: l_pos - @mid_point,
|
||||
right_pos: r_pos - @mid_point,
|
||||
character: char,
|
||||
vertices: vertices,
|
||||
left_pos: l_pos - @mid_point,
|
||||
right_pos: r_pos - @mid_point,
|
||||
coordinates: coords
|
||||
}
|
||||
end
|
||||
|
||||
defp parse_coords(parsed, ""), do: parsed |> Enum.reverse
|
||||
defp parse_coords(parsed, ""), do: parsed |> Enum.reverse()
|
||||
defp parse_coords(parsed, " R" <> rest), do: parse_coords([:pen_up | parsed], rest)
|
||||
defp parse_coords(parsed, << xy::binary-size(2), rest::binary >>) do
|
||||
[y, x] = xy |> String.to_charlist
|
||||
|
||||
defp parse_coords(parsed, <<xy::binary-size(2), rest::binary>>) do
|
||||
[y, x] = xy |> String.to_charlist()
|
||||
normalized_x = @mid_point - x
|
||||
normalized_y = y - @mid_point
|
||||
parse_coords([{normalized_y, normalized_x} | parsed], rest)
|
||||
|
@ -64,7 +70,7 @@ defmodule Vivid.Hershey do
|
|||
|
||||
defp priv_dir do
|
||||
:vivid
|
||||
|> :code.priv_dir
|
||||
|> List.to_string
|
||||
|> :code.priv_dir()
|
||||
|> List.to_string()
|
||||
end
|
||||
end
|
||||
|
|
|
@ -21,7 +21,7 @@ defmodule Vivid.Line do
|
|||
"@@@@@@@@\n"
|
||||
"""
|
||||
|
||||
@opaque t :: %Line{origin: Point.t, termination: Point.t}
|
||||
@opaque t :: %Line{origin: Point.t(), termination: Point.t()}
|
||||
|
||||
@doc ~S"""
|
||||
Create a Line given an `origin` and `termination` point.
|
||||
|
@ -32,7 +32,7 @@ defmodule Vivid.Line do
|
|||
%Vivid.Line{origin: %Vivid.Point{x: 1, y: 1}, termination: %Vivid.Point{x: 4, y: 4}}
|
||||
|
||||
"""
|
||||
@spec init(Point.t, Point.t) :: Line.t
|
||||
@spec init(Point.t(), Point.t()) :: Line.t()
|
||||
def init(%Point{} = origin, %Point{} = termination) do
|
||||
%Line{origin: origin, termination: termination}
|
||||
end
|
||||
|
@ -40,7 +40,7 @@ defmodule Vivid.Line do
|
|||
@doc """
|
||||
Create a `Line` from a two-element list of points.
|
||||
"""
|
||||
@spec init([Point.t]) :: Line.t
|
||||
@spec init([Point.t()]) :: Line.t()
|
||||
def init([o, t]) do
|
||||
init(o, t)
|
||||
end
|
||||
|
@ -53,7 +53,7 @@ defmodule Vivid.Line do
|
|||
iex> Vivid.Line.init(Vivid.Point.init(1,1), Vivid.Point.init(4,4)) |> Vivid.Line.origin
|
||||
%Vivid.Point{x: 1, y: 1}
|
||||
"""
|
||||
@spec origin(Line.t) :: Point.t
|
||||
@spec origin(Line.t()) :: Point.t()
|
||||
def origin(%Line{origin: o}), do: o
|
||||
|
||||
@doc ~S"""
|
||||
|
@ -66,7 +66,7 @@ defmodule Vivid.Line do
|
|||
...> |> Line.termination
|
||||
#Vivid.Point<{4, 4}>
|
||||
"""
|
||||
@spec termination(Line.t) :: Point.t
|
||||
@spec termination(Line.t()) :: Point.t()
|
||||
def termination(%Line{termination: t}), do: t
|
||||
|
||||
@doc ~S"""
|
||||
|
@ -77,7 +77,7 @@ defmodule Vivid.Line do
|
|||
iex> Vivid.Line.init(Vivid.Point.init(1,1), Vivid.Point.init(14,4)) |> Vivid.Line.width
|
||||
13
|
||||
"""
|
||||
@spec width(Line.t) :: number
|
||||
@spec width(Line.t()) :: number
|
||||
def width(%Line{} = line), do: abs(x_distance(line))
|
||||
|
||||
@doc ~S"""
|
||||
|
@ -88,7 +88,7 @@ defmodule Vivid.Line do
|
|||
iex> Vivid.Line.init(Vivid.Point.init(14,1), Vivid.Point.init(1,4)) |> Vivid.Line.x_distance
|
||||
-13
|
||||
"""
|
||||
@spec x_distance(Line.t) :: number
|
||||
@spec x_distance(Line.t()) :: number
|
||||
def x_distance(%Line{origin: %Point{x: x0}, termination: %Point{x: x1}}), do: x1 - x0
|
||||
|
||||
@doc ~S"""
|
||||
|
@ -99,7 +99,7 @@ defmodule Vivid.Line do
|
|||
iex> Vivid.Line.init(Vivid.Point.init(1,1), Vivid.Point.init(4,14)) |> Vivid.Line.height
|
||||
13
|
||||
"""
|
||||
@spec height(Line.t) :: number
|
||||
@spec height(Line.t()) :: number
|
||||
def height(%Line{} = line), do: abs(y_distance(line))
|
||||
|
||||
@doc ~S"""
|
||||
|
@ -110,7 +110,7 @@ defmodule Vivid.Line do
|
|||
iex> Vivid.Line.init(Vivid.Point.init(1,14), Vivid.Point.init(4,1)) |> Vivid.Line.y_distance
|
||||
-13
|
||||
"""
|
||||
@spec y_distance(Line.t) :: number
|
||||
@spec y_distance(Line.t()) :: number
|
||||
def y_distance(%Line{origin: %Point{y: y0}, termination: %Point{y: y1}}), do: y1 - y0
|
||||
|
||||
@doc ~S"""
|
||||
|
@ -122,7 +122,7 @@ defmodule Vivid.Line do
|
|||
iex> Vivid.Line.init(Vivid.Point.init(1,1), Vivid.Point.init(4,5)) |> Vivid.Line.length
|
||||
5.0
|
||||
"""
|
||||
@spec length(Line.t) :: number
|
||||
@spec length(Line.t()) :: number
|
||||
def length(%Line{} = line) do
|
||||
dx2 = line |> width |> pow(2)
|
||||
dy2 = line |> height |> pow(2)
|
||||
|
@ -144,13 +144,13 @@ defmodule Vivid.Line do
|
|||
...> |> Line.on?(Point.init(2,2))
|
||||
false
|
||||
"""
|
||||
@spec on?(Line.t, Point.t) :: boolean
|
||||
@spec on?(Line.t(), Point.t()) :: boolean
|
||||
def on?(%Line{origin: origin, termination: termination}, %Point{} = point) do
|
||||
x_distance_point = point.x - termination.x
|
||||
y_distance_point = point.y - termination.y
|
||||
x_distance_point = point.x - termination.x
|
||||
y_distance_point = point.y - termination.y
|
||||
x_distance_origin = origin.x - termination.x
|
||||
y_distance_origin = origin.y - termination.y
|
||||
cross_product = x_distance_point * y_distance_origin - x_distance_origin * y_distance_point
|
||||
cross_product = x_distance_point * y_distance_origin - x_distance_origin * y_distance_point
|
||||
|
||||
cross_product == 0.0
|
||||
end
|
||||
|
@ -165,18 +165,26 @@ defmodule Vivid.Line do
|
|||
...> |> Line.x_intersect(10)
|
||||
#Vivid.Point<{10, 5.25}>
|
||||
"""
|
||||
@spec x_intersect(Line.t, integer) :: Point.t | nil
|
||||
def x_intersect(%Line{origin: %Point{x: x0} = p, termination: %Point{x: x1}}, x) when x == x0 and x == x1, do: p
|
||||
def x_intersect(%Line{origin: %Point{x: x0} = p0, termination: %Point{x: x1} = p1}, x) when x0 > x1 do
|
||||
@spec x_intersect(Line.t(), integer) :: Point.t() | nil
|
||||
def x_intersect(%Line{origin: %Point{x: x0} = p, termination: %Point{x: x1}}, x)
|
||||
when x == x0 and x == x1,
|
||||
do: p
|
||||
|
||||
def x_intersect(%Line{origin: %Point{x: x0} = p0, termination: %Point{x: x1} = p1}, x)
|
||||
when x0 > x1 do
|
||||
x_intersect(%Line{origin: p1, termination: p0}, x)
|
||||
end
|
||||
|
||||
def x_intersect(%Line{origin: %Point{x: x0} = p}, x) when x0 == x, do: p
|
||||
def x_intersect(%Line{termination: %Point{x: x0} = p}, x) when x0 == x, do: p
|
||||
def x_intersect(%Line{origin: %Point{x: x0, y: y0}, termination: %Point{x: x1, y: y1}}, x) when x0 < x and x < x1 do
|
||||
|
||||
def x_intersect(%Line{origin: %Point{x: x0, y: y0}, termination: %Point{x: x1, y: y1}}, x)
|
||||
when x0 < x and x < x1 do
|
||||
rx = (x - x0) / (x1 - x0)
|
||||
y = rx * (y1 - y0) + y0
|
||||
y = rx * (y1 - y0) + y0
|
||||
Point.init(x, y)
|
||||
end
|
||||
|
||||
def x_intersect(_line, _x), do: nil
|
||||
|
||||
@doc """
|
||||
|
@ -189,18 +197,26 @@ defmodule Vivid.Line do
|
|||
...> |> Line.y_intersect(10)
|
||||
#Vivid.Point<{17.307692307692307, 10}>
|
||||
"""
|
||||
@spec y_intersect(Line.t, integer) :: Point.t | nil
|
||||
def y_intersect(%Line{origin: %Point{y: y0} = p, termination: %Point{y: y1}}, y) when y == y0 and y == y1, do: p
|
||||
def y_intersect(%Line{origin: %Point{y: y0} = p0, termination: %Point{y: y1} = p1}, y) when y0 > y1 do
|
||||
@spec y_intersect(Line.t(), integer) :: Point.t() | nil
|
||||
def y_intersect(%Line{origin: %Point{y: y0} = p, termination: %Point{y: y1}}, y)
|
||||
when y == y0 and y == y1,
|
||||
do: p
|
||||
|
||||
def y_intersect(%Line{origin: %Point{y: y0} = p0, termination: %Point{y: y1} = p1}, y)
|
||||
when y0 > y1 do
|
||||
y_intersect(%Line{origin: p1, termination: p0}, y)
|
||||
end
|
||||
|
||||
def y_intersect(%Line{origin: %Point{y: y0} = p}, y) when y0 == y, do: p
|
||||
def y_intersect(%Line{termination: %Point{y: y0} = p}, y) when y0 == y, do: p
|
||||
def y_intersect(%Line{origin: %Point{x: x0, y: y0}, termination: %Point{x: x1, y: y1}}, y) when y0 < y and y < y1 do
|
||||
|
||||
def y_intersect(%Line{origin: %Point{x: x0, y: y0}, termination: %Point{x: x1, y: y1}}, y)
|
||||
when y0 < y and y < y1 do
|
||||
ry = (y - y0) / (y1 - y0)
|
||||
x = ry * (x1 - x0) + x0
|
||||
x = ry * (x1 - x0) + x0
|
||||
Point.init(x, y)
|
||||
end
|
||||
|
||||
def y_intersect(_line, _y), do: nil
|
||||
|
||||
@doc """
|
||||
|
@ -218,8 +234,10 @@ defmodule Vivid.Line do
|
|||
...> |> Line.horizontal?
|
||||
false
|
||||
"""
|
||||
@spec horizontal?(Line.t) :: boolean
|
||||
def horizontal?(%Line{origin: %Point{y: y0}, termination: %Point{y: y1}}) when y0 == y1, do: true
|
||||
@spec horizontal?(Line.t()) :: boolean
|
||||
def horizontal?(%Line{origin: %Point{y: y0}, termination: %Point{y: y1}}) when y0 == y1,
|
||||
do: true
|
||||
|
||||
def horizontal?(_line), do: false
|
||||
|
||||
@doc """
|
||||
|
@ -237,7 +255,7 @@ defmodule Vivid.Line do
|
|||
...> |> Line.vertical?
|
||||
false
|
||||
"""
|
||||
@spec vertical?(Line.t) :: boolean
|
||||
@spec vertical?(Line.t()) :: boolean
|
||||
def vertical?(%Line{origin: %Point{x: x0}, termination: %Point{x: x1}}) when x0 == x1, do: true
|
||||
def vertical?(_line), do: false
|
||||
end
|
||||
|
|
|
@ -30,7 +30,7 @@ defmodule Vivid.Path do
|
|||
"@@@@@@@@@@@@\n"
|
||||
"""
|
||||
|
||||
@opaque t :: %Path{vertices: [Shape.t]}
|
||||
@opaque t :: %Path{vertices: [Shape.t()]}
|
||||
|
||||
@doc """
|
||||
Initialize an empty path.
|
||||
|
@ -40,7 +40,7 @@ defmodule Vivid.Path do
|
|||
iex> Vivid.Path.init
|
||||
%Vivid.Path{vertices: []}
|
||||
"""
|
||||
@spec init() :: Path.t
|
||||
@spec init() :: Path.t()
|
||||
def init, do: %Path{vertices: []}
|
||||
|
||||
@doc """
|
||||
|
@ -56,7 +56,7 @@ defmodule Vivid.Path do
|
|||
%Vivid.Point{x: 2, y: 1}
|
||||
]}
|
||||
"""
|
||||
@spec init([Point.t]) :: Path.t
|
||||
@spec init([Point.t()]) :: Path.t()
|
||||
def init(points) when is_list(points), do: %Path{vertices: points}
|
||||
|
||||
@doc """
|
||||
|
@ -72,7 +72,7 @@ defmodule Vivid.Path do
|
|||
%Vivid.Line{origin: %Vivid.Point{x: 2, y: 2},
|
||||
termination: %Vivid.Point{x: 2, y: 1}}]
|
||||
"""
|
||||
@spec to_lines(Path.t) :: [Line.t]
|
||||
@spec to_lines(Path.t()) :: [Line.t()]
|
||||
def to_lines(%Path{vertices: points}) do
|
||||
points_to_lines([], points)
|
||||
end
|
||||
|
@ -85,7 +85,7 @@ defmodule Vivid.Path do
|
|||
iex> Vivid.Path.init([Vivid.Point.init(1,1), Vivid.Point.init(2,2)]) |> Vivid.Path.delete(Vivid.Point.init(2,2))
|
||||
%Vivid.Path{vertices: [%Vivid.Point{x: 1, y: 1}]}
|
||||
"""
|
||||
@spec delete(Path.t, Point.t) :: Path.t
|
||||
@spec delete(Path.t(), Point.t()) :: Path.t()
|
||||
def delete(%Path{vertices: points}, %Point{} = point) do
|
||||
points
|
||||
|> List.delete(point)
|
||||
|
@ -100,7 +100,7 @@ defmodule Vivid.Path do
|
|||
iex> Vivid.Path.init([Vivid.Point.init(1,1), Vivid.Point.init(2,2)]) |> Vivid.Path.delete_at(1)
|
||||
%Vivid.Path{vertices: [%Vivid.Point{x: 1, y: 1}]}
|
||||
"""
|
||||
@spec delete_at(Path.t, integer) :: Path.t
|
||||
@spec delete_at(Path.t(), integer) :: Path.t()
|
||||
def delete_at(%Path{vertices: points}, index) do
|
||||
points
|
||||
|> List.delete_at(index)
|
||||
|
@ -115,10 +115,10 @@ defmodule Vivid.Path do
|
|||
iex> Vivid.Path.init([Vivid.Point.init(1,1), Vivid.Point.init(2,2)]) |> Vivid.Path.first
|
||||
%Vivid.Point{x: 1, y: 1}
|
||||
"""
|
||||
@spec first(Path.t) :: Point.t
|
||||
@spec first(Path.t()) :: Point.t()
|
||||
def first(%Path{vertices: points}) do
|
||||
points
|
||||
|> List.first
|
||||
|> List.first()
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
@ -133,7 +133,7 @@ defmodule Vivid.Path do
|
|||
%Vivid.Point{x: 2, y: 2}
|
||||
]}
|
||||
"""
|
||||
@spec insert_at(Path.t, integer, Point.t) :: Path.t
|
||||
@spec insert_at(Path.t(), integer, Point.t()) :: Path.t()
|
||||
def insert_at(%Path{vertices: points}, index, %Point{} = point) do
|
||||
points
|
||||
|> List.insert_at(index, point)
|
||||
|
@ -148,10 +148,10 @@ defmodule Vivid.Path do
|
|||
iex> Vivid.Path.init([Vivid.Point.init(1,1), Vivid.Point.init(2,2)]) |> Vivid.Path.last
|
||||
%Vivid.Point{x: 2, y: 2}
|
||||
"""
|
||||
@spec last(Path.t) :: Point.t
|
||||
@spec last(Path.t()) :: Point.t()
|
||||
def last(%Path{vertices: points}) do
|
||||
points
|
||||
|> List.last
|
||||
|> List.last()
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
@ -166,7 +166,7 @@ defmodule Vivid.Path do
|
|||
%Vivid.Point{x: 3, y: 3}
|
||||
]}
|
||||
"""
|
||||
@spec replace_at(Path.t, integer, Point.t) :: Path.t
|
||||
@spec replace_at(Path.t(), integer, Point.t()) :: Path.t()
|
||||
def replace_at(%Path{vertices: points}, index, %Point{} = point) do
|
||||
points
|
||||
|> List.replace_at(index, point)
|
||||
|
@ -181,9 +181,9 @@ defmodule Vivid.Path do
|
|||
end
|
||||
|
||||
defp points_to_lines(lines, [point | rest]) do
|
||||
origin = lines |> List.last |> Line.termination
|
||||
term = point
|
||||
lines = lines ++ [Line.init(origin, term)]
|
||||
origin = lines |> List.last() |> Line.termination()
|
||||
term = point
|
||||
lines = lines ++ [Line.init(origin, term)]
|
||||
points_to_lines(lines, rest)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -29,10 +29,9 @@ defmodule Vivid.Point do
|
|||
iex> Vivid.Point.init(13, 27)
|
||||
%Vivid.Point{x: 13, y: 27}
|
||||
"""
|
||||
@spec init(number, number) :: Point.t
|
||||
@spec init(number, number) :: Point.t()
|
||||
def init(x, y)
|
||||
when is_number(x) and is_number(y)
|
||||
do
|
||||
when is_number(x) and is_number(y) do
|
||||
%Point{x: x, y: y}
|
||||
end
|
||||
|
||||
|
@ -44,7 +43,7 @@ defmodule Vivid.Point do
|
|||
iex> Vivid.Point.init(13, 27) |> Vivid.Point.x
|
||||
13
|
||||
"""
|
||||
@spec x(Point.t) :: number
|
||||
@spec x(Point.t()) :: number
|
||||
def x(%Point{x: x}), do: x
|
||||
|
||||
@doc ~S"""
|
||||
|
@ -55,7 +54,7 @@ defmodule Vivid.Point do
|
|||
iex> Vivid.Point.init(13, 27) |> Vivid.Point.y
|
||||
27
|
||||
"""
|
||||
@spec y(Point.t) :: number
|
||||
@spec y(Point.t()) :: number
|
||||
def y(%Point{y: y}), do: y
|
||||
|
||||
@doc """
|
||||
|
@ -68,7 +67,7 @@ defmodule Vivid.Point do
|
|||
...> |> Vivid.Point.swap_xy
|
||||
#Vivid.Point<{27, 13}>
|
||||
"""
|
||||
@spec swap_xy(Point.t) :: Point.t
|
||||
@spec swap_xy(Point.t()) :: Point.t()
|
||||
def swap_xy(%Point{x: x, y: y}), do: Point.init(y, x)
|
||||
|
||||
@doc """
|
||||
|
@ -82,7 +81,7 @@ defmodule Vivid.Point do
|
|||
...> Point.vector(a, b)
|
||||
{10, 10}
|
||||
"""
|
||||
@spec vector(Point.t, Point.t) :: {number, number}
|
||||
@spec vector(Point.t(), Point.t()) :: {number, number}
|
||||
def vector(%Point{x: x0, y: y0} = _a, %Point{x: x1, y: y1} = _b) do
|
||||
{x1 - x0, y1 - y0}
|
||||
end
|
||||
|
@ -96,6 +95,6 @@ defmodule Vivid.Point do
|
|||
...> |> Vivid.Point.round
|
||||
#Vivid.Point<{1, 5}>
|
||||
"""
|
||||
@spec round(Point.t) :: Point.t
|
||||
@spec round(Point.t()) :: Point.t()
|
||||
def round(%Point{x: x, y: y}), do: Point.init(Kernel.round(x), Kernel.round(y))
|
||||
end
|
||||
|
|
|
@ -31,7 +31,7 @@ defmodule Vivid.Polygon do
|
|||
"@@@@@@@@@@@@\n"
|
||||
"""
|
||||
|
||||
@opaque t :: %Polygon{vertices: [Point.t], fill: boolean}
|
||||
@opaque t :: %Polygon{vertices: [Point.t()], fill: boolean}
|
||||
|
||||
@doc """
|
||||
Initialize an empty Polygon.
|
||||
|
@ -41,7 +41,7 @@ defmodule Vivid.Polygon do
|
|||
iex> Vivid.Polygon.init
|
||||
%Vivid.Polygon{vertices: []}
|
||||
"""
|
||||
@spec init() :: Polygon.t
|
||||
@spec init() :: Polygon.t()
|
||||
def init, do: %Polygon{vertices: [], fill: false}
|
||||
|
||||
@doc """
|
||||
|
@ -57,12 +57,13 @@ defmodule Vivid.Polygon do
|
|||
%Vivid.Point{x: 2, y: 1}
|
||||
]}
|
||||
"""
|
||||
@spec init([Point.t]) :: Polygon.t
|
||||
@spec init([Point.t()]) :: Polygon.t()
|
||||
def init(points) when is_list(points), do: %Polygon{vertices: points, fill: false}
|
||||
|
||||
@doc false
|
||||
@spec init([Point.t], boolean) :: Polygon.t
|
||||
def init(points, fill) when is_list(points) and is_boolean(fill), do: %Polygon{vertices: points, fill: fill}
|
||||
@spec init([Point.t()], boolean) :: Polygon.t()
|
||||
def init(points, fill) when is_list(points) and is_boolean(fill),
|
||||
do: %Polygon{vertices: points, fill: fill}
|
||||
|
||||
@doc """
|
||||
Convert a Polygon into a list of lines joined by the vertices.
|
||||
|
@ -79,7 +80,7 @@ defmodule Vivid.Polygon do
|
|||
%Vivid.Line{origin: %Vivid.Point{x: 2, y: 1},
|
||||
termination: %Vivid.Point{x: 1, y: 1}}]
|
||||
"""
|
||||
@spec to_lines(Polygon.t) :: [Line.t]
|
||||
@spec to_lines(Polygon.t()) :: [Line.t()]
|
||||
def to_lines(%Polygon{vertices: points}) do
|
||||
points_to_lines([], points)
|
||||
end
|
||||
|
@ -92,7 +93,7 @@ defmodule Vivid.Polygon do
|
|||
iex> Vivid.Polygon.init([Vivid.Point.init(1,1), Vivid.Point.init(2,2)]) |> Vivid.Polygon.delete(Vivid.Point.init(2,2))
|
||||
%Vivid.Polygon{vertices: [%Vivid.Point{x: 1, y: 1}]}
|
||||
"""
|
||||
@spec delete(Polygon.t, Point.t) :: Polygon.t
|
||||
@spec delete(Polygon.t(), Point.t()) :: Polygon.t()
|
||||
def delete(%Polygon{vertices: points}, %Point{} = point) do
|
||||
points
|
||||
|> List.delete(point)
|
||||
|
@ -107,7 +108,7 @@ defmodule Vivid.Polygon do
|
|||
iex> Vivid.Polygon.init([Vivid.Point.init(1,1), Vivid.Point.init(2,2)]) |> Vivid.Polygon.delete_at(1)
|
||||
%Vivid.Polygon{vertices: [%Vivid.Point{x: 1, y: 1}]}
|
||||
"""
|
||||
@spec delete_at(Polygon.t, integer) :: Polygon.t
|
||||
@spec delete_at(Polygon.t(), integer) :: Polygon.t()
|
||||
def delete_at(%Polygon{vertices: points}, index) do
|
||||
points
|
||||
|> List.delete_at(index)
|
||||
|
@ -122,10 +123,10 @@ defmodule Vivid.Polygon do
|
|||
iex> Vivid.Polygon.init([Vivid.Point.init(1,1), Vivid.Point.init(2,2)]) |> Vivid.Polygon.first
|
||||
%Vivid.Point{x: 1, y: 1}
|
||||
"""
|
||||
@spec first(Polygon.t) :: Point.t
|
||||
@spec first(Polygon.t()) :: Point.t()
|
||||
def first(%Polygon{vertices: points}) do
|
||||
points
|
||||
|> List.first
|
||||
|> List.first()
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
@ -140,7 +141,7 @@ defmodule Vivid.Polygon do
|
|||
%Vivid.Point{x: 2, y: 2}
|
||||
]}
|
||||
"""
|
||||
@spec insert_at(Polygon.t, integer, Point.t) :: Polygon.t
|
||||
@spec insert_at(Polygon.t(), integer, Point.t()) :: Polygon.t()
|
||||
def insert_at(%Polygon{vertices: points}, index, %Point{} = point) do
|
||||
points
|
||||
|> List.insert_at(index, point)
|
||||
|
@ -155,10 +156,10 @@ defmodule Vivid.Polygon do
|
|||
iex> Vivid.Polygon.init([Vivid.Point.init(1,1), Vivid.Point.init(2,2)]) |> Vivid.Polygon.last
|
||||
%Vivid.Point{x: 2, y: 2}
|
||||
"""
|
||||
@spec last(Polygon.t) :: Point.t
|
||||
@spec last(Polygon.t()) :: Point.t()
|
||||
def last(%Polygon{vertices: points}) do
|
||||
points
|
||||
|> List.last
|
||||
|> List.last()
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
@ -173,7 +174,7 @@ defmodule Vivid.Polygon do
|
|||
%Vivid.Point{x: 3, y: 3}
|
||||
]}
|
||||
"""
|
||||
@spec replace_at(Polygon.t, integer, Point.t) :: Polygon.t
|
||||
@spec replace_at(Polygon.t(), integer, Point.t()) :: Polygon.t()
|
||||
def replace_at(%Polygon{vertices: points}, index, %Point{} = point) do
|
||||
points
|
||||
|> List.replace_at(index, point)
|
||||
|
@ -200,7 +201,7 @@ defmodule Vivid.Polygon do
|
|||
...> |> Polygon.filled?
|
||||
false
|
||||
"""
|
||||
@spec filled?(Polygon.t) :: boolean
|
||||
@spec filled?(Polygon.t()) :: boolean
|
||||
def filled?(%Polygon{fill: fill}), do: fill
|
||||
|
||||
@doc """
|
||||
|
@ -214,12 +215,12 @@ defmodule Vivid.Polygon do
|
|||
...> |> Polygon.filled?
|
||||
true
|
||||
"""
|
||||
@spec fill(Polygon.t, boolean) :: Polygon.t
|
||||
@spec fill(Polygon.t(), boolean) :: Polygon.t()
|
||||
def fill(%Polygon{} = polygon, fill) when is_boolean(fill), do: %{polygon | fill: fill}
|
||||
|
||||
defp points_to_lines(lines, []) do
|
||||
origin = lines |> List.last |> Line.termination
|
||||
term = lines |> List.first |> Line.origin
|
||||
origin = lines |> List.last() |> Line.termination()
|
||||
term = lines |> List.first() |> Line.origin()
|
||||
lines ++ [Line.init(origin, term)]
|
||||
end
|
||||
|
||||
|
@ -229,9 +230,9 @@ defmodule Vivid.Polygon do
|
|||
end
|
||||
|
||||
defp points_to_lines(lines, [point | rest]) do
|
||||
origin = lines |> List.last |> Line.termination
|
||||
term = point
|
||||
lines = lines ++ [Line.init(origin, term)]
|
||||
origin = lines |> List.last() |> Line.termination()
|
||||
term = point
|
||||
lines = lines ++ [Line.init(origin, term)]
|
||||
points_to_lines(lines, rest)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
defprotocol Vivid.Rasterize do
|
||||
alias Vivid.Shape
|
||||
|
||||
@moduledoc ~S"""
|
||||
The Rasterize protocol is responsible for converting shapes into bitmaps.
|
||||
|
||||
|
@ -18,6 +19,6 @@ defprotocol Vivid.Rasterize do
|
|||
|
||||
Takes a `shape` and returns a `MapSet` of points within `bounds`.
|
||||
"""
|
||||
@spec rasterize(Shape.t, Bounds.t) :: MapSet
|
||||
@spec rasterize(Shape.t(), Bounds.t()) :: MapSet
|
||||
def rasterize(shape, bounds)
|
||||
end
|
||||
|
|
|
@ -15,10 +15,10 @@ defimpl Vivid.Rasterize, for: Vivid.Arc do
|
|||
#MapSet<[#Vivid.Point<{0, 5}>, #Vivid.Point<{1, 3}>, #Vivid.Point<{1, 4}>, #Vivid.Point<{2, 2}>, #Vivid.Point<{3, 1}>, #Vivid.Point<{4, 1}>, #Vivid.Point<{5, 0}>]>
|
||||
|
||||
"""
|
||||
@spec rasterize(Arc.t, Bounds.t) :: MapSet.t
|
||||
@spec rasterize(Arc.t(), Bounds.t()) :: MapSet.t()
|
||||
def rasterize(arc, bounds) do
|
||||
arc
|
||||
|> Arc.to_path
|
||||
|> Arc.to_path()
|
||||
|> Rasterize.rasterize(bounds)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,10 +15,10 @@ defimpl Vivid.Rasterize, for: Vivid.Box do
|
|||
...> Rasterize.rasterize(box, Bounds.bounds(box))
|
||||
#MapSet<[#Vivid.Point<{2, 2}>, #Vivid.Point<{2, 3}>, #Vivid.Point<{2, 4}>, #Vivid.Point<{3, 2}>, #Vivid.Point<{3, 4}>, #Vivid.Point<{4, 2}>, #Vivid.Point<{4, 3}>, #Vivid.Point<{4, 4}>]>
|
||||
"""
|
||||
@spec rasterize(Box.t, Bounds.t) :: MapSet.t
|
||||
@spec rasterize(Box.t(), Bounds.t()) :: MapSet.t()
|
||||
def rasterize(box, bounds) do
|
||||
box
|
||||
|> Box.to_polygon
|
||||
|> Box.to_polygon()
|
||||
|> Rasterize.rasterize(bounds)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -27,10 +27,10 @@ defimpl Vivid.Rasterize, for: Vivid.Circle do
|
|||
%Vivid.Point{x: 9, y: 5}, %Vivid.Point{x: 9, y: 6}
|
||||
])
|
||||
"""
|
||||
@spec rasterize(Circle.t, Bounds.t) :: MapSet.t
|
||||
@spec rasterize(Circle.t(), Bounds.t()) :: MapSet.t()
|
||||
def rasterize(circle, bounds) do
|
||||
circle
|
||||
|> Circle.to_polygon
|
||||
|> Circle.to_polygon()
|
||||
|> Rasterize.rasterize(bounds)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,9 +14,9 @@ defimpl Vivid.Rasterize, for: Vivid.Group do
|
|||
...> Vivid.Group.init([path]) |> Vivid.Rasterize.rasterize(Vivid.Bounds.init(0, 0, 3, 3))
|
||||
#MapSet<[#Vivid.Point<{1, 1}>, #Vivid.Point<{1, 2}>, #Vivid.Point<{1, 3}>, #Vivid.Point<{2, 3}>, #Vivid.Point<{3, 1}>, #Vivid.Point<{3, 2}>, #Vivid.Point<{3, 3}>]>
|
||||
"""
|
||||
@spec rasterize(Group.t, Bounds.t) :: MapSet.t
|
||||
@spec rasterize(Group.t(), Bounds.t()) :: MapSet.t()
|
||||
def rasterize(%Group{shapes: shapes} = _group, bounds) do
|
||||
Enum.reduce(shapes, MapSet.new, fn(shape, acc) ->
|
||||
Enum.reduce(shapes, MapSet.new(), fn shape, acc ->
|
||||
MapSet.union(acc, Rasterize.rasterize(shape, bounds))
|
||||
end)
|
||||
end
|
||||
|
|
|
@ -34,36 +34,36 @@ defimpl Vivid.Rasterize, for: Vivid.Line do
|
|||
])
|
||||
|
||||
"""
|
||||
@spec rasterize(Line.t, Bounds.t) :: MapSet.t
|
||||
@spec rasterize(Line.t(), Bounds.t()) :: MapSet.t()
|
||||
def rasterize(%Line{} = line, bounds) do
|
||||
# Convert the line into absolute coordinates.
|
||||
origin = line |> Line.origin |> Point.round
|
||||
term = line |> Line.termination |> Point.round
|
||||
line = Line.init(origin, term)
|
||||
origin = line |> Line.origin() |> Point.round()
|
||||
term = line |> Line.termination() |> Point.round()
|
||||
line = Line.init(origin, term)
|
||||
|
||||
dx = line |> Line.x_distance
|
||||
dy = line |> Line.y_distance
|
||||
dx = line |> Line.x_distance()
|
||||
dy = line |> Line.y_distance()
|
||||
|
||||
steps = choose_largest_of(abs(dx), abs(dy))
|
||||
|
||||
points = if steps == 0 do
|
||||
MapSet.new([origin])
|
||||
else
|
||||
x_increment = dx / steps
|
||||
y_increment = dy / steps
|
||||
points =
|
||||
if steps == 0 do
|
||||
MapSet.new([origin])
|
||||
else
|
||||
x_increment = dx / steps
|
||||
y_increment = dy / steps
|
||||
|
||||
points = MapSet.new([origin])
|
||||
current_x = origin |> Point.x
|
||||
current_y = origin |> Point.y
|
||||
points = MapSet.new([origin])
|
||||
current_x = origin |> Point.x()
|
||||
current_y = origin |> Point.y()
|
||||
|
||||
reduce_points({points, steps, current_x,
|
||||
current_y, x_increment, y_increment})
|
||||
end
|
||||
reduce_points({points, steps, current_x, current_y, x_increment, y_increment})
|
||||
end
|
||||
|
||||
points
|
||||
|> Stream.map(&Point.round(&1))
|
||||
|> Stream.filter(&Bounds.contains?(bounds, &1))
|
||||
|> Enum.into(MapSet.new)
|
||||
|> Enum.into(MapSet.new())
|
||||
end
|
||||
|
||||
defp reduce_points({points, 0, _, _, _, _}), do: points
|
||||
|
@ -71,7 +71,7 @@ defimpl Vivid.Rasterize, for: Vivid.Line do
|
|||
defp reduce_points({points, steps, current_x, current_y, x_increment, y_increment}) do
|
||||
next_x = current_x + x_increment
|
||||
next_y = current_y + y_increment
|
||||
steps = steps - 1
|
||||
steps = steps - 1
|
||||
points = MapSet.put(points, Point.init(next_x, next_y))
|
||||
reduce_points({points, steps, next_x, next_y, x_increment, y_increment})
|
||||
end
|
||||
|
|
|
@ -22,11 +22,11 @@ defimpl Vivid.Rasterize, for: Vivid.Path do
|
|||
%Vivid.Point{x: 3, y: 3}
|
||||
])
|
||||
"""
|
||||
@spec rasterize(Path.t, Bounds.t) :: MapSet.t
|
||||
@spec rasterize(Path.t(), Bounds.t()) :: MapSet.t()
|
||||
def rasterize(%Path{} = path, bounds) do
|
||||
lines = path |> Path.to_lines
|
||||
lines = path |> Path.to_lines()
|
||||
|
||||
Enum.reduce(lines, MapSet.new, fn(line, acc) ->
|
||||
Enum.reduce(lines, MapSet.new(), fn line, acc ->
|
||||
MapSet.union(acc, Rasterize.rasterize(line, bounds))
|
||||
end)
|
||||
end
|
||||
|
|
|
@ -13,14 +13,14 @@ defimpl Vivid.Rasterize, for: Vivid.Point do
|
|||
iex> Vivid.Rasterize.rasterize(Vivid.Point.init(3,3), Vivid.Bounds.init(0, 0, 3, 3)) |> Enum.to_list
|
||||
[%Vivid.Point{x: 3, y: 3}]
|
||||
"""
|
||||
@spec rasterize(Point.t, Bounds.t) :: MapSet.t
|
||||
@spec rasterize(Point.t(), Bounds.t()) :: MapSet.t()
|
||||
def rasterize(point, bounds) do
|
||||
point = point |> Point.round
|
||||
point = point |> Point.round()
|
||||
|
||||
if Bounds.contains?(bounds, point) do
|
||||
MapSet.new([point])
|
||||
else
|
||||
MapSet.new
|
||||
MapSet.new()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -29,7 +29,7 @@ defimpl Vivid.Rasterize, for: Vivid.Polygon do
|
|||
%Vivid.Point{x: 3, y: 3}
|
||||
])
|
||||
"""
|
||||
@spec rasterize(Polygon.t, Bounds.t) :: MapSet.t
|
||||
@spec rasterize(Polygon.t(), Bounds.t()) :: MapSet.t()
|
||||
def rasterize(%Polygon{vertices: v}, _bounds) when length(v) < 3 do
|
||||
raise InvalidPolygonError, "Polygon does not contain enough edges."
|
||||
end
|
||||
|
@ -46,15 +46,15 @@ defimpl Vivid.Rasterize, for: Vivid.Polygon do
|
|||
|
||||
defp filled_polygon_inside_area(polygon, bounds) do
|
||||
polygon
|
||||
|> SLPFA.fill
|
||||
|> SLPFA.fill()
|
||||
|> Enum.filter(&Bounds.contains?(bounds, &1))
|
||||
|> Enum.into(MapSet.new)
|
||||
|> Enum.into(MapSet.new())
|
||||
end
|
||||
|
||||
defp polygon_border(polygon, bounds) do
|
||||
lines = polygon |> Polygon.to_lines
|
||||
lines = polygon |> Polygon.to_lines()
|
||||
|
||||
Enum.reduce(lines, MapSet.new, fn(line, acc) ->
|
||||
Enum.reduce(lines, MapSet.new(), fn line, acc ->
|
||||
MapSet.union(acc, Rasterize.rasterize(line, bounds))
|
||||
end)
|
||||
end
|
||||
|
|
|
@ -23,13 +23,15 @@ defmodule Vivid.RGBA do
|
|||
"""
|
||||
|
||||
@type zero_to_one :: number
|
||||
@opaque t :: %RGBA{red: zero_to_one,
|
||||
green: zero_to_one,
|
||||
blue: zero_to_one,
|
||||
alpha: zero_to_one,
|
||||
a_red: zero_to_one,
|
||||
a_green: zero_to_one,
|
||||
a_blue: zero_to_one}
|
||||
@opaque t :: %RGBA{
|
||||
red: zero_to_one,
|
||||
green: zero_to_one,
|
||||
blue: zero_to_one,
|
||||
alpha: zero_to_one,
|
||||
a_red: zero_to_one,
|
||||
a_green: zero_to_one,
|
||||
a_blue: zero_to_one
|
||||
}
|
||||
|
||||
# I would put this at the bottom, but it has to be defined *before* it's
|
||||
# used in the guard.
|
||||
|
@ -54,7 +56,7 @@ defmodule Vivid.RGBA do
|
|||
iex> Vivid.RGBA.init(0.1, 0.2, 0.3, 0.4)
|
||||
#Vivid.RGBA<{0.1, 0.2, 0.3, 0.4}>
|
||||
"""
|
||||
@spec init(zero_to_one, zero_to_one, zero_to_one) :: RGBA.t
|
||||
@spec init(zero_to_one, zero_to_one, zero_to_one) :: RGBA.t()
|
||||
def init(red, green, blue), do: init(red, green, blue, 1)
|
||||
|
||||
@doc """
|
||||
|
@ -72,46 +74,44 @@ defmodule Vivid.RGBA do
|
|||
iex> Vivid.RGBA.init(0.1, 0.2, 0.3, 0.4)
|
||||
#Vivid.RGBA<{0.1, 0.2, 0.3, 0.4}>
|
||||
"""
|
||||
@spec init(zero_to_one, zero_to_one, zero_to_one, zero_to_one) :: RGBA.t
|
||||
@spec init(zero_to_one, zero_to_one, zero_to_one, zero_to_one) :: RGBA.t()
|
||||
def init(red, green, blue, 1)
|
||||
when zero_to_one?(red) and zero_to_one?(green) and zero_to_one?(blue)
|
||||
do
|
||||
when zero_to_one?(red) and zero_to_one?(green) and zero_to_one?(blue) do
|
||||
%RGBA{
|
||||
red: red,
|
||||
green: green,
|
||||
blue: blue,
|
||||
alpha: 1,
|
||||
a_red: red,
|
||||
red: red,
|
||||
green: green,
|
||||
blue: blue,
|
||||
alpha: 1,
|
||||
a_red: red,
|
||||
a_green: green,
|
||||
a_blue: blue
|
||||
a_blue: blue
|
||||
}
|
||||
end
|
||||
|
||||
def init(red, green, blue, 0)
|
||||
when zero_to_one?(red) and zero_to_one?(green) and zero_to_one?(blue)
|
||||
do
|
||||
when zero_to_one?(red) and zero_to_one?(green) and zero_to_one?(blue) do
|
||||
%RGBA{
|
||||
red: red,
|
||||
green: green,
|
||||
blue: blue,
|
||||
alpha: 0,
|
||||
a_red: 0,
|
||||
red: red,
|
||||
green: green,
|
||||
blue: blue,
|
||||
alpha: 0,
|
||||
a_red: 0,
|
||||
a_green: 0,
|
||||
a_blue: 0
|
||||
a_blue: 0
|
||||
}
|
||||
end
|
||||
|
||||
def init(red, green, blue, alpha)
|
||||
when zero_to_one?(red) and zero_to_one?(green) and zero_to_one?(blue) and zero_to_one?(alpha)
|
||||
do
|
||||
when zero_to_one?(red) and zero_to_one?(green) and zero_to_one?(blue) and
|
||||
zero_to_one?(alpha) do
|
||||
%RGBA{
|
||||
red: red,
|
||||
green: green,
|
||||
blue: blue,
|
||||
alpha: alpha,
|
||||
a_red: red * alpha,
|
||||
red: red,
|
||||
green: green,
|
||||
blue: blue,
|
||||
alpha: alpha,
|
||||
a_red: red * alpha,
|
||||
a_green: green * alpha,
|
||||
a_blue: blue * alpha
|
||||
a_blue: blue * alpha
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -123,7 +123,7 @@ defmodule Vivid.RGBA do
|
|||
iex> Vivid.RGBA.white
|
||||
#Vivid.RGBA<{1, 1, 1, 1}>
|
||||
"""
|
||||
@spec white() :: RGBA.t
|
||||
@spec white() :: RGBA.t()
|
||||
def white, do: RGBA.init(1, 1, 1)
|
||||
|
||||
@doc """
|
||||
|
@ -134,7 +134,7 @@ defmodule Vivid.RGBA do
|
|||
iex> Vivid.RGBA.black
|
||||
#Vivid.RGBA<{0, 0, 0, 1}>
|
||||
"""
|
||||
@spec black() :: RGBA.t
|
||||
@spec black() :: RGBA.t()
|
||||
def black, do: RGBA.init(0, 0, 0)
|
||||
|
||||
@doc """
|
||||
|
@ -146,7 +146,7 @@ defmodule Vivid.RGBA do
|
|||
...> |> Vivid.RGBA.red
|
||||
0.7
|
||||
"""
|
||||
@spec red(RGBA.t) :: zero_to_one
|
||||
@spec red(RGBA.t()) :: zero_to_one
|
||||
def red(%RGBA{red: r}), do: r
|
||||
|
||||
@doc """
|
||||
|
@ -158,7 +158,7 @@ defmodule Vivid.RGBA do
|
|||
...> |> Vivid.RGBA.green
|
||||
0.6
|
||||
"""
|
||||
@spec green(RGBA.t) :: zero_to_one
|
||||
@spec green(RGBA.t()) :: zero_to_one
|
||||
def green(%RGBA{green: g}), do: g
|
||||
|
||||
@doc """
|
||||
|
@ -170,7 +170,7 @@ defmodule Vivid.RGBA do
|
|||
...> |> Vivid.RGBA.blue
|
||||
0.5
|
||||
"""
|
||||
@spec blue(RGBA.t) :: zero_to_one
|
||||
@spec blue(RGBA.t()) :: zero_to_one
|
||||
def blue(%RGBA{blue: b}), do: b
|
||||
|
||||
@doc """
|
||||
|
@ -182,7 +182,7 @@ defmodule Vivid.RGBA do
|
|||
...> |> Vivid.RGBA.alpha
|
||||
0.4
|
||||
"""
|
||||
@spec alpha(RGBA.t) :: zero_to_one
|
||||
@spec alpha(RGBA.t()) :: zero_to_one
|
||||
def alpha(%RGBA{alpha: a}), do: a
|
||||
|
||||
@doc """
|
||||
|
@ -194,7 +194,7 @@ defmodule Vivid.RGBA do
|
|||
...> |> Vivid.RGBA.to_hex
|
||||
"#B39980"
|
||||
"""
|
||||
@spec to_hex(RGBA.t) :: String.t
|
||||
@spec to_hex(RGBA.t()) :: String.t()
|
||||
def to_hex(%RGBA{red: r, green: g, blue: b, alpha: 1}) do
|
||||
r = r |> int_to_hex
|
||||
g = g |> int_to_hex
|
||||
|
@ -218,14 +218,21 @@ defmodule Vivid.RGBA do
|
|||
iex> Vivid.RGBA.over(Vivid.RGBA.black, Vivid.RGBA.init(1,1,1, 0.5))
|
||||
#Vivid.RGBA<{0.5, 0.5, 0.5, 1.0}>
|
||||
"""
|
||||
@spec over(RGBA.t, RGBA.t) :: RGBA.t
|
||||
@spec over(RGBA.t(), RGBA.t()) :: RGBA.t()
|
||||
def over(nil, %RGBA{} = colour), do: colour
|
||||
def over(%RGBA{}, %RGBA{alpha: 1} = visible), do: visible
|
||||
def over(%RGBA{} = visible, %RGBA{alpha: 0}), do: visible
|
||||
def over(%RGBA{a_red: r0, a_green: g0, a_blue: b0, alpha: a0}, %RGBA{a_red: r1, a_green: g1, a_blue: b1, alpha: a1}) do
|
||||
|
||||
def over(%RGBA{a_red: r0, a_green: g0, a_blue: b0, alpha: a0}, %RGBA{
|
||||
a_red: r1,
|
||||
a_green: g1,
|
||||
a_blue: b1,
|
||||
alpha: a1
|
||||
}) do
|
||||
a = a0 + a1 * (1 - a0)
|
||||
|
||||
[r, g, b] = [{r0, r1}, {g0, g1}, {b0, b1}]
|
||||
[r, g, b] =
|
||||
[{r0, r1}, {g0, g1}, {b0, b1}]
|
||||
|> Enum.map(fn {c0, c1} -> c1 + c0 * (1 - a1) end)
|
||||
|
||||
RGBA.init(r, g, b, a)
|
||||
|
@ -246,7 +253,7 @@ defmodule Vivid.RGBA do
|
|||
iex> Vivid.RGBA.black |> Vivid.RGBA.luminance
|
||||
0.0
|
||||
"""
|
||||
@spec luminance(RGBA.t) :: zero_to_one
|
||||
@spec luminance(RGBA.t()) :: zero_to_one
|
||||
def luminance(%RGBA{a_red: r, a_green: g, a_blue: b}) do
|
||||
[rl, gl, bl] = [r, g, b] |> Enum.map(&pow(&1, 2.2))
|
||||
0.2128 * rl + 0.7150 * gl + 0.0722 * bl
|
||||
|
@ -261,7 +268,7 @@ defmodule Vivid.RGBA do
|
|||
The chacaters used (from black to white) are `" .:-=+*#%@"`. These are
|
||||
chosen based on the `luminance/1` value of the colour.
|
||||
"""
|
||||
@spec to_ascii(RGBA.t) :: String.t
|
||||
@spec to_ascii(RGBA.t()) :: String.t()
|
||||
def to_ascii(%RGBA{} = colour) do
|
||||
l = luminance(colour)
|
||||
c = round(l * (@ascii_luminance_map_length - 1))
|
||||
|
@ -269,9 +276,9 @@ defmodule Vivid.RGBA do
|
|||
end
|
||||
|
||||
defp int_to_hex(n) when zero_to_one?(n) do
|
||||
h = Integer.to_string(round(n * 0xff), 16)
|
||||
h = Integer.to_string(round(n * 0xFF), 16)
|
||||
|
||||
case h |> String.length do
|
||||
case h |> String.length() do
|
||||
1 -> "0" <> h
|
||||
2 -> h
|
||||
end
|
||||
|
|
|
@ -1,9 +1,18 @@
|
|||
defmodule Vivid.Shape do
|
||||
alias Vivid.{Arc, Bounds, Box, Circle, Group, Line, Path, Point, Polygon}
|
||||
|
||||
@moduledoc """
|
||||
Doesn't do anything - is merely a type to represent an arbitrary shape in typespecs.
|
||||
"""
|
||||
|
||||
@type t :: Arc.t | Bounds.t | Box.t | Circle.t | Group.t |
|
||||
Line.t | Path.t | Point.t | Polygon.t
|
||||
@type t ::
|
||||
Arc.t()
|
||||
| Bounds.t()
|
||||
| Box.t()
|
||||
| Circle.t()
|
||||
| Group.t()
|
||||
| Line.t()
|
||||
| Path.t()
|
||||
| Point.t()
|
||||
| Polygon.t()
|
||||
end
|
||||
|
|
|
@ -95,7 +95,7 @@ defmodule Vivid.SLPFA do
|
|||
" @@@@ @@@@ \n" <>
|
||||
" \n"
|
||||
"""
|
||||
@spec fill(Polygon.t) :: MapSet.t
|
||||
@spec fill(Polygon.t()) :: MapSet.t()
|
||||
def fill(%Polygon{vertices: vertices}) do
|
||||
vertices
|
||||
|> create_edge_table
|
||||
|
@ -105,7 +105,7 @@ defmodule Vivid.SLPFA do
|
|||
defp process_edge_table([a0 | _] = edge_table) do
|
||||
scan_line = a0.y_min
|
||||
{active, edge_table} = update_active_list(scan_line, [], edge_table)
|
||||
points = pixels_for_active_list(MapSet.new, active, scan_line)
|
||||
points = pixels_for_active_list(MapSet.new(), active, scan_line)
|
||||
process_edge_table(points, active, edge_table, scan_line + 1)
|
||||
end
|
||||
|
||||
|
@ -122,14 +122,16 @@ defmodule Vivid.SLPFA do
|
|||
Enum.map(active, fn
|
||||
%EdgeBucket{distance_x: 0} = edge_bucket ->
|
||||
edge_bucket
|
||||
|
||||
%EdgeBucket{distance_x: dx, sum: s} = edge_bucket ->
|
||||
edge_bucket
|
||||
|> Map.put(:sum, s + dx)
|
||||
|> increment_edge
|
||||
|> Map.put(:sum, s + dx)
|
||||
|> increment_edge
|
||||
end)
|
||||
end
|
||||
|
||||
defp increment_edge(%EdgeBucket{sum: sum, distance_y: dy, sign: sign, x: x} = edge_bucket) when sum >= dy do
|
||||
defp increment_edge(%EdgeBucket{sum: sum, distance_y: dy, sign: sign, x: x} = edge_bucket)
|
||||
when sum >= dy do
|
||||
edge_bucket
|
||||
|> Map.put(:x, x + sign)
|
||||
|> Map.put(:sum, sum - dy)
|
||||
|
@ -142,45 +144,54 @@ defmodule Vivid.SLPFA do
|
|||
active
|
||||
|> Stream.chunk(2)
|
||||
|> Enum.reduce(points, fn [a0, a1], points ->
|
||||
Enum.reduce(a0.x + 1..a1.x - 1, points, fn x, points ->
|
||||
Enum.reduce((a0.x + 1)..(a1.x - 1), points, fn x, points ->
|
||||
MapSet.put(points, Point.init(x, y))
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
defp update_active_list(scan_line, active, edge_table) do
|
||||
{active, edge_table} = active
|
||||
{active, edge_table} =
|
||||
active
|
||||
|> Stream.concat(edge_table)
|
||||
|> Enum.reduce({[], []}, fn
|
||||
%EdgeBucket{y_min: y_min, y_max: y_max} = edge, {active, edge_table} when y_min <= scan_line and y_max > scan_line ->
|
||||
%EdgeBucket{y_min: y_min, y_max: y_max} = edge, {active, edge_table}
|
||||
when y_min <= scan_line and y_max > scan_line ->
|
||||
active = [edge | active]
|
||||
{active, edge_table}
|
||||
|
||||
%EdgeBucket{y_min: y_min} = edge, {active, edge_table} when y_min >= scan_line ->
|
||||
edge_table = [edge | edge_table]
|
||||
{active, edge_table}
|
||||
|
||||
_edge_bucket, {active, edge_table} ->
|
||||
{active, edge_table}
|
||||
end)
|
||||
|
||||
new_active = active
|
||||
new_active =
|
||||
active
|
||||
|> Enum.sort(&sort_by_x_and_slope(&1, &2))
|
||||
|
||||
{new_active, edge_table}
|
||||
end
|
||||
|
||||
defp sort_by_x_and_slope(%EdgeBucket{x: x0},
|
||||
%EdgeBucket{x: x1})
|
||||
when x0 < x1, do: true
|
||||
defp sort_by_x_and_slope(%EdgeBucket{x: x0},
|
||||
%EdgeBucket{x: x1})
|
||||
when x0 > x1, do: false
|
||||
defp sort_by_x_and_slope(%EdgeBucket{distance_x: dx0, distance_y: dy0},
|
||||
%EdgeBucket{distance_x: dx1, distance_y: dy1}),
|
||||
do: (dx0 / dy0) < (dx1 / dy1)
|
||||
defp sort_by_x_and_slope(%EdgeBucket{x: x0}, %EdgeBucket{x: x1})
|
||||
when x0 < x1,
|
||||
do: true
|
||||
|
||||
defp sort_by_x_and_slope(%EdgeBucket{x: x0}, %EdgeBucket{x: x1})
|
||||
when x0 > x1,
|
||||
do: false
|
||||
|
||||
defp sort_by_x_and_slope(%EdgeBucket{distance_x: dx0, distance_y: dy0}, %EdgeBucket{
|
||||
distance_x: dx1,
|
||||
distance_y: dy1
|
||||
}),
|
||||
do: dx0 / dy0 < dx1 / dy1
|
||||
|
||||
defp create_edge_table(vertices) do
|
||||
vertices
|
||||
|> Stream.with_index
|
||||
|> Stream.with_index()
|
||||
|> Stream.map(fn {p0, idx} ->
|
||||
p1 = Enum.at(vertices, idx - 1)
|
||||
Line.init(p0, p1)
|
||||
|
@ -191,25 +202,28 @@ defmodule Vivid.SLPFA do
|
|||
|> Enum.sort(&sort_by_min_y(&1, &2))
|
||||
end
|
||||
|
||||
defp line_left_to_right(%Line{origin: %Point{x: x0} = p0, termination: %Point{x: x1} = p1}) when x0 > x1, do: Line.init(p1, p0)
|
||||
defp line_left_to_right(%Line{origin: %Point{x: x0} = p0, termination: %Point{x: x1} = p1})
|
||||
when x0 > x1,
|
||||
do: Line.init(p1, p0)
|
||||
|
||||
defp line_left_to_right(line), do: line
|
||||
|
||||
defp line_to_edge_bucket(%Line{origin: p0, termination: p1}) do
|
||||
y_max = if p0.y > p1.y, do: p0.y, else: p1.y
|
||||
y_min = if p0.y < p1.y, do: p0.y, else: p1.y
|
||||
y_max = if p0.y > p1.y, do: p0.y, else: p1.y
|
||||
y_min = if p0.y < p1.y, do: p0.y, else: p1.y
|
||||
init_x = if p0.y < p1.y, do: p0.x, else: p1.x
|
||||
sign = if p1.y - p0.y < 0, do: -1, else: 1
|
||||
dx = abs(p1.x - p0.x)
|
||||
dy = abs(p1.y - p0.y)
|
||||
sign = if p1.y - p0.y < 0, do: -1, else: 1
|
||||
dx = abs(p1.x - p0.x)
|
||||
dy = abs(p1.y - p0.y)
|
||||
|
||||
%EdgeBucket{
|
||||
y_min: round(y_min),
|
||||
y_max: round(y_max),
|
||||
x: round(init_x),
|
||||
sign: sign,
|
||||
y_min: round(y_min),
|
||||
y_max: round(y_max),
|
||||
x: round(init_x),
|
||||
sign: sign,
|
||||
distance_x: round(dx),
|
||||
distance_y: round(dy),
|
||||
sum: 0
|
||||
sum: 0
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ defmodule Vivid.Transform do
|
|||
alias Vivid.{Point, Transform, Bounds, Shape}
|
||||
alias Vivid.Transformable
|
||||
import Vivid.Math
|
||||
defstruct [operations: [], shape: nil]
|
||||
defstruct operations: [], shape: nil
|
||||
|
||||
defmodule Operation do
|
||||
alias __MODULE__
|
||||
|
@ -10,7 +10,7 @@ defmodule Vivid.Transform do
|
|||
|
||||
@moduledoc false
|
||||
|
||||
@opaque t :: %Operation{function: function, name: String.t}
|
||||
@opaque t :: %Operation{function: function, name: String.t()}
|
||||
end
|
||||
|
||||
@moduledoc ~S"""
|
||||
|
@ -72,8 +72,8 @@ defmodule Vivid.Transform do
|
|||
"@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
|
||||
"""
|
||||
|
||||
@opaque t :: %Transform{shape: Shape.t, operations: [Operation.t]}
|
||||
@type shape_or_transform :: Transform.t | Shape.t
|
||||
@opaque t :: %Transform{shape: Shape.t(), operations: [Operation.t()]}
|
||||
@type shape_or_transform :: Transform.t() | Shape.t()
|
||||
@type degrees :: number
|
||||
|
||||
@doc """
|
||||
|
@ -86,7 +86,7 @@ defmodule Vivid.Transform do
|
|||
...> |> Vivid.Transform.apply
|
||||
#Vivid.Polygon<[#Vivid.Point<{15, 10}>, #Vivid.Point<{15, 15}>, #Vivid.Point<{10, 15}>, #Vivid.Point<{10, 10}>]>
|
||||
"""
|
||||
@spec translate(shape_or_transform, number, number) :: Transform.t
|
||||
@spec translate(shape_or_transform, number, number) :: Transform.t()
|
||||
def translate(shape, x, y) do
|
||||
fun = fn _shape ->
|
||||
&Transform.Point.translate(&1, x, y)
|
||||
|
@ -105,7 +105,7 @@ defmodule Vivid.Transform do
|
|||
...> |> 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}>]>
|
||||
"""
|
||||
@spec scale(shape_or_transform, number) :: Transform.t
|
||||
@spec scale(shape_or_transform, number) :: Transform.t()
|
||||
def scale(shape, uniform) do
|
||||
fun = fn shape ->
|
||||
origin = Bounds.center_of(shape)
|
||||
|
@ -126,7 +126,7 @@ defmodule Vivid.Transform do
|
|||
#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}>]>
|
||||
|
||||
"""
|
||||
@spec scale(shape_or_transform, number, number) :: Transform.t
|
||||
@spec scale(shape_or_transform, number, number) :: Transform.t()
|
||||
def scale(shape, x, y) do
|
||||
fun = fn shape ->
|
||||
origin = Bounds.center_of(shape)
|
||||
|
@ -163,9 +163,10 @@ defmodule Vivid.Transform do
|
|||
"@@@@@@@@ @@@@@@@@\n" <>
|
||||
"@@@@@@@@@@@@@@@@@\n"
|
||||
"""
|
||||
@spec rotate(shape_or_transform, degrees) :: Transform.t
|
||||
@spec rotate(shape_or_transform, degrees) :: Transform.t()
|
||||
def rotate(shape, degrees) do
|
||||
radians = degrees_to_radians(degrees)
|
||||
|
||||
fun = fn shape ->
|
||||
origin = Bounds.center_of(shape)
|
||||
&Transform.Point.rotate_radians(&1, origin, radians)
|
||||
|
@ -201,9 +202,10 @@ defmodule Vivid.Transform do
|
|||
"@@@@@@@@ @@@@@@@@\n" <>
|
||||
"@@@@@@@@@@@@@@@@@\n"
|
||||
"""
|
||||
@spec rotate(shape_or_transform, degrees, Point.t) :: Transform.t
|
||||
@spec rotate(shape_or_transform, degrees, Point.t()) :: Transform.t()
|
||||
def rotate(shape, degrees, %Point{x: x, y: y} = origin) do
|
||||
radians = degrees_to_radians(degrees)
|
||||
|
||||
fun = fn _shape ->
|
||||
&Transform.Point.rotate_radians(&1, origin, radians)
|
||||
end
|
||||
|
@ -237,18 +239,20 @@ defmodule Vivid.Transform do
|
|||
"@ @\n" <>
|
||||
"@@@@@@@@@@@@@\n"
|
||||
"""
|
||||
@spec center(shape_or_transform, Shape.t) :: Transform.t
|
||||
@spec center(shape_or_transform, Shape.t()) :: Transform.t()
|
||||
def center(shape, bounds) do
|
||||
bounds = Bounds.bounds(bounds)
|
||||
bounds_width = Bounds.width(bounds)
|
||||
bounds = Bounds.bounds(bounds)
|
||||
bounds_width = Bounds.width(bounds)
|
||||
bounds_height = Bounds.height(bounds)
|
||||
bounds_center = Bounds.center_of(bounds)
|
||||
|
||||
fun = fn shape ->
|
||||
shape_center = Bounds.center_of(shape)
|
||||
{tr_x, tr_y} = Point.vector(shape_center, bounds_center)
|
||||
|
||||
&Transform.Point.translate(&1, tr_x, tr_y)
|
||||
end
|
||||
|
||||
apply_transform(shape, fun, "center-within-#{bounds_width}-#{bounds_height}")
|
||||
end
|
||||
|
||||
|
@ -262,22 +266,23 @@ defmodule Vivid.Transform do
|
|||
...> |> 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}>]>
|
||||
"""
|
||||
@spec stretch(shape_or_transform, Shape.t) :: Transform.t
|
||||
@spec stretch(shape_or_transform, Shape.t()) :: Transform.t()
|
||||
def stretch(shape, bounds) do
|
||||
bounds = Bounds.bounds(bounds)
|
||||
bounds_min = Bounds.min(bounds)
|
||||
bounds_width = Bounds.width(bounds)
|
||||
bounds = Bounds.bounds(bounds)
|
||||
bounds_min = Bounds.min(bounds)
|
||||
bounds_width = Bounds.width(bounds)
|
||||
bounds_height = Bounds.height(bounds)
|
||||
|
||||
fun = fn shape ->
|
||||
shape_bounds = Bounds.bounds(shape)
|
||||
shape_width = Bounds.width(shape_bounds)
|
||||
shape_height = Bounds.height(shape_bounds)
|
||||
shape_min = Bounds.min(shape_bounds)
|
||||
shape_bounds = Bounds.bounds(shape)
|
||||
shape_width = Bounds.width(shape_bounds)
|
||||
shape_height = Bounds.height(shape_bounds)
|
||||
shape_min = Bounds.min(shape_bounds)
|
||||
|
||||
{tr_x, tr_y} = Point.vector(shape_min, bounds_min)
|
||||
{tr_x, tr_y} = Point.vector(shape_min, bounds_min)
|
||||
|
||||
scale_x = bounds_width / shape_width
|
||||
scale_y = bounds_height / shape_height
|
||||
scale_x = bounds_width / shape_width
|
||||
scale_y = bounds_height / shape_height
|
||||
|
||||
fn point ->
|
||||
point
|
||||
|
@ -285,6 +290,7 @@ defmodule Vivid.Transform do
|
|||
|> Transform.Point.scale(scale_x, scale_y)
|
||||
end
|
||||
end
|
||||
|
||||
apply_transform(shape, fun, "stretch-to-#{bounds_width}-#{bounds_height}")
|
||||
end
|
||||
|
||||
|
@ -298,23 +304,24 @@ defmodule Vivid.Transform do
|
|||
...> |> 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}>]>
|
||||
"""
|
||||
@spec fill(shape_or_transform, Shape.t) :: Transform.t
|
||||
@spec fill(shape_or_transform, Shape.t()) :: Transform.t()
|
||||
def fill(shape, bounds) do
|
||||
bounds = Bounds.bounds(bounds)
|
||||
bounds_min = Bounds.min(bounds)
|
||||
bounds_width = Bounds.width(bounds)
|
||||
bounds = Bounds.bounds(bounds)
|
||||
bounds_min = Bounds.min(bounds)
|
||||
bounds_width = Bounds.width(bounds)
|
||||
bounds_height = Bounds.height(bounds)
|
||||
|
||||
fun = fn shape ->
|
||||
shape_bounds = Bounds.bounds(shape)
|
||||
shape_width = Bounds.width(shape_bounds)
|
||||
shape_height = Bounds.height(shape_bounds)
|
||||
shape_min = Bounds.min(shape_bounds)
|
||||
shape_bounds = Bounds.bounds(shape)
|
||||
shape_width = Bounds.width(shape_bounds)
|
||||
shape_height = Bounds.height(shape_bounds)
|
||||
shape_min = Bounds.min(shape_bounds)
|
||||
|
||||
{tr_x, tr_y} = Point.vector(shape_min, bounds_min)
|
||||
{tr_x, tr_y} = Point.vector(shape_min, bounds_min)
|
||||
|
||||
scale_x = bounds_width / shape_width
|
||||
scale_y = bounds_height / shape_height
|
||||
scale = if scale_x < scale_y, do: scale_x, else: scale_y
|
||||
scale_x = bounds_width / shape_width
|
||||
scale_y = bounds_height / shape_height
|
||||
scale = if scale_x < scale_y, do: scale_x, else: scale_y
|
||||
|
||||
fn point ->
|
||||
point
|
||||
|
@ -322,6 +329,7 @@ defmodule Vivid.Transform do
|
|||
|> Transform.Point.scale(scale, scale)
|
||||
end
|
||||
end
|
||||
|
||||
apply_transform(shape, fun, "fill-to-#{bounds_width}-#{bounds_height}")
|
||||
end
|
||||
|
||||
|
@ -336,23 +344,24 @@ defmodule Vivid.Transform do
|
|||
...> |> 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}>]>
|
||||
"""
|
||||
@spec overflow(shape_or_transform, Shape.t) :: Transform.t
|
||||
@spec overflow(shape_or_transform, Shape.t()) :: Transform.t()
|
||||
def overflow(shape, bounds) do
|
||||
bounds = Bounds.bounds(bounds)
|
||||
bounds_min = Bounds.min(bounds)
|
||||
bounds_width = Bounds.width(bounds)
|
||||
bounds = Bounds.bounds(bounds)
|
||||
bounds_min = Bounds.min(bounds)
|
||||
bounds_width = Bounds.width(bounds)
|
||||
bounds_height = Bounds.height(bounds)
|
||||
|
||||
fun = fn shape ->
|
||||
shape_bounds = Bounds.bounds(shape)
|
||||
shape_width = Bounds.width(shape_bounds)
|
||||
shape_height = Bounds.height(shape_bounds)
|
||||
shape_min = Bounds.min(shape_bounds)
|
||||
shape_bounds = Bounds.bounds(shape)
|
||||
shape_width = Bounds.width(shape_bounds)
|
||||
shape_height = Bounds.height(shape_bounds)
|
||||
shape_min = Bounds.min(shape_bounds)
|
||||
|
||||
{tr_x, tr_y} = Point.vector(shape_min, bounds_min)
|
||||
{tr_x, tr_y} = Point.vector(shape_min, bounds_min)
|
||||
|
||||
scale_x = bounds_width / shape_width
|
||||
scale_y = bounds_height / shape_height
|
||||
scale = if scale_x > scale_y, do: scale_x, else: scale_y
|
||||
scale_x = bounds_width / shape_width
|
||||
scale_y = bounds_height / shape_height
|
||||
scale = if scale_x > scale_y, do: scale_x, else: scale_y
|
||||
|
||||
fn point ->
|
||||
point
|
||||
|
@ -360,6 +369,7 @@ defmodule Vivid.Transform do
|
|||
|> Transform.Point.scale(scale, scale)
|
||||
end
|
||||
end
|
||||
|
||||
apply_transform(shape, fun, "overflow-#{bounds_width}-#{bounds_height}")
|
||||
end
|
||||
|
||||
|
@ -388,16 +398,16 @@ defmodule Vivid.Transform do
|
|||
...> |> Vivid.Transform.apply
|
||||
#Vivid.Polygon<[#Vivid.Point<{25, 10}>, #Vivid.Point<{25, 20}>, #Vivid.Point<{15, 20}>, #Vivid.Point<{15, 10}>]>
|
||||
"""
|
||||
@spec transform(shape_or_transform, function) :: Transform.t
|
||||
@spec transform(shape_or_transform, function) :: Transform.t()
|
||||
def transform(shape, fun), do: apply_transform(shape, fun, inspect(fun))
|
||||
|
||||
@doc """
|
||||
Apply a transformation pipeline returning the modified shape.
|
||||
"""
|
||||
@spec apply(Transform.t) :: Shape.t
|
||||
@spec apply(Transform.t()) :: Shape.t()
|
||||
def apply(%Transform{operations: operations, shape: shape}) do
|
||||
operations
|
||||
|> Enum.reverse
|
||||
|> Enum.reverse()
|
||||
|> Enum.reduce(shape, fn %Operation{function: fun}, shape ->
|
||||
transform = fun.(shape)
|
||||
Transformable.transform(shape, transform)
|
||||
|
@ -408,6 +418,7 @@ defmodule Vivid.Transform do
|
|||
operations = [%Operation{function: fun, name: name} | operations]
|
||||
%{transform | operations: operations}
|
||||
end
|
||||
|
||||
defp apply_transform(shape, fun, name) do
|
||||
%Transform{operations: [%Operation{function: fun, name: name}], shape: shape}
|
||||
end
|
||||
|
|
|
@ -16,19 +16,20 @@ defmodule Vivid.Transform.Point do
|
|||
@doc """
|
||||
Translate `point` (ie move it) by adding `x` and `y` to it's coordinates.
|
||||
"""
|
||||
@spec translate(Point.t, number, number) :: Point.t
|
||||
@spec translate(Point.t(), number, number) :: Point.t()
|
||||
def translate(%Point{x: x0, y: y0} = _point, x, y), do: Point.init(x0 + x, y0 + y)
|
||||
|
||||
@doc """
|
||||
Scale `point` (ie move it) by multiplying it's distance from the `0`, `0` point by `x_factor` and `y_factor`.
|
||||
"""
|
||||
@spec scale(Point, number, number) :: Point.t
|
||||
def scale(%Point{} = point, x_factor, y_factor), do: scale(point, x_factor, y_factor, Point.init(0, 0))
|
||||
@spec scale(Point, number, number) :: Point.t()
|
||||
def scale(%Point{} = point, x_factor, y_factor),
|
||||
do: scale(point, x_factor, y_factor, Point.init(0, 0))
|
||||
|
||||
@doc """
|
||||
Scale `point` (ie move it) by multiplying it's distance from the origin point by `x_factor` and `y_factor`.
|
||||
"""
|
||||
@spec scale(Point.t, number, number, Point.t) :: Point.t
|
||||
@spec scale(Point.t(), number, number, Point.t()) :: Point.t()
|
||||
def scale(%Point{x: x, y: y} = _point, x_factor, y_factor, %Point{x: xo, y: yo} = _origin) do
|
||||
x = (x - xo) * x_factor + xo
|
||||
y = (y - yo) * y_factor + yo
|
||||
|
@ -38,13 +39,14 @@ defmodule Vivid.Transform.Point do
|
|||
@doc """
|
||||
Rotate `point` `degrees` around an `origin` point.
|
||||
"""
|
||||
@spec rotate(Point.t, Point.t, degrees) :: Point.t
|
||||
def rotate(point, origin, degrees), do: rotate_radians(point, origin, degrees_to_radians(degrees))
|
||||
@spec rotate(Point.t(), Point.t(), degrees) :: Point.t()
|
||||
def rotate(point, origin, degrees),
|
||||
do: rotate_radians(point, origin, degrees_to_radians(degrees))
|
||||
|
||||
@doc """
|
||||
Rotate `point` `radians` around an `origin` point.
|
||||
"""
|
||||
@spec rotate_radians(Point.t, Point.t, radians) :: Point.t
|
||||
@spec rotate_radians(Point.t(), Point.t(), radians) :: Point.t()
|
||||
def rotate_radians(%Point{x: x0, y: y0} = _point, %Point{x: x1, y: y1} = _origin, radians) do
|
||||
x = cos(radians) * (x0 - x1) - sin(radians) * (y0 - y1) + x1
|
||||
y = sin(radians) * (x0 - x1) + cos(radians) * (y0 - y1) + y1
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
defprotocol Vivid.Transformable do
|
||||
alias Vivid.Shape
|
||||
|
||||
@moduledoc """
|
||||
This protocol is used to apply *point* transformations to a shape.
|
||||
"""
|
||||
|
@ -7,6 +8,6 @@ defprotocol Vivid.Transformable do
|
|||
@doc """
|
||||
Transform all of a shape's points using `fun`.
|
||||
"""
|
||||
@spec transform(Shape.t, function) :: Shape.t
|
||||
@spec transform(Shape.t(), function) :: Shape.t()
|
||||
def transform(shape, fun)
|
||||
end
|
||||
|
|
|
@ -10,11 +10,11 @@ defimpl Vivid.Transformable, for: Vivid.Arc do
|
|||
Many of the transformations can't be applied to an Arc, but we
|
||||
can convert it to a path and then use that to apply transformations.
|
||||
"""
|
||||
@spec transform(Arc.t, (Point.t -> Point.t)) :: Path.t
|
||||
@spec transform(Arc.t(), (Point.t() -> Point.t())) :: Path.t()
|
||||
def transform(arc, fun) do
|
||||
arc
|
||||
|> Arc.to_path
|
||||
|> Arc.to_path()
|
||||
|> Stream.map(&Transformable.transform(&1, fun))
|
||||
|> Enum.into(Path.init)
|
||||
|> Enum.into(Path.init())
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,10 +7,10 @@ defimpl Vivid.Transformable, for: Vivid.Box do
|
|||
* `box` - the box to modify.
|
||||
* `fun` - the transformation function to apply.
|
||||
"""
|
||||
@spec transform(Box.t, (Point.t -> Point.t)) :: Box.t
|
||||
@spec transform(Box.t(), (Point.t() -> Point.t())) :: Box.t()
|
||||
def transform(box, fun) do
|
||||
box
|
||||
|> Box.to_polygon
|
||||
|> Box.to_polygon()
|
||||
|> Transformable.transform(fun)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,10 +10,10 @@ defimpl Vivid.Transformable, for: Vivid.Circle do
|
|||
Many of the transformations can't be applied to a Circle, but we
|
||||
can convert it to a polygon and then use that to apply transformations.
|
||||
"""
|
||||
@spec transform(Circle.t, (Point.t -> Point.t)) :: Polygon.t
|
||||
@spec transform(Circle.t(), (Point.t() -> Point.t())) :: Polygon.t()
|
||||
def transform(%Circle{fill: f} = circle, fun) do
|
||||
circle
|
||||
|> Circle.to_polygon
|
||||
|> Circle.to_polygon()
|
||||
|> Stream.map(&Transformable.transform(&1, fun))
|
||||
|> Enum.into(Polygon.init([], f))
|
||||
end
|
||||
|
|
|
@ -7,10 +7,10 @@ defimpl Vivid.Transformable, for: Vivid.Group do
|
|||
* `group` - the group to modify.
|
||||
* `fun` - the transformation function to apply.
|
||||
"""
|
||||
@spec transform(Group.t, (Point.t -> Point.t)) :: Group.t
|
||||
@spec transform(Group.t(), (Point.t() -> Point.t())) :: Group.t()
|
||||
def transform(group, fun) do
|
||||
group
|
||||
|> Stream.map(&Transformable.transform(&1, fun))
|
||||
|> Enum.into(Group.init)
|
||||
|> Enum.into(Group.init())
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,10 +7,10 @@ defimpl Vivid.Transformable, for: Vivid.Line do
|
|||
* `line` - the line to modify.
|
||||
* `fun` - the transformation function to apply.
|
||||
"""
|
||||
@spec transform(Line.t, (Point.t -> Point.t)) :: Line.t
|
||||
@spec transform(Line.t(), (Point.t() -> Point.t())) :: Line.t()
|
||||
def transform(line, fun) do
|
||||
origin = line |> Line.origin |> Transformable.transform(fun)
|
||||
term = line |> Line.termination |> Transformable.transform(fun)
|
||||
origin = line |> Line.origin() |> Transformable.transform(fun)
|
||||
term = line |> Line.termination() |> Transformable.transform(fun)
|
||||
Line.init(origin, term)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,10 +7,10 @@ defimpl Vivid.Transformable, for: Vivid.Path do
|
|||
* `path` - the path to modify.
|
||||
* `fun` - the transformation function to apply.
|
||||
"""
|
||||
@spec transform(Path.t, (Point.t -> Point.t)) :: Path.t
|
||||
@spec transform(Path.t(), (Point.t() -> Point.t())) :: Path.t()
|
||||
def transform(path, fun) do
|
||||
path
|
||||
|> Stream.map(&Transformable.transform(&1, fun))
|
||||
|> Enum.into(Path.init)
|
||||
|> Enum.into(Path.init())
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,6 +7,6 @@ defimpl Vivid.Transformable, for: Vivid.Point do
|
|||
* `point` - the point to modify.
|
||||
* `fun` - the transformation function to apply.
|
||||
"""
|
||||
@spec transform(Point.t, (Point.t -> Point.t)) :: Point.t
|
||||
@spec transform(Point.t(), (Point.t() -> Point.t())) :: Point.t()
|
||||
def transform(point, fun), do: fun.(point)
|
||||
end
|
||||
|
|
|
@ -7,7 +7,7 @@ defimpl Vivid.Transformable, for: Vivid.Polygon do
|
|||
* `polygon` - the polygon to modify.
|
||||
* `fun` - the transformation function to apply.
|
||||
"""
|
||||
@spec transform(Polygon.t, (Point.t -> Point.t)) :: Polygon.t
|
||||
@spec transform(Polygon.t(), (Point.t() -> Point.t())) :: Polygon.t()
|
||||
def transform(%Polygon{fill: fill} = polygon, fun) do
|
||||
polygon
|
||||
|> Stream.map(&Transformable.transform(&1, fun))
|
||||
|
|
34
mix.exs
34
mix.exs
|
@ -4,19 +4,23 @@ defmodule Vivid.Mixfile do
|
|||
@version "0.4.2"
|
||||
|
||||
def project do
|
||||
[app: :vivid,
|
||||
version: @version,
|
||||
description: description(),
|
||||
elixir: "~> 1.3",
|
||||
build_embedded: Mix.env == :prod,
|
||||
start_permanent: Mix.env == :prod,
|
||||
package: package(),
|
||||
deps: deps(),
|
||||
docs: [source_ref: "v#{@version}",
|
||||
main: "Vivid",
|
||||
canonical: "http://hexdocs.pm/vivid",
|
||||
source_url: "https://github.com/jamesotron/vivid.ex",
|
||||
extras: ["guides/getting-started.md"]]]
|
||||
[
|
||||
app: :vivid,
|
||||
version: @version,
|
||||
description: description(),
|
||||
elixir: "~> 1.3",
|
||||
build_embedded: Mix.env() == :prod,
|
||||
start_permanent: Mix.env() == :prod,
|
||||
package: package(),
|
||||
deps: deps(),
|
||||
docs: [
|
||||
source_ref: "v#{@version}",
|
||||
main: "Vivid",
|
||||
canonical: "http://hexdocs.pm/vivid",
|
||||
source_url: "https://github.com/jamesotron/vivid.ex",
|
||||
extras: ["guides/getting-started.md"]
|
||||
]
|
||||
]
|
||||
end
|
||||
|
||||
# Configuration for the OTP application
|
||||
|
@ -34,8 +38,8 @@ defmodule Vivid.Mixfile do
|
|||
|
||||
def package do
|
||||
[
|
||||
maintainers: [ "James Harton <james@messagerocket.co>" ],
|
||||
licenses: [ "MIT" ],
|
||||
maintainers: ["James Harton <james@messagerocket.co>"],
|
||||
licenses: ["MIT"],
|
||||
links: %{
|
||||
"Source" => "https://github.com/jamesotron/vivid.ex"
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Collectable.Vivid.GroupTest do
|
||||
use ExUnit.Case
|
||||
doctest Collectable.Vivid.Group
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Collectable.Vivid.PathTest do
|
||||
use ExUnit.Case
|
||||
doctest Collectable.Vivid.Path
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Collectable.Vivid.PolygonTest do
|
||||
use ExUnit.Case
|
||||
doctest Collectable.Vivid.Polygon
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Enumerable.Vivid.BufferTest do
|
||||
use ExUnit.Case
|
||||
doctest Enumerable.Vivid.Buffer
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Enumerable.Vivid.GroupTest do
|
||||
use ExUnit.Case
|
||||
doctest Enumerable.Vivid.Group
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Enumerable.Vivid.LineTest do
|
||||
use ExUnit.Case
|
||||
doctest Enumerable.Vivid.Line
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Enumerable.Vivid.PathTest do
|
||||
use ExUnit.Case
|
||||
doctest Enumerable.Vivid.Path
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Enumerable.Vivid.PolygonTest do
|
||||
use ExUnit.Case
|
||||
doctest Enumerable.Vivid.Polygon
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Vivid.ArcTest do
|
||||
use ExUnit.Case
|
||||
doctest Vivid.Arc
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Vivid.BoundsTest do
|
||||
use ExUnit.Case
|
||||
doctest Vivid.Bounds
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Vivid.BoxTest do
|
||||
use ExUnit.Case
|
||||
doctest Vivid.Box
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Vivid.BufferTest do
|
||||
use ExUnit.Case
|
||||
doctest Vivid.Buffer
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Vivid.CircleTest do
|
||||
use ExUnit.Case
|
||||
doctest Vivid.Circle
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Vivid.FontTest do
|
||||
use ExUnit.Case
|
||||
doctest Vivid.Font
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Vivid.FrameTest do
|
||||
use ExUnit.Case
|
||||
doctest Vivid.Frame
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Vivid.GroupTest do
|
||||
use ExUnit.Case
|
||||
doctest Vivid.Group
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Vivid.LineTest do
|
||||
use ExUnit.Case
|
||||
doctest Vivid.Line
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Vivid.MathTest do
|
||||
use ExUnit.Case
|
||||
doctest Vivid.Math
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Vivid.PathTest do
|
||||
use ExUnit.Case
|
||||
doctest Vivid.Path
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Vivid.PointTest do
|
||||
use ExUnit.Case
|
||||
doctest Vivid.Point
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Vivid.Rasterize.CircleTest do
|
||||
use ExUnit.Case
|
||||
doctest Vivid.Rasterize.Vivid.Circle
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Vivid.Rasterize.GroupTest do
|
||||
use ExUnit.Case
|
||||
doctest Vivid.Rasterize.Vivid.Group
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
defmodule Vivid.Rasterize.LineTest do
|
||||
use ExUnit.Case
|
||||
doctest Vivid.Rasterize.Vivid.Line
|
||||
end
|
||||
end
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue