Packages

A Ray Casting algorithm for Elixir.

Current section

Files

Jump to
ex_ray_casting lib ray_casting.ex
Raw

lib/ray_casting.ex

defmodule RayCasting do
@moduledoc """
A Ray Casting algorithm for Elixir.
This module contains the Application that you can use to perform
solutions for some problems like:
- To know if a coordinate exists inside a polygon
- To know if a coordinate exists outside a polygon
"""
@doc """
Ray Casting
"""
def rayCasting(path, point) do
crossings = 0
{x, _y} = Enum.map_reduce(path, 0, fn _item, acc ->
a = Enum.at(path, acc)
b = Enum.at(path, acc + 1)
if (a == List.last(path)) do
b = Enum.at(path, 0)
end
if rayCrossesSegment(point, a, b) do
crossings = crossings + 1
end
acc = acc + 1
{crossings, acc}
end)
crossings = List.last(x)
rem(crossings, 2) == 1
end
defp rayCrossesSegment(point, a, b) do
px = point.lng
py = point.lat
ax = a.lng
ay = a.lat
bx = b.lng
by = b.lat
if (ay > by) do
ax = b.lng
ay = b.lat
bx = a.lng
by = a.lat
end
if (px < 0), do: px = px + 360
if (ax < 0), do: ax = ax + 360
if (bx < 0), do: bx = bx + 360
if (py == ay || py == by), do: py = py + 0.00000001
if (ax != bx) do
red = ((by - ay) / (bx - ax))
else
red = Infinity
end
if (ax != px) do
blue = ((py - ay) / (px - ax))
else
blue = Infinity
end
cond do
((py > by || py < ay) || (px > max(ax, bx))) -> false
(px < min(ax, bx)) -> true
blue >= red -> true
true -> true
end
end
end