Check if something is within four given points

Recommended Posts

Hello!

I am trying to do a boundary system based on coordinates, so no col shapes or anything. Unfortunately I'm not that good at math, but I tried doing it based on found results on the internet.

My problem is that this whole script is not working how it should, check it for yourself, it has debug outputs and visible markers for corners and the center.

• Why does the width and height return a much bigger number than the calculatedX and calculatedY?
• Why does the calculatedX and calculatedY return always the same?
• Why does the width and height change values as I move around?

I would be really grateful if somebody could help me, this is for a community project, so others would be too!

Here's my current full code:

Global:

```customBoundaries = {
-- this boundary is between the big brown building(s) and the skatepark on the road in LS
["test"] = {
point1 = {x = 1842.2908935547, y = -1412.469360351},
point2 = {x = 1856.8596191406, y = -1412.555664062},
point3 = {x = 1851.5925292969, y = -1436.5225830078},
point4 = {x = 1842.0438232422, y = -1424.5217285156},
},
}```

Client:

```local debugEnabled = true

function sum(n)
return ((n+1) * n) / 2
end

function isElementWithinBoundary(element, boundary)
if element and isElement(element) then
local elementX, elementY, elementZ = getElementPosition(element)
boundary = tostring(boundary)
if boundary and type(boundary) == "string" then
if customBoundaries and customBoundaries[boundary] then
local corner1 = {customBoundaries[boundary].point1.x, customBoundaries[boundary].point1.y}
local corner2 = {customBoundaries[boundary].point2.x, customBoundaries[boundary].point2.y}
local corner3 = {customBoundaries[boundary].point3.x, customBoundaries[boundary].point3.y}
local corner4 = {customBoundaries[boundary].point4.x, customBoundaries[boundary].point4.y}

local centerX, centerY = (corner1[1] + corner2[1] + corner3[1] + corner4[1])/4, (corner1[2] + corner2[2] + corner3[2] + corner4[2])/4
local originX, originY = elementX - corner1[1], elementY - corner1[2]

local width = math.sqrt((corner2[1] - originX)^2 + (corner2[2] - originY)^2)
local height = math.sqrt((corner4[1] - originX)^2 + (corner4[2] - originY)^2)

local calculatedX = originX * (corner2[1] - originX)/width + originY * (corner2[2] - originY)/height
local calculatedY = originX * (corner4[1] - originX)/width + originY * (corner4[2] - originY)/height

outputChatBox("X: " .. math.floor(calculatedX) .. " | width: " .. math.floor(width))
outputChatBox("Y: " .. math.floor(calculatedY) .. " | height: " .. math.floor(height))

if (0 <= calculatedX and calculatedX <= width) and (0 <= calculatedY and calculatedY <= height) then
outputChatBox("XD")
end

if debugEnabled then
for points, coordinates in pairs(customBoundaries[boundary]) do

local cornerMarker = createMarker(coordinates.x, coordinates.y, getGroundPosition(coordinates.x, coordinates.y, elementZ), "cylinder", 2, 140, 245, 20, 150)

local centerMarker = createMarker(centerX, centerY, getGroundPosition(centerX, centerY, elementZ)+2, "arrow", 1, 245, 140, 20, 150)
end
end
end
end
end
end

isElementWithinBoundary(localPlayer, "test")```

Here's the calculation I was trying to copy and make it work based on: https://math.stackexchange.com/a/190257

```customBoundaries = {
-- this boundary is between the big brown building(s) and the skatepark on the road in LS
["test"] = {
{x = 1842.2908935547, y = -1412.469360351},
{x = 1856.8596191406, y = -1412.555664062},
{x = 1851.5925292969, y = -1436.5225830078},
{x = 1842.0438232422, y = -1424.5217285156},
},
}

local colorOfBounds = tocolor(255, 0, 0)

bindKey("e", "down",
function ()
if isElementWithinBoundary(localPlayer, "test") then
colorOfBounds = tocolor(0, 255, 0)
else
colorOfBounds = tocolor(255, 0, 0)
end
end
)

function ()
local localX, localY, localZ = getElementPosition(localPlayer)
local boundary = "test"

for i = 1, #customBoundaries[boundary] do
local currentPoint = customBoundaries[boundary][i]
local nextPoint = customBoundaries[boundary][i + 1]

if currentPoint then
if i == #customBoundaries[boundary] then
nextPoint = customBoundaries[boundary][1]
dxDrawLine3D(currentPoint.x, currentPoint.y, localZ, nextPoint.x, nextPoint.y, localZ, colorOfBounds, 3)
end

dxDrawLine3D(currentPoint.x, currentPoint.y, localZ, nextPoint.x, nextPoint.y, localZ, colorOfBounds, 3)
end
end
end
)

function isElementWithinBoundary(element, boundary)
if isElement(element) and boundary and customBoundaries[boundary] and #customBoundaries[boundary] >= 3 then
local pointX, pointY, pointZ = getElementPosition(element)
local intersections = 0

for i = 1, #customBoundaries[boundary] do
local currentPoint = customBoundaries[boundary][i]

if currentPoint then
local nextPoint = customBoundaries[boundary][i + 1]
local previousPoint = customBoundaries[boundary][i - 1]

if i == 1 then
previousPoint = customBoundaries[boundary][1]
elseif i == #customBoundaries[boundary] then
nextPoint = customBoundaries[boundary][1]
end

if areIntersecting(pointX, pointY, previousPoint.x, previousPoint.y, currentPoint.x, currentPoint.y, nextPoint.x, nextPoint.y) then
intersections = intersections + 1
end
end
end

if intersections > 0 then
return true
end
end

return false
end

function sign(x1, y1, x2, y2, x3, y3)
return (x1 - x3) * (y2 - y3) - (x2 - x3) * (y1 - y3)
end

function areIntersecting(pointX, pointY, x1, y1, x2, y2, x3, y3)
local b1 = sign(pointX, pointY, x1, y1, x2, y2) < 0
local b2 = sign(pointX, pointY, x2, y2, x3, y3) < 0
local b3 = sign(pointX, pointY, x3, y3, x1, y1) < 0

return b1 == b2 and b2 == b3
end```

Tested. Works with 3 or more points.

Yes, you can check the element within the the polygon.

• 1

Thank you so much for your help!

Create an account

Register a new account