Add shape groups.
This commit is contained in:
parent
2c5cbba334
commit
6d5463d2b5
8 changed files with 167 additions and 0 deletions
20
lib/collectable/vivid/group.ex
Normal file
20
lib/collectable/vivid/group.ex
Normal file
|
@ -0,0 +1,20 @@
|
|||
defimpl Collectable, for: Vivid.Group do
|
||||
alias Vivid.Group
|
||||
|
||||
@doc """
|
||||
Collect an enumerable into a Group.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> [Vivid.Point.init(1,1)] |> Enum.into(Vivid.Group.init)
|
||||
%Vivid.Group{shapes: MapSet.new([%Vivid.Point{x: 1, y: 1}])}
|
||||
"""
|
||||
|
||||
def into(%Group{shapes: shapes}) do
|
||||
{MapSet.new, 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
|
44
lib/enumerable/vivid/group.ex
Normal file
44
lib/enumerable/vivid/group.ex
Normal file
|
@ -0,0 +1,44 @@
|
|||
defimpl Enumerable, for: Vivid.Group do
|
||||
alias Vivid.Group
|
||||
|
||||
@moduledoc """
|
||||
Implements the Enumerable protocol for %Group{}
|
||||
"""
|
||||
|
||||
@doc """
|
||||
Returns the number of Shapes in a group.
|
||||
|
||||
## Example
|
||||
|
||||
iex> Vivid.Group.init([Vivid.Point.init(1,1), Vivid.Point.init(2,2)])
|
||||
...> |> Enum.count
|
||||
2
|
||||
"""
|
||||
def count(%Group{shapes: shapes}), do: {:ok, Enum.count(shapes)}
|
||||
|
||||
@doc """
|
||||
Returns whether the shape is a member of a group.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> Vivid.Group.init([Vivid.Point.init(1,1)])
|
||||
...> |> Enum.member?(Vivid.Point.init(1,1))
|
||||
true
|
||||
|
||||
iex> Vivid.Group.init([Vivid.Point.init(1,1)])
|
||||
...> |> Enum.member?(Vivid.Point.init(2,2))
|
||||
false
|
||||
"""
|
||||
def member?(%Group{shapes: shapes}, shape), do: {:ok, Enum.member?(shapes, shape)}
|
||||
|
||||
@doc """
|
||||
Reduce's the Path's shapes into an accumulator
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
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}
|
||||
"""
|
||||
def reduce(%Group{shapes: shapes}, acc, fun), do: Enumerable.MapSet.reduce(shapes, acc, fun)
|
||||
end
|
56
lib/vivid/group.ex
Normal file
56
lib/vivid/group.ex
Normal file
|
@ -0,0 +1,56 @@
|
|||
defmodule Vivid.Group do
|
||||
alias Vivid.Group
|
||||
defstruct ~w(shapes)a
|
||||
|
||||
@moduledoc """
|
||||
Represents a collection of shapes which can be Rasterized in a single pass.
|
||||
"""
|
||||
|
||||
@doc """
|
||||
Initialize a group either empty or from a list of shapes.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> circle = Vivid.Circle.init(Vivid.Point.init(5,5), 5)
|
||||
...> line = Vivid.Line.init(Vivid.Point.init(1,1), Vivid.Point.init(10,10))
|
||||
...> Vivid.Group.init([circle, line])
|
||||
%Vivid.Group{shapes: MapSet.new([
|
||||
%Vivid.Circle{center: %Vivid.Point{x: 5, y: 5}, radius: 5},
|
||||
%Vivid.Line{origin: %Vivid.Point{x: 1, y: 1}, termination: %Vivid.Point{x: 10, y: 10}}
|
||||
])}
|
||||
|
||||
iex> Vivid.Group.init
|
||||
%Vivid.Group{shapes: MapSet.new()}
|
||||
"""
|
||||
|
||||
def init, do: %Group{shapes: MapSet.new()}
|
||||
def init(shapes) do
|
||||
%Group{shapes: MapSet.new(shapes)}
|
||||
end
|
||||
|
||||
@doc """
|
||||
Remove a shape from a Group
|
||||
|
||||
## Example
|
||||
|
||||
iex> line = Vivid.Line.init(Vivid.Point.init(1,1), Vivid.Point.init(10,10))
|
||||
...> Vivid.Group.init([line])
|
||||
...> |> Vivid.Group.delete(line)
|
||||
%Vivid.Group{shapes: MapSet.new()}
|
||||
"""
|
||||
def delete(%Group{shapes: shapes}, shape), do: shapes |> MapSet.delete(shape) |> init
|
||||
|
||||
@doc """
|
||||
Add a shape to a Group
|
||||
|
||||
## Example
|
||||
|
||||
iex> line = Vivid.Line.init(Vivid.Point.init(1,1), Vivid.Point.init(10,10))
|
||||
...> Vivid.Group.init()
|
||||
...> |> Vivid.Group.put(line)
|
||||
%Vivid.Group{shapes: MapSet.new([
|
||||
%Vivid.Line{origin: %Vivid.Point{x: 1, y: 1}, termination: %Vivid.Point{x: 10, y: 10}}
|
||||
])}
|
||||
"""
|
||||
def put(%Group{shapes: shapes}, shape), do: shapes |> MapSet.put(shape) |> init
|
||||
end
|
31
lib/vivid/rasterize/group.ex
Normal file
31
lib/vivid/rasterize/group.ex
Normal file
|
@ -0,0 +1,31 @@
|
|||
defimpl Vivid.Rasterize, for: Vivid.Group do
|
||||
alias Vivid.{Group, Rasterize}
|
||||
|
||||
@moduledoc """
|
||||
Rasterizes the Group into a sequence of points.
|
||||
"""
|
||||
|
||||
@doc """
|
||||
Convert Group into a set of points for display.
|
||||
|
||||
## Example
|
||||
|
||||
iex> path = Vivid.Path.init([Vivid.Point.init(1,1), Vivid.Point.init(1,3), Vivid.Point.init(3,3), Vivid.Point.init(3,1)])
|
||||
...> Vivid.Group.init([path])
|
||||
...> |> Vivid.Rasterize.rasterize
|
||||
MapSet.new([
|
||||
%Vivid.Point{x: 1, y: 1},
|
||||
%Vivid.Point{x: 1, y: 2},
|
||||
%Vivid.Point{x: 1, y: 3},
|
||||
%Vivid.Point{x: 2, y: 3},
|
||||
%Vivid.Point{x: 3, y: 1},
|
||||
%Vivid.Point{x: 3, y: 2},
|
||||
%Vivid.Point{x: 3, y: 3}
|
||||
])
|
||||
"""
|
||||
def rasterize(%Group{shapes: shapes}) do
|
||||
Enum.reduce(shapes, MapSet.new, fn(shape, acc) ->
|
||||
MapSet.union(acc, Rasterize.rasterize(shape))
|
||||
end)
|
||||
end
|
||||
end
|
4
test/collectable/vivid/group_test.exs
Normal file
4
test/collectable/vivid/group_test.exs
Normal file
|
@ -0,0 +1,4 @@
|
|||
defmodule Collectable.Vivid.GroupTest do
|
||||
use ExUnit.Case
|
||||
doctest Collectable.Vivid.Group
|
||||
end
|
4
test/enumerable/vivid/group_test.exs
Normal file
4
test/enumerable/vivid/group_test.exs
Normal file
|
@ -0,0 +1,4 @@
|
|||
defmodule Enumerable.Vivid.GroupTest do
|
||||
use ExUnit.Case
|
||||
doctest Enumerable.Vivid.Group
|
||||
end
|
4
test/vivid/group_test.exs
Normal file
4
test/vivid/group_test.exs
Normal file
|
@ -0,0 +1,4 @@
|
|||
defmodule Vivid.GroupTest do
|
||||
use ExUnit.Case
|
||||
doctest Vivid.Group
|
||||
end
|
4
test/vivid/rasterize/group_test.exs
Normal file
4
test/vivid/rasterize/group_test.exs
Normal file
|
@ -0,0 +1,4 @@
|
|||
defmodule Vivid.Rasterize.GroupTest do
|
||||
use ExUnit.Case
|
||||
doctest Vivid.Rasterize.Vivid.Group
|
||||
end
|
Loading…
Reference in a new issue