Matrix rotation can be used for Vector3s and Vector2s. Its about rotateing a Vector around the 0 position. Matrices are constructed by rows and columns, the rotation matrix we are going to use is 2x2 (2 rows and 2 columns) [cos(R) -sin(R).sin(R) cos(R)] the comma is a sign its the next row
When we multipliy the a Vector2 by the roation matrix we get a rotated vector by the angle we want, lets try and rotate a Vector2 by 90 deg:
local v = Vector2.new(10, 10)
local Rv = Vector2.new(v.X * math.cos(math.rad(90)) - v.Y * math.sin(math.rad(90)),
v.X * math.sin(math.rad(90)) + v.Y * math.cos(math.rad(90)))
When calculated Rv = (-10, 10), as expected Vector v was rotated by 90. If we use this formula we can rotate the Frames by 360-R (R = the main frames rotation) and then check if any corner is inside the frame.
Another problem we run into is acually calculating the position of the corners, if a frame is rotated the position of its corners isnt equal to its position + size, we need to use the right triangle formulas and the center of the frame. The center of the frame is its position + its size/2 here is and example of a function to calculate all the corners:
local function GetCorners(frame)
local pos = frame.AbsolutePosition
local size = frame.AbsoluteSize
local rot = frame.AbsoluteRotation
local center = pos + size/2
local x = Vector2.new(math.cos(math.rad(rot))*(size.X/2), math.sin(math.rad(rot))*(size.X/2))
local y = Vector2.new(math.cos(math.rad(rot+90))*(size.Y/2), math.sin(math.rad(rot+90))*(size.Y/2))
local crs = {center - x - y,
center + x - y,
center - x + y,
center + x + y}
return crs
end
as we caluclated the corners we can now check if its inside the cube:
local function GetCorners(frame)
local pos = frame.AbsolutePosition
local size = frame.AbsoluteSize
local rot = frame.AbsoluteRotation
local center = pos + size/2
local x = Vector2.new(math.cos(math.rad(rot))*(size.X/2), math.sin(math.rad(rot))*(size.X/2))
local y = Vector2.new(math.cos(math.rad(rot+90))*(size.Y/2), math.sin(math.rad(rot+90))*(size.Y/2))
local crs = {center - x - y,
center + x - y,
center - x + y,
center + x + y}
return crs
end
local function CheckIfInsideRect(v1, cr1, cr2)
-- V1 is the position we want to check
-- cr1 is the top-right corner
-- cr2 = is the lower-left corner
if v1.X > cr1.X and v1.Y > cr1.Y then
if v1.X < cr2.X and v1.Y < cr2.Y then
return true
end
end
return false
end
local function GetRotatedVector(angle, v)
return Vector2.new(v.X*math.cos(math.rad(angle))-v.Y*math.sin(math.rad(angle))
, v.X*math.sin(math.rad(angle))+v.Y*math.cos(math.rad(angle)))
-- Just the matrix rotation
end
local cornerCollisions = {}
local function CheckRect(obj1, obj2)
local angle = 360-obj2.AbsoluteRotation
-- angle is equal to the rotation we need to rotate for the obj2s corners to be rotated back to zero
local cr1 = GetCorners(obj1)
local cr2 = GetCorners(obj2)
local cr11 = GetRotatedVector(angle, cr1[1])
local cr12 = GetRotatedVector(angle, cr1[2])
local cr13 = GetRotatedVector(angle, cr1[3])
local cr14 = GetRotatedVector(angle, cr1[4])
local cr21 = GetRotatedVector(angle, cr2[1])
local cr24 = GetRotatedVector(angle, cr2[4])
-- all of the rotated angles
local o1 = CheckIfInsideRect(cr11, cr21, cr24)
local o2 = CheckIfInsideRect(cr12, cr21, cr24)
local o3 = CheckIfInsideRect(cr13, cr21, cr24)
local o4 = CheckIfInsideRect(cr14, cr21, cr24)
-- check if the rotated corners of obj1 is inside obj2
if o1 == true or o2 == true or o3 == true or o4 == true then
return true
end
-- return true if any corners and inside obj2
return false
end
local function CollisionTest(obj1, obj2)
local o1 = CheckRect(obj2, obj1)
local o2 = CheckRect(obj1, obj2)
if o1 == true or o2 == true then
return true
end
return false
end
works alright tho there is 100% faster code out there :p. hope this was helpfull :D