Skip to content

Commit

Permalink
Implement some transformations
Browse files Browse the repository at this point in the history
  • Loading branch information
Ju Liu committed Mar 5, 2019
1 parent cd0507d commit e259ba4
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 9 deletions.
48 changes: 48 additions & 0 deletions lib/box.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,52 @@ defmodule Box do
def dimensions(%Box{a: a, b: b, c: c}) do
{a.x + b.x, a.y + c.y}
end

def turn(%Box{a: a, b: b, c: c}) do
%Box{a: Vector.add(a, b), b: c, c: Vector.neg(b)}
end

def flip(%Box{a: a, b: b, c: c}) do
%Box{a: Vector.add(a, c), b: b, c: Vector.neg(c)}
end

def split_horizontally(factor, %Box{a: a, b: b, c: c}) do
above_ratio = factor

below_ratio = 1 - above_ratio

above = %Box{
a: Vector.add(a, Vector.scale(below_ratio, c)),
b: b,
c: Vector.scale(above_ratio, c)
}

below = %Box{
a: a,
b: b,
c: Vector.scale(below_ratio, c)
}

{above, below}
end

def split_vertically(factor, %Box{a: a, b: b, c: c}) do
left_ratio = factor

right_ratio = 1 - left_ratio

left = %Box{
a: a,
b: Vector.scale(left_ratio, b),
c: c
}

right = %Box{
a: Vector.add(a, Vector.scale(left_ratio, b)),
b: Vector.scale(right_ratio, b),
c: c
}

{left, right}
end
end
2 changes: 1 addition & 1 deletion lib/shape.ex → lib/figure.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
defmodule Shape do
defmodule Figure do
def george do
pts1 = [
%Vector{x: 0.00, y: 0.55},
Expand Down
71 changes: 71 additions & 0 deletions lib/picture.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
defmodule Picture do
# A picture is a lambda function that takes a box and produces a list
# of {shape, style} tuples. Think of it as something like this:
#
# picture =
# fn box ->
# render_stuff_with box
# end
#
# The nice thing about this idea is that we can transform the picture
# by just transforming the box. For example, if we want to turn the picture
# we could just do something like:
#
# turned_picture =
# fn box ->
# box
# |> Box.turn
# |> picture.()
# end

def turn(picture) do
fn box ->
box
|> Box.turn()
|> picture.()
end
end

def flip(picture) do
fn box ->
box
|> Box.flip()
|> picture.()
end
end

def above_ratio(m, n, p1, p2) do
fn box ->
factor = m / (m + n)

{box_above, box_below} = Box.split_horizontally(factor, box)

p1.(box_above) ++ p2.(box_below)
end
end

def above(p1, p2) do
above_ratio(1, 1, p1, p2)
end

def beside_ratio(m, n, p1, p2) do
fn box ->
factor = m / (m + n)

{box_left, box_right} = Box.split_vertically(factor, box)

p1.(box_left) ++ p2.(box_right)
end
end

def beside(p1, p2) do
beside_ratio(1, 1, p1, p2)
end

def quartet(p1, p2, p3, p4) do
above(
beside(p1, p2),
beside(p3, p4)
)
end
end
38 changes: 30 additions & 8 deletions lib/scenes/home.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,41 @@ defmodule ScenicEscher.Scene.Home do
fn g ->
box = %Box{
a: %Vector{x: 75.0, y: 75.0},
b: %Vector{x: 250.0, y: 0.0},
c: %Vector{x: 0.0, y: 250.0}
b: %Vector{x: 500.0, y: 0.0},
c: %Vector{x: 0.0, y: 500.0}
}

{width, height} = Box.dimensions(box)

shapes = Shape.george
george = Fitting.create_picture(Figure.george())

picture = Fitting.create_picture(shapes)
atom =
Picture.above(
george,
george |> Picture.turn() |> Picture.turn()
)

molecule =
Picture.beside(
atom,
atom |> Picture.flip()
)

simple =
Picture.quartet(
molecule,
molecule,
molecule,
molecule
)

picture =
Picture.quartet(
simple,
simple,
simple,
simple
)

paths =
box
Expand All @@ -42,10 +68,6 @@ defmodule ScenicEscher.Scene.Home do
translate: {20, 20}
)

# ============================================================================
# setup

# --------------------------------------------------------
def init(_, _) do
push_graph(@graph)
{:ok, @graph}
Expand Down

0 comments on commit e259ba4

Please sign in to comment.