Jump to content

Check if a point is within a Quad-Point Zone?


Go to solution Solved by cfrag,

Recommended Posts

Posted

Hey all,

My question is basically the title. How do you go about checking if a point is within a Quad-Point Zone? I've poked around online and it seems like raycasting is the accepted way of doing this, but that's way beyond my amateur pay-grade. Is there a more accessible/off-the-self function for doing that?

Thanks in advance.

i7-7700K @ 4.9Ghz | 16Gb DDR4 @ 3200Mhz | MSI Z270 Gaming M7 | MSI GeForce GTX 1080ti Gaming X | Win 10 Home | Thrustmaster Warthog | MFG Crosswind pedals | Oculus Rift S

  • Solution
Posted (edited)
20 hours ago, Pizzicato said:

Is there a more accessible/off-the-self function for doing that?

There is if you are not too much terrorized by trigonometry, and can ensure that all your quad-point zones are convex (meaning that none of the angles inside the zone have more than 180° - the zone is then shaped like a "V")

If above restraints are met (most quad zones do), simple trig can come to the rescue, and you can test inside/outside with a few multiplications. The idea is that a point P is inside of a polygon ABCD if, and only if it is to the same side of all vertices AB, BC, CD and DA. If it isn't, it's outside the polygon. Which side a point P is to a line AB is determined by the direction of the normal vector to the two vectors PA and PB. The normal vector will either point up or down since the triangle PAB define a plane identical to DCS's XZ (ground) plane. Since the result is either positive or negative, we simply look at all four normal vectors. If they all have the same sign, the point is inside, otherwise it's outside. Calculating the normal vector is a simple matter of multiplication and subtraction, which is very fast.

Below is how DML determines if a point is inside a poly

function cfxZones.isPointInsideQuad(thePoint, A, B, C, D) 
    -- Inside test (only convex polygons): 
	-- point lies on the same side of each quad's vertex AB, BC, CD, DA
	-- how do we find out which side a point lies on? via the cross product
	-- see isLeft below
	
	-- so all we need to do is make sure all results of isLeft for all
	-- four sides are the same
	local mustMatch = isLeftXZ(A, B, thePoint) -- all test results must be the same and we are ok
									   -- they just must be the same side.
	if (cfxZones.isLeftXZ(B, C, thePoint ~= mustMatch)) then return false end -- on other side than all before
	if (cfxZones.isLeftXZ(C, D, thePoint ~= mustMatch)) then return false end 
	if (cfxZones.isLeftXZ(D, A, thePoint ~= mustMatch)) then return false end
	return true
end

function cfxZones.isLeftXZ(A, B, P)
	return ((B.x - A.x)*(P.z - A.z) - (B.z - A.z)*(P.x - A.x)) > 0
end

 

Edited by cfrag
  • Like 1
  • Thanks 1
Posted

Thanks, as ever, for the response and the detailed explanation @cfrag. That's hugely helpful and much appreciated.

i7-7700K @ 4.9Ghz | 16Gb DDR4 @ 3200Mhz | MSI Z270 Gaming M7 | MSI GeForce GTX 1080ti Gaming X | Win 10 Home | Thrustmaster Warthog | MFG Crosswind pedals | Oculus Rift S

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...