collision v0.3.1 Collision.Polygon

A general polygon is defined by its vertices; from these we can calculate the edges, centroid, rotation angles, and whether the polygon is concave or convex.

Summary

Functions

Find the midpoint of a polygon

In a convex polygon, all internal angles are < 180 degrees

Takes a list of ordered vertices and returns the polygon they describe

Construct a regular polygon

Rotate a polygon, rotation angle should be radians

Rotate a regular polygon using rotation angle in degrees

From an angle and a vertex, generates a function to rotate a vertex around a point

Translate a polygon’s vertices

Types

t :: %Collision.Polygon{convex: term, edges: [Collision.Polygon.Edge.t], vertices: term}

Functions

centroid(polygon)

Find the midpoint of a polygon.

Returns: %Vertex{}

Example

iex> p = Polygon.gen_regular_polygon(4, 4, 0, {0, 0})
iex> Polygon.centroid(p)
%Vertex{x: 0.0, y: 0.0}
convex?(edges)

Specs

In a convex polygon, all internal angles are < 180 degrees.

Returns: true | false

Example

iex> p = Polygon.from_vertices([ ...> %Vertex{x: 2, y: 2}, %Vertex{x: -2, y: 2}, ...> %Vertex{x: -2, y: -2}, %Vertex{x: 2, y: -2} ...> ]) iex> Polygon.convex?(p) true

iex> p = Polygon.from_vertices([%Vertex{x: 2, y: 2}, %Vertex{x: 0, y: 0}, ...> %Vertex{x: -2, y: 2}, %Vertex{x: -2, y: -2}, %Vertex{x: 2, y: -2}]) iex> Polygon.convex?(p) false

from_vertices(vertices)

Specs

from_vertices([Collision.Polygon.Vertex.t]) :: t

Takes a list of ordered vertices and returns the polygon they describe.

Returns: %Polygon{}

Example

iex> Polygon.from_vertices([
...>   %Vertex{x: 4, y: 4}, %Vertex{x: 0, y: 4},
...>   %Vertex{x: 0, y: 0}, %Vertex{x: 4, y: 0}])
%Polygon{vertices: [
  %Vertex{x: 4, y: 4}, %Vertex{x: 0, y: 4},
  %Vertex{x: 0, y: 0}, %Vertex{x: 4, y: 0}
], edges: [
  %Edge{length: 4.0, next: %Vertex{x: 0, y: 4}, point: %Vertex{x: 4, y: 4}},
  %Edge{length: 4.0, next: %Vertex{x: 0, y: 0}, point: %Vertex{x: 0, y: 4}},
  %Edge{length: 4.0, next: %Vertex{x: 4, y: 0}, point: %Vertex{x: 0, y: 0}},
  %Edge{length: 4.0, next: %Vertex{x: 4, y: 4}, point: %Vertex{x: 4, y: 0}}
]}
gen_regular_polygon(s, r, a, arg)
gen_regular_polygon(s, r, a, arg, arg5)

Specs

gen_regular_polygon(integer, number, number, {number, number}, atom) :: Collision.Polygon.t

Construct a regular polygon.

A polygon must have at least three sides.

Examples

iex> Polygon.gen_regular_polygon(4, 4, 0, {0, 0})
%Polygon{vertices: [
  %Vertex{x: 4.0, y: 0.0}, %Vertex{x: 0.0, y: 4.0},
  %Vertex{x: -4.0, y: 0.0}, %Vertex{x: 0.0, y: -4.0}
], edges: [
  %Edge{length: 5.656854249492381, next: %Vertex{x: 0.0, y: 4.0}, point: %Vertex{x: 4.0, y: 0.0}},
  %Edge{length: 5.656854249492381, next: %Vertex{x: -4.0, y: 0.0}, point: %Vertex{x: 0.0, y: 4.0}},
  %Edge{length: 5.656854249492381, next: %Vertex{x: 0.0, y: -4.0}, point: %Vertex{x: -4.0, y: 0.0}},
  %Edge{length: 5.656854249492381, next: %Vertex{x: 4.0, y: 0.0}, point: %Vertex{x: 0.0, y: -4.0}}
]}

iex> Polygon.gen_regular_polygon(3, 2, 0, {0, 0})
%Polygon{edges: [
  %Edge{length: 3.4641012113533867, next: %Vertex{x: -1.0, y: 1.73205}, point: %Vertex{x: 2.0, y: 0.0}},
  %Edge{length: 3.4641, next: %Vertex{x: -1.0, y: -1.73205}, point: %Vertex{x: -1.0, y: 1.73205}},
  %Edge{length: 3.4641012113533867, next: %Vertex{x: 2.0, y: 0.0}, point: %Vertex{x: -1.0, y: -1.73205}}
], vertices: [
  %Vertex{x: 2.0, y: 0.0},
  %Vertex{x: -1.0, y: 1.73205},
  %Vertex{x: -1.0, y: -1.73205}
]}
rotate(polygon, radians, rotation_point \\ %{x: 0, y: 0})

Specs

rotate(Collision.Polygon.t, radians, %{x: number, y: number}) :: Collision.Polygon.t

Rotate a polygon, rotation angle should be radians.

The rotation point is the point around which the polygon is rotated. It defaults to the origin, so without specifying the polygon’s centroid as the rotation point, it will not be an in-place rotation.

Returns: %Polygon{}

Example

iex> p = Polygon.from_vertices([
...>       %Vertex{x: 2, y: 2}, %Vertex{x: -2, y: 2},
...>       %Vertex{x: -2, y: -2}, %Vertex{x: 2, y: -2}
...>     ])
iex> Polygon.rotate(p, :math.pi)
%Polygon{edges: [
%Edge{length: 4.0, next: %Vertex{x: 2.0, y: -2.0}, point: %Vertex{x: -2.0, y: -2.0}},
%Edge{length: 4.0, next: %Vertex{x: 2.0, y: 2.0}, point: %Vertex{x: 2.0, y: -2.0}},
  %Edge{length: 4.0, next: %Vertex{x: -2.0, y: 2.0}, point: %Vertex{x: 2.0, y: 2.0}},
  %Edge{length: 4.0, next: %Vertex{x: -2.0, y: -2.0}, point: %Vertex{x: -2.0, y: 2.0}}
], vertices: [
  %Vertex{x: -2.0, y: -2.0}, %Vertex{x: 2.0, y: -2.0},
  %Vertex{x: 2.0, y: 2.0}, %Vertex{x: -2.0, y: 2.0}
]}
rotate_degrees(polygon, degrees, point \\ %{x: 0, y: 0})

Specs

rotate_degrees(Collision.Polygon.t, degrees, %{x: number, y: number}) :: Collision.Polygon.t

Rotate a regular polygon using rotation angle in degrees.

Returns: %Polygon{}

Example

iex> p = Polygon.from_vertices([
...>       %Vertex{x: 2, y: 2}, %Vertex{x: -2, y: 2},
...>       %Vertex{x: -2, y: -2}, %Vertex{x: 2, y: -2}
...>     ])
iex> Polygon.rotate_degrees(p, 90)
%Polygon{edges: [
  %Edge{length: 4.0, next: %Vertex{x: -2.0, y: -2.0}, point: %Vertex{x: -2.0, y: 2.0}},
  %Edge{length: 4.0, next: %Vertex{x: 2.0, y: -2.0}, point: %Vertex{x: -2.0, y: -2.0}},
  %Edge{length: 4.0, next: %Vertex{x: 2.0, y: 2.0}, point: %Vertex{x: 2.0, y: -2.0}},
  %Edge{length: 4.0, next: %Vertex{x: -2.0, y: 2.0}, point: %Vertex{x: 2.0, y: 2.0}}
], vertices: [
  %Vertex{x: -2.0, y: 2.0}, %Vertex{x: -2.0, y: -2.0},
  %Vertex{x: 2.0, y: -2.0}, %Vertex{x: 2.0, y: 2.0}
]}
rotate_vertex(radians, rotation_point)

From an angle and a vertex, generates a function to rotate a vertex around a point.

Returns: (%Vertex{} -> %Vertex{})

Example

iex> rotation = Polygon.rotate_vertex(:math.pi, %{x: 0, y: 0})
iex> rotation.(%Vertex{x: 5, y: 0})
%Vertex{x: -5.0, y: 0.0}
translate(polygon, translation_vector)

Specs

translate(Collision.Polygon.t, %{x: number, y: number}) :: Collision.Polygon.t

Translate a polygon’s vertices.

Returns: %Polygon{}

Example

iex> p = Polygon.gen_regular_polygon(4, 4, 0, {0, 0})
iex> Polygon.translate(p, %{x: 2, y: 2})
%Polygon{vertices: [
  %Vertex{x: 6.0, y: 2.0}, %Vertex{x: 2.0, y: 6.0},
  %Vertex{x: -2.0, y: 2.0}, %Vertex{x: 2.0, y: -2.0}
], edges: [
  %Edge{length: 5.656854249492381, next: %Vertex{x: 2.0, y: 6.0}, point: %Vertex{x: 6.0, y: 2.0}},
  %Edge{length: 5.656854249492381, next: %Vertex{x: -2.0, y: 2.0}, point: %Vertex{x: 2.0, y: 6.0}},
  %Edge{length: 5.656854249492381, next: %Vertex{x: 2.0, y: -2.0}, point: %Vertex{x: -2.0, y: 2.0}},
  %Edge{length: 5.656854249492381, next: %Vertex{x: 6.0, y: 2.0}, point: %Vertex{x: 2.0, y: -2.0}}
]}