Point-in-Polygon and Polygon Touches Predicates

Spatial predicates for routing: the ray-casting point-in-polygon test, three-way classification of points as interior, boundary, or exterior, and the polygon-touches predicate that distinguishes shared-boundary contact from overlap.

Step 1 of 157%

Tutorial

The Point-in-Polygon Predicate via Ray Casting

In a live air-routing system we must constantly answer queries such as: does a waypoint lie inside a restricted-airspace polygon? Such Boolean queries on geometric configurations are called spatial predicates.

The point-in-polygon (PIP) predicate decides whether a point PP lies inside a closed simple polygon Ω\Omega. The standard algorithm is ray casting (a.k.a. the parity test):

  1. Cast a ray from PP in some direction (commonly +x+x).
  2. Count the number kk of polygon edges the ray crosses.
  3. If kk is odd, PP is inside; if kk is even, PP is outside.

To test whether a horizontal +x+x ray from P=(Px,Py)P=(P_x,P_y) crosses the edge from A=(Ax,Ay)A=(A_x,A_y) to B=(Bx,By)B=(B_x,B_y), we require:

(i) PyP_y strictly between AyA_y and ByB_y: min(Ay,By)<Py<max(Ay,By)\min(A_y,B_y) < P_y < \max(A_y,B_y).

(ii) The edge's xx-coordinate at height PyP_y,

x=Ax+PyAyByAy(BxAx),x^* = A_x + \dfrac{P_y - A_y}{B_y - A_y}\,(B_x - A_x),

satisfies x>Pxx^* > P_x.

Illustration: triangle (0,0),(4,0),(2,4)(0,0),(4,0),(2,4) with P=(2,1)P=(2,1).

  • Edge (0,0) ⁣ ⁣(4,0)(0,0)\!\to\!(4,0): Ay=By=0A_y=B_y=0, ray at y=1y=1 is not strictly between. Skip.
  • Edge (4,0) ⁣ ⁣(2,4)(4,0)\!\to\!(2,4): 0<1<40<1<4 ✓. x=4+1040(24)=3.5>2x^* = 4 + \tfrac{1-0}{4-0}(2-4) = 3.5 > 2 ✓. Cross.
  • Edge (2,4) ⁣ ⁣(0,0)(2,4)\!\to\!(0,0): 0<1<40<1<4 ✓. x=2+1404(02)=0.5<2x^* = 2 + \tfrac{1-4}{0-4}(0-2) = 0.5 < 2. No.

Total crossings k=1k=1 (odd), so PP is inside the triangle.

navigate · Enter open · Esc close · ⌘K/Ctrl K toggle