HC.polygon

polygon = require 'HC.polygon'

Polygon class with some handy algorithms. Does not provide collision detection - this functionality is provided by newPolygonShape() instead.

class Polygon(x1, y1, ..., xn, yn)
Arguments:
  • x1,y1, ..., xn,yn (numbers) – The corners of the polygon. At least three corners are needed.
Returns:

The polygon object.

Construct a polygon.

At least three points that are not collinear (i.e. not lying on a straight line) are needed to construct the polygon. If there are collinear points, these points will be removed. The shape of the polygon is not changed.

Note

The syntax depends on used class system. The shown syntax works when using the bundled hump.class or slither.

Example:

Polygon = require 'HC.polygon'
poly = Polygon(10,10, 40,50, 70,10, 40,30)
Polygon:unpack()
Returns:x1,y1, ..., xn,yn - The vertices of the polygon.

Get the polygon’s vertices. Useful for drawing with love.graphics.polygon().

Example:

love.graphics.draw('line', poly:unpack())
Polygon:clone()
Returns:A copy of the polygon.

Get a copy of the polygon.

Note

Since Lua uses references when simply assigning an existing polygon to a variable, unexpected things can happen when operating on the variable. Consider this code:

p1 = Polygon(10,10, 40,50, 70,10, 40,30)
p2 = p1         -- p2 is a reference
p3 = p1:clone() -- p3 is a clone
p2:rotate(math.pi) -- p1 will be rotated, too!
p3:rotate(-math.pi) -- only p3 will be rotated

Example:

copy = poly:clone()
copy:move(10,20)
Polygon:bbox()
Returns:x1, y1, x2, y2 - Corners of the counding box.

Get axis aligned bounding box. x1, y1 defines the upper left corner, while x2, y2 define the lower right corner.

Example:

x1,y1,x2,y2 = poly:bbox()
-- draw bounding box
love.graphics.rectangle('line', x1,y2, x2-x1, y2-y1)
Polygon:isConvex()
Returns:true if the polygon is convex, false otherwise.

Test if a polygon is convex, i.e. a line line between any two points inside the polygon will lie in the interior of the polygon.

Example:

-- split into convex sub polygons
if not poly:isConvex() then
    list = poly:splitConvex()
else
    list = {poly:clone()}
end
Polygon:move(x, y)
Arguments:
  • x, y (numbers) – Coordinates of the direction to move.

Move a polygon in a direction..

Example:

poly:move(10,-5) -- move 10 units right and 5 units up
Polygon:rotate(angle[, cx, cy])
Arguments:
  • angle (number) – The angle to rotate in radians.
  • cx, cy (numbers) – The rotation center (optional).

Rotate the polygon. You can define a rotation center. If it is omitted, the polygon will be rotated around it’s centroid.

Example:

p1:rotate(math.pi/2)          -- rotate p1 by 90° around it's center
p2:rotate(math.pi/4, 100,100) -- rotate p2 by 45° around the point 100,100
Polygon:triangulate()
Returns:table of Polygons: Triangles that the polygon is composed of.

Split the polygon into triangles.

Example:

triangles = poly:triangulate()
for i,triangle in ipairs(triangles) do
    triangles.move(math.random(5,10), math.random(5,10))
end
Polygon:splitConvex()
Returns:table of Polygons: Convex polygons that form the original polygon.

Split the polygon into convex sub polygons.

Example:

convex = concave_polygon:splitConvex()
function love.draw()
    for i,poly in ipairs(convex) do
        love.graphics.polygon('fill', poly:unpack())
    end
end
Polygon:mergedWith(other)
Arguments:
  • other (Polygon) – The polygon to merge with.
Returns:

The merged polygon, or nil if the two polygons don’t share an edge.

Create a merged polygon of two polygons if, and only if the two polygons share one complete edge. If the polygons share more than one edge, the result may be erroneous.

This function does not change either polygon, but rather creates a new one.

Example:

merged = p1:mergedWith(p2)
Polygon:contains(x, y)
Arguments:
  • x, y (numbers) – Point to test.
Returns:

true if x,y lies in the interior of the polygon.

Test if the polygon contains a given point.

Example:

if button:contains(love.mouse.getPosition()) then
    button:setHovered(true)
end
Polygon:intersectionsWithRay(x, y, dx, dy)
Arguments:
  • x, y (numbers) – Starting point of the ray.
  • dx, dy (numbers) – Direction of the ray.
Returns:

Table of ray parameters.

Test if the polygon intersects the given ray. The ray parameters of the intersections are returned as a table. The position of the intersections can be computed as (x,y) + ray_parameter * (dx, dy).

Polygon:intersectsRay(x, y, dx, dy)
Arguments:
  • x, y (numbers) – Starting point of the ray.
  • dx, dy (numbers) – Direction of the ray.
Returns:

intersects, ray_parameter - intersection indicator and ray paremter.

Test if the polygon intersects a ray. If the shape intersects the ray, the point of intersection can be computed by (x,y) + ray_parameter * (dx, dy).

Example:

if poly:intersectsRay(400,300, dx,dy) then
    love.graphics.setLine(2) -- highlight polygon
end