Pizzicato Posted June 29, 2024 Posted June 29, 2024 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 cfrag Posted June 30, 2024 Solution Posted June 30, 2024 (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 June 30, 2024 by cfrag 1 1
Pizzicato Posted June 30, 2024 Author Posted June 30, 2024 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
Recommended Posts