Packages

The geom project gives access to a variety of geometric shapes and the algorithms necessary for their manipulation.

Current section

Files

Jump to
geom lib shape face.ex
Raw

lib/shape/face.ex

defmodule Geom.Shape.Face do
@moduledoc """
The face of a polygon represented by its 3 vertices.
"""
alias Geom.Shape.Face
alias Geom.Shape.Vector
@type t :: %Face{v1: Vector.t, v2: Vector.t, v3: Vector.t}
@derive [Poison.Encoder]
defstruct v1: nil, v2: nil, v3: nil
@doc "Returns true if the vector is one of the face's vertices, false otherwise."
@spec is_own_vertex?(Face.t, Vector.t) :: boolean
def is_own_vertex?(%Face{v1: v1, v2: v2, v3: v3}, v0),
do: v0 == v1 or v0 == v2 or v0 == v3
@doc "Returns true if the vector is inside the face, false otherwise."
@spec contains?(Face.t, Vector.t) :: boolean
def contains?(%Face{v1: v1, v2: v2, v3: v3} = face, v0) do
if is_own_vertex?(face, v0) do
true
else
# Compute vectors
vec1 = Vector.sub(v3, v1)
vec2 = Vector.sub(v2, v1)
vec3 = Vector.sub(v0, v1)
# Compute dot products
dot00 = Vector.dot(vec1, vec1)
dot01 = Vector.dot(vec1, vec2)
dot02 = Vector.dot(vec1, vec3)
dot11 = Vector.dot(vec2, vec2)
dot12 = Vector.dot(vec2, vec3)
# Compute barycentric coordinates
invDenom = 1 / (dot00 * dot11 - dot01 * dot01)
u = (dot11 * dot02 - dot01 * dot12) * invDenom
v = (dot00 * dot12 - dot01 * dot02) * invDenom
# Check if point is in triangle
(u >= 0) && (v >= 0) && (u + v < 1)
end
end
end