103 lines
2.5 KiB
Lua
103 lines
2.5 KiB
Lua
local point = require("slick.geometry.point")
|
|
local slickmath = require("slick.util.slickmath")
|
|
|
|
--- @class slick.geometry.rectangle
|
|
--- @field topLeft slick.geometry.point
|
|
--- @field bottomRight slick.geometry.point
|
|
local rectangle = {}
|
|
local metatable = {
|
|
__index = rectangle
|
|
}
|
|
|
|
--- @param x1 number?
|
|
--- @param y1 number?
|
|
--- @param x2 number?
|
|
--- @param y2 number?
|
|
--- @return slick.geometry.rectangle
|
|
function rectangle.new(x1, y1, x2, y2)
|
|
local result = setmetatable({ topLeft = point.new(), bottomRight = point.new() }, metatable)
|
|
result:init(x1, y1, x2, y2)
|
|
|
|
return result
|
|
end
|
|
|
|
--- @param x1 number?
|
|
--- @param y1 number?
|
|
--- @param x2 number?
|
|
--- @param y2 number?
|
|
function rectangle:init(x1, y1, x2, y2)
|
|
x1 = x1 or 0
|
|
x2 = x2 or x1
|
|
y1 = y1 or 0
|
|
y2 = y2 or y1
|
|
|
|
self.topLeft:init(math.min(x1, x2), math.min(y1, y2))
|
|
self.bottomRight:init(math.max(x1, x2), math.max(y1, y2))
|
|
end
|
|
|
|
function rectangle:left()
|
|
return self.topLeft.x
|
|
end
|
|
|
|
function rectangle:right()
|
|
return self.bottomRight.x
|
|
end
|
|
|
|
function rectangle:top()
|
|
return self.topLeft.y
|
|
end
|
|
|
|
function rectangle:bottom()
|
|
return self.bottomRight.y
|
|
end
|
|
|
|
function rectangle:width()
|
|
return self:right() - self:left()
|
|
end
|
|
|
|
function rectangle:height()
|
|
return self:bottom() - self:top()
|
|
end
|
|
|
|
--- @param x number
|
|
--- @param y number
|
|
function rectangle:expand(x, y)
|
|
self.topLeft.x = math.min(self.topLeft.x, x)
|
|
self.topLeft.y = math.min(self.topLeft.y, y)
|
|
self.bottomRight.x = math.max(self.bottomRight.x, x)
|
|
self.bottomRight.y = math.max(self.bottomRight.y, y)
|
|
end
|
|
|
|
---@param x number
|
|
---@param y number
|
|
function rectangle:move(x, y)
|
|
self.topLeft.x = self.topLeft.x + x
|
|
self.topLeft.y = self.topLeft.y + y
|
|
self.bottomRight.x = self.bottomRight.x + x
|
|
self.bottomRight.y = self.bottomRight.y + y
|
|
end
|
|
|
|
--- @param x number
|
|
--- @param y number
|
|
function rectangle:sweep(x, y)
|
|
self:expand(x - self:width(), y - self:height())
|
|
self:expand(x + self:width(), y + self:height())
|
|
end
|
|
|
|
--- @param other slick.geometry.rectangle
|
|
--- @return boolean
|
|
function rectangle:overlaps(other)
|
|
return self:left() <= other:right() and self:right() >= other:left() and
|
|
self:top() <= other:bottom() and self:bottom() >= other:top()
|
|
end
|
|
|
|
--- @param p slick.geometry.point
|
|
--- @param E number?
|
|
--- @return boolean
|
|
function rectangle:inside(p, E)
|
|
E = E or 0
|
|
return slickmath.withinRange(p.x, self:left(), self:right(), E) and slickmath.withinRange(p.y, self:top(), self:bottom(), E)
|
|
end
|
|
|
|
return rectangle
|