116 lines
4.7 KiB
Lua
116 lines
4.7 KiB
Lua
-- A chain class. If loop is true then this is the same as a polygon, otherwise its a collection of connected lines (an open polygon).
|
|
-- Implements every function that Polygon does.
|
|
Chain = Object:extend()
|
|
Chain:implement(Polygon)
|
|
function Chain:init(loop, vertices)
|
|
self.loop = loop
|
|
self.vertices = vertices
|
|
self:get_size()
|
|
self:get_bounds()
|
|
self:get_centroid()
|
|
end
|
|
|
|
|
|
-- Draws the chain of lines with the given color and width.
|
|
function Chain:draw(color, line_width)
|
|
if self.loop and not line_width then
|
|
graphics.polygon(self.vertices, color, line_width)
|
|
else
|
|
for i = 1, #self.vertices-2, 2 do
|
|
graphics.line(self.vertices[i], self.vertices[i+1], self.vertices[i+2], self.vertices[i+3], color, line_width)
|
|
if self.loop and i == #self.vertices-2 then
|
|
graphics.line(self.vertices[i], self.vertices[i+1], self.vertices[1], self.vertices[2], color, line_width)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
-- If loop is true, returns true if the point is inside the polygon.
|
|
-- If loop is false, returns true if the point lies on any of the chain's lines.
|
|
-- colliding = chain:is_colliding_with_point(x, y)
|
|
function Chain:is_colliding_with_point(x, y)
|
|
if self.loop then
|
|
return mlib.polygon.checkPoint(x, y, self.vertices)
|
|
else
|
|
for i = 1, #self.vertices-2, 2 do
|
|
if mlib.segment.checkPoint(x, y, self.vertices[i], self.vertices[i+1], self.vertices[i+2], self.vertices[i+3]) then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
-- If loop is true, returns true if the line is colliding with the polygon.
|
|
-- If loop is false, returns true if the line is colliding with any of the chain's lines.
|
|
-- colliding = chain:is_colliding_with_line(line)
|
|
function Chain:is_colliding_with_line(line)
|
|
if self.loop then
|
|
return mlib.polygon.isSegmentInside(line.x1, line.y1, line.x2, line.y2, self.vertices)
|
|
else
|
|
for i = 1, #self.vertices-2, 2 do
|
|
if mlib.segment.getIntersection(self.vertices[i], self.vertices[i+1], self.vertices[i+2], self.vertices[i+3], line.x1, line.y1, line.x2, line.y2) then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
-- If loop is true for both chains, returns true if the polygon is colliding with the polygon.
|
|
-- If loop is false for both chains, returns true if any of the lines of one chain are colliding with any of the lines of the other chain.
|
|
-- If one is true and the other is false, returns true if the one that's a polygon is colliding with any of the lines of the one that is a chain.
|
|
-- colliding = chain:is_colliding_with_chain(other_chain)
|
|
function Chain:is_colliding_with_chain(chain)
|
|
if self.loop and chain.loop then
|
|
return mlib.polygon.isPolygonInside(self.vertices, chain.vertices) or mlib.polygon.isPolygonInside(chain.vertices, self.vertices)
|
|
elseif self.loop and not chain.loop then
|
|
return chain:is_colliding_with_polygon(self)
|
|
elseif not self.loop and chain.loop then
|
|
return self:is_colliding_with_polygon(chain)
|
|
else
|
|
for i = 1, #self.vertices-2, 2 do
|
|
for j = 1, #chain.vertices-2, 2 do
|
|
if mlib.segment.getIntersection(self.vertices[i], self.vertices[i+1], self.vertices[i+2], self.vertices[i+3], chain.vertices[j], chain.vertices[j+1], chain.vertices[j+2], chain.vertices[j+3]) then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
-- If loop is true, returns true if the circle is colliding with the polygon.
|
|
-- If loop is false, returns true if the circle is colliding with any of the chain's lines.
|
|
-- colliding = chain:is_colliding_with_circle(circle)
|
|
function Chain:is_colliding_with_circle(circle)
|
|
if self.loop then
|
|
return mlib.polygon.isCircleCompletelyInside(circle.x, circle.y, circle.rs, self.vertices) or
|
|
mlib.circle.isPolygonCompletelyInside(circle.x, circle.y, circle.rs, self.vertices) or
|
|
mlib.polygon.getCircleIntersection(circle.x, circle.y, circle.rs, self.vertices)
|
|
else
|
|
for i = 1, #self.vertices-2, 2 do
|
|
if mlib.circle.getSegmentIntersection(circle.x, circle.y, circle.rs, self.vertices[i], self.vertices[i+1], self.vertices[i+2], self.vertices[i+3]) then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
-- If loop is true, returns true if the polygon is colliding with the polygon.
|
|
-- If loop is false, returns true if the polygon is colliding with any of the chain's lines.
|
|
-- colliding = chain:is_colliding_with_polygon(polygon)
|
|
function Chain:is_colliding_with_polygon(polygon)
|
|
if self.loop then
|
|
return mlib.polygon.isPolygonInside(self.vertices, polygon.vertices) or mlib.polygon.isPolygonInside(polygon.vertices, self.vertices)
|
|
else
|
|
for i = 1, #self.vertices-2, 2 do
|
|
if mlib.polygon.getSegmentIntersection(self.vertices[i], self.vertices[i+1], self.vertices[i+2], self.vertices[i+3], polygon.vertices) then
|
|
return true
|
|
end
|
|
end
|
|
end
|
|
end
|