local M={}M.__index=M local P P={default=function(P,V)local b=setmetatable({},M)b.P1=P[1]b.P2=P[2]b.P3=P[3]b.P4=P[4]b.u=V[1]b.v=V[2]b.w=V[3]return b end;CF_Size=function(M,V)local b=(M*CFrame.new(V.X/-2,V.Y/-2,V.Z/-2)).Position local K=(M*CFrame.new(V.X/2,V.Y/-2,V.Z/-2)).Position local m=(M*CFrame.new(V.X/-2,V.Y/2,V.Z/-2)).Position local i=(M*CFrame.new(V.X/-2,V.Y/-2,V.Z/2)).Position local y=K-b local a=m-b local s=i-b return P.default({b,K;m;i},{y;a;s})end;part=function(M)return P.CF_Size(M.CFrame,M.Size)end}function M.new(...)local M=select("\035",...)local V={...}if M==1 and typeof(V[1])=="\073\110\115\116\097\110\099\101"then return P.part(...)elseif M==2 and(typeof(V[1])=="\067\070\114\097\109\101"and typeof(V[2])=="\086\101\099\116\111\114\051")then return P.CF_Size(...)elseif M==2 and(typeof(V[1])=="\116\097\098\108\101"and(#V[1]==4 and(typeof(V[2])=="\116\097\098\108\101"and#V[2]==3)))then return P.default(...)else error("\073\110\099\111\114\114\101\099\116 \103\105\118\101\110 \112\097\114\097\109\101\116\101\114\115")end end function M.isInArea(P,M)local V=P.u:Dot(M)local b=P.v:Dot(M)local K=P.w:Dot(M)local m=P.u:Dot(P.P1)<=V and V<=P.u:Dot(P.P2)local i=P.v:Dot(P.P1)<=b and b<=P.v:Dot(P.P3)local y=P.w:Dot(P.P1)<=K and K<=P.w:Dot(P.P4)return m and(i and y)end function M.getCF_Size(M)return CFrame.fromMatrix(((M.P1+M.u/2)+M.v/2)+M.w/2,M.u,M.v,M.w),Vector3.new(M.u.Magnitude,M.v.Magnitude,M.w.Magnitude)end return M
-- names comes from the fact im storing 7 vectors
local Area = {}
Area.__index = Area

local constructors
constructors = {
   default = function(corners, vectors) -- first param needs the four positions of a corner (origin and three perpendicular corners), second needs the vectors of those three perpendicular corners
        local self = setmetatable({}, Area)
        self.P1 = corners[1] 
        self.P2 = corners[2]
        self.P3 = corners[3]
        self.P4 = corners[4]
        self.u = vectors[1]
        self.v = vectors[2]
        self.w = vectors[3]
        return self
    end,
    CF_Size = function (cframe, Size)
        local pos1 = (cframe * CFrame.new(Size.X/-2, Size.Y/-2, Size.Z/-2)).Position
        local pos2 = (cframe * CFrame.new(Size.X/2, Size.Y/-2, Size.Z/-2)).Position
        local pos3 = (cframe * CFrame.new(Size.X/-2, Size.Y/2, Size.Z/-2)).Position
        local pos4 = (cframe * CFrame.new(Size.X/-2, Size.Y/-2, Size.Z/2)).Position
       
        local u = pos2 - pos1
        local v = pos3 - pos1
        local w = pos4 - pos1       
        return constructors.default({pos1,pos2,pos3,pos4} , {u, v, w})
    end,
    part = function(part)
        return constructors.CF_Size(part.CFrame, part.Size)
    end
}

function Area.new(...) -- constructors for AreaV7
    local n = select("#", ...)
    local args = {...}

    if n == 1 and typeof(args[1]) == "Instance" then
        return constructors.part(...)
    elseif  n == 2 and typeof(args[1]) == "CFrame" and typeof(args[2]) == "Vector3" then
        return  constructors.CF_Size(...)
    elseif  n == 2 and typeof(args[1]) == "table" and #args[1] == 4 and typeof(args[2]) == "table" and #args[2] == 3 then
        return constructors.default(...)
    else
        error("Incorrect given parameters")
    end
end

-- credit for the idea of checking an area https://math.stackexchange.com/questions/1472049/check-if-a-point-is-inside-a-rectangular-shaped-area-3d
function Area:isInArea(position) -- expects a vector3 instance, returns true if the position is inside the area
    local ux = self.u:Dot(position)
    local vx = self.v:Dot(position)
    local wx = self.w:Dot(position)

    local constraint1 = self.u:Dot(self.P1) <= ux and ux <= self.u:Dot(self.P2)
    local constraint2 = self.v:Dot(self.P1) <= vx and vx <= self.v:Dot(self.P3)
    local constraint3 = self.w:Dot(self.P1) <= wx and wx <= self.w:Dot(self.P4)
    return constraint1 and constraint2 and constraint3
end

function Area:getCF_Size()
    return CFrame.fromMatrix(self.P1 + self.u/2 + self.v/2 + self.w/2, self.u , self.v, self.w), Vector3.new(self.u.Magnitude, self.v.Magnitude, self.w.Magnitude)
end

return Area
