Scurry.Geo (Scurry v3.0.0)
View SourceGeometry functions related to lines relevant for 2D map pathfinding.
Summary
Types
A vector is represented as a tuple {x, y}
, it's x and y components, both number/0
. These are used for vector math in Scurry.Vector
and as 2D points in Scurry.Polygon
and Scurry.PolygonMap
.
Functions
Get the distance from a point to a line/segment.
Get the distance squared from point
to line
.
Check if two lines intersect
Determine if, where and how two lines intersect.
Types
A line is represented by two vertices of type vector/0
@type polygon() :: [vector()]
A polygon is represented by a list of vector/0
, each being a tuple of {x, y}
coordinates, both number/0
. To be properly defined, the vertices of the polygon must be non-closed and clockwise.
A vector is represented as a tuple {x, y}
, it's x and y components, both number/0
. These are used for vector math in Scurry.Vector
and as 2D points in Scurry.Polygon
and Scurry.PolygonMap
.
Functions
Get the distance from a point to a line/segment.
This is the square root of distance_squared/2
.
Params
line
(line/0
) the line to compute the distance to.point
(vector/0
) the point to compute the distance toline
for.
Returns
The distance beween the given point
and line
.
Examples
iex> Geo.distance_to_segment({{2, 0}, {2, 2}}, {0, 1})
2.0
Get the distance squared from point
to line
.
Params
line
(line/0
) the line to compute the distance squared to.point
(vector/0
) the point to compute the distance squared toline
for.
Returns
The square of the distance beween the given point
and line
.
Examples
iex> Geo.distance_to_segment_squared({{2, 0}, {2, 2}}, {0, 1})
4.0
Check if two lines intersect
This is a simpler version of line_segment_intersection/2
, which is typically
a better choice since it handles endpoints and segment overlap too.
This is kept/provided for historic purposes.
Params
line1
(line/0
) a line to check for intersection withline2
(line/0
) a line to check if it intersects withline1
.
Returns
true
if they intersect, false
otherwise.
Note
This doesn't handle segment overlap or points touching. Use
line_segment_intersection/2
instead for that level of detail.
@spec line_segment_intersection(line(), line()) :: :none | :parallel | :on_segment | {:point_intersection, vector()} | {:intersection, vector()}
Determine if, where and how two lines intersect.
This function computes whether two lines intersect (cross each other) touch on an endpoint or are on top of each other.
Params
line1
(line/0
) a line segmentline2
(line/0
) a line segment to check where and how it intersects withline1
.
Returns
:none
no intersection.:parallel
the lines are parallel and do not intersect.:on_segment
one line is on the other. They may extend past each other's endpoints.{:point_intersection, vector}
either line has an endpoint on the other line. This means they just touch at the returned vector.{:intersection, vector}
the lines intersect at the returned vector.
Examples
iex> Geo.line_segment_intersection({{1, 2}, {4, 2}}, {{2, 0}, {3, 0}})
:parallel
iex> Geo.line_segment_intersection({{1, 2}, {4, 2}}, {{2, 2}, {3, 2}})
:on_segment
iex> Geo.line_segment_intersection({{1, 2}, {4, 2}}, {{2, 2}, {5, 2}})
:on_segment
iex> Geo.line_segment_intersection({{1, 2}, {4, 2}}, {{2, 0}, {2, 1}})
:none
iex> Geo.line_segment_intersection({{1, 2}, {4, 2}}, {{2, 0}, {2, 2}})
{:point_intersection, {2.0, 2.0}}
iex> Geo.line_segment_intersection({{1, 2}, {4, 2}}, {{2, 0}, {2, 3}})
{:intersection, {2.0, 2.0}}