Current section
Files
Jump to
Current section
Files
lib/topo/util.ex
defmodule Topo.Util do
@moduledoc false
def cross({ax, ay}, {bx, by}, {cx, cy}) do
Vector.cross({ax - cx, ay - cy}, {bx - cx, by - cy})
|> Vector.component(:z)
end
def collinear(a, b, c) do
cross(a, b, c) == 0
end
def between({ax, ay}, {bx, by}, {px, py}) when ax == bx and ay == by and (px != ax and py != ay), do: false
def between({ax, ay}, {bx, by}, {_, py}) when ax == bx and ay != by, do: ((ay <= py) && (py <= by)) || ((ay >= py) && (py >= by))
def between({ax, _}, {bx, _}, {px, _}), do: ((ax <= px) && (px <= bx)) || ((ax >= px) && (px >= bx))
def assert_no_collinear([a, b, c | rest]) do
cond do
collinear(a, c, b) && between(a, c, b) -> assert_no_collinear([a, c | rest])
true -> [a] ++ assert_no_collinear([b, c | rest])
end
end
def assert_no_collinear(ring), do: ring
def midpoint(a, b) do
Vector.divide(Vector.add(a, b), 2)
end
def any_edge_pair_not?(a, b, rel) do
do_any_edge_pair? a, b, fn a1, a2, b1, b2 ->
elem(SegSeg.intersection(a1, a2, b1, b2), 1) !== rel
end
end
def any_edge_pair?(a, b, rel) do
do_any_edge_pair? a, b, fn a1, a2, b1, b2 ->
elem(SegSeg.intersection(a1, a2, b1, b2), 1) === rel
end
end
defp do_any_edge_pair?(_, [_], _), do: false
defp do_any_edge_pair?(a, [b1, b2 | rest], fun) do
any_edge?(a, [b1, b2], fun) || do_any_edge_pair?(a, [b2 | rest], fun)
end
defp any_edge?([_], _, _), do: false
defp any_edge?([a1, a2 | rest], [b1, b2], fun) do
fun.(a1, a2, b1, b2) || any_edge?([a2 | rest], [b1, b2], fun)
end
end