Created
July 8, 2019 21:36
-
-
Save Fraktality/4abc46547838fd0f15d641ad1466765f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Various ways of testing a screen point against a GuiBase2d | |
-- Note: Rounded rect corner radius is inferred from SliceCenter.Min.X | |
local cos = math.cos | |
local min = math.min | |
local rad = math.rad | |
local sin = math.sin | |
return { | |
-- Axis-aligned rectangle | |
aaRect = function(gui, x, y) | |
x, y = x + 0.5, y + 0.5 | |
local position = gui.AbsolutePosition | |
local p0x, p0y = position.x, position.y | |
if x >= p0x and y >= p0y then | |
local s = gui.AbsoluteSize | |
return x < p0x + s.x and y < p0y + s.y | |
end | |
return false | |
end, | |
-- Rectangle, accounting for rotation | |
rect = function(gui, x, y) | |
x, y = x + 0.5, y + 0.5 | |
local position = gui.AbsolutePosition | |
local size = gui.AbsoluteSize | |
local p0x, p0y = position.x, position.y | |
local sx, sy = size.x*0.5, size.y*0.5 | |
local cx, cy = p0x + sx, p0y + sy | |
if (x - cx)*(x - cx) + (y - cy)*(y - cy) > sx*sx + sy*sy then | |
return false | |
end | |
local rotationDeg = gui.AbsoluteRotation | |
if rotationDeg%180 ~= 0 then | |
if rotationDeg%90 ~= 0 then | |
local rotationRad = rad(rotationDeg) | |
local c = cos(rotationRad) | |
local s = sin(rotationRad) | |
x, y = | |
cx + c*(x - cx) + s*(y - cy), | |
cy - s*(x - cx) + c*(y - cy) | |
else | |
x, y = | |
cx - cy + y, | |
cx + cy - x | |
end | |
end | |
return x >= p0x and y >= p0y and x < cx + sx and y < cy + sy | |
end, | |
-- Axis-aligned rounded rectangle | |
aaRoundedRect = function(gui, x, y) | |
x, y = x + 0.5, y + 0.5 | |
local position = gui.AbsolutePosition | |
local p0x, p0y = position.x, position.y | |
if x >= p0x and y >= p0y then | |
local size = gui.AbsoluteSize | |
local sx, sy = size.x, size.y | |
local p1x = p0x + sx | |
local p1y = p0y + sy | |
if x < p1x and y < p1y then | |
loca l r = min(gui.SliceCenter.Min.x, sx*0.5, sy*0.5) | |
if (x >= p0x + r and x + r < p1x) or (y >= p0y + r and y + r < p1y) then | |
return true | |
end | |
local cx = x - (x > p0x + sx*0.5 and p1x - r or p0x + r) | |
local cy = y - (y > p0y + sy*0.5 and p1y - r or p0y + r) | |
return cx*cx + cy*cy < r*r | |
end | |
end | |
return false | |
end, | |
-- Rounded rectangle, accounting for rotation | |
roundedRect = function(gui, x, y) | |
x, y = x + 0.5, y + 0.5 | |
local position = gui.AbsolutePosition | |
local size = gui.AbsoluteSize | |
local p0x, p0y = position.x, position.y | |
local sx, sy = size.x*0.5, size.y*0.5 | |
local cx, cy = p0x + sx, p0y + sy | |
if (x - cx)*(x - cx) + (y - cy)*(y - cy) > sx*sx + sy*sy then | |
return false | |
end | |
local rotationDeg = gui.AbsoluteRotation | |
if rotationDeg%180 ~= 0 then | |
if rotationDeg%90 ~= 0 then | |
local rotationRad = rad(rotationDeg) | |
local c = cos(rotationRad) | |
local s = sin(rotationRad) | |
x, y = | |
cx + c*(x - cx) + s*(y - cy), | |
cy - s*(x - cx) + c*(y - cy) | |
else | |
x, y = | |
cx - cy + y, | |
cx + cy - x | |
end | |
end | |
local p1x = cx + sx | |
local p1y = cy + sy | |
if x >= p0x and y >= p0y and x < p1x and y < p1y then | |
local r = min(gui.SliceCenter.Min.x, sx, sy) | |
if (x >= p0x + r and x + r < p1x) or (y >= p0y + r and y + r < p1y) then | |
return true | |
end | |
cx = x - (x > cx and p1x - r or p0x + r) | |
cy = y - (y > cy and p1y - r or p0y + r) | |
return cx*cx + cy*cy < r*r | |
end | |
return false | |
end, | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment