Problem
You are given a list of N
points (x1, y1), (x2, y2), ..., (xN, yN)
representing a polygon. You can assume these points are given in order; that is, you can construct the polygon by connecting point 1
to point 2
, point 2
to point 3
, and so on, finally looping around to connect point N
to point 1
.
Determine if a new point p
lies inside this polygon. (If p
is on the boundary of the polygon, you should return False
).
Background
Known as Point-In-Polygon problem, testing whether a point lies inside a polygon is a classic literature problem in computational geometry.
A simple test to check whether a point p = {x, y}
lies inside a given polygon is to extend one of its dimensions to infinity:
p_inf = {+∞, y}
and do a line segments intersection test between p p_inf
and each one of the edges of the polygon. If the count of the intersections is odd, the point lies inside the polygon.
Special attention deserve two cases:
- when segment
p p_inf
has a successful intersection test andp
is found collinear to the polygon edge: ifp
lies in the polygon edge segment, any further check can be skipped since the point lies on the border of the polygon - when the
to_infinity
segment crosses one or more vertices of the polygon the intersection has to be counted once
Examples
Example 1
|
|
Example 2
|
|
Example 3
|
|
Example 4
|
|
Solution
Method 1 - Ray Casting Algorithm
Intuition
The ray casting algorithm works by casting a ray from the test point in any direction (typically horizontal to the right) and counting how many times it intersects with the polygon edges. If the number of intersections is odd, the point is inside; if even, it’s outside. This is based on the mathematical principle that to enter a closed shape, you must cross its boundary an odd number of times.
Approach
- Cast a horizontal ray from the test point extending to the right (to infinity)
- Count intersections with each edge of the polygon
- For each edge from vertex i to vertex i+1:
- Check if the ray intersects this edge
- Handle special cases like horizontal edges and vertices
- An intersection occurs when:
- The ray’s y-coordinate is between the edge’s y-coordinates
- The intersection point’s x-coordinate is to the right of the test point
- Return true if the intersection count is odd, false if even
- Special handling for boundary points: return false if point lies exactly on any edge
Code
|
|
|
|
|
|
|
|
Complexity
- ⏰ Time complexity:
O(n)
, where n is the number of vertices in the polygon. We need to check each edge exactly once - 🧺 Space complexity:
O(1)
, only using constant extra space for variables
Method 2 - Winding Number Algorithm
Intuition
The winding number algorithm calculates how many times the polygon winds around the test point. If the winding number is non-zero, the point is inside; if zero, it’s outside. This method is more robust for complex polygons and handles edge cases better than ray casting.
Approach
- Initialize winding number to 0
- For each edge of the polygon:
- Determine if the edge crosses the horizontal line through the test point
- If it crosses from below to above, increment winding number
- If it crosses from above to below, decrement winding number
- Check if the point lies exactly on any edge (return false if true)
- Return true if winding number is non-zero, false otherwise
- Use cross product to determine the side of the point relative to each edge
Code
|
|
|
|
|
|
|
|
Complexity
- ⏰ Time complexity:
O(n)
, where n is the number of vertices in the polygon. We process each edge exactly once - 🧺 Space complexity:
O(1)
, only using constant extra space for the winding number and temporary variables
Analysis
Both methods solve the point-in-polygon problem effectively:
- Method 1 (Ray Casting): Simpler to understand and implement, based on counting intersections
- Method 2 (Winding Number): More mathematically robust, handles complex polygons better
Key considerations:
- Both methods correctly handle the boundary condition by returning
false
for points on edges - Floating-point precision is handled using an epsilon value for edge detection
- The algorithms work for both convex and concave polygons
- Time complexity is optimal as we must examine each edge at least once
Advanced Implementation
Method 3 - Detailed Ray Casting with Edge Cases
This implementation provides comprehensive handling of edge cases including vertex intersections, collinear points, and special geometric configurations.
Code
|
|
Key Features of Advanced Implementation
- Vertex Intersection Handling: Uses hash set to track vertices that lie on the same horizontal line as the test point
- Collinear Point Detection: Special handling when the test point is collinear with polygon edges
- Integer Arithmetic: Uses integer coordinates to avoid floating-point precision issues
- Edge Case Management: Comprehensive handling of degenerate cases and boundary conditions
- Efficient Wraparound: Proper modular arithmetic for polygon edge traversal
Complexity
- ⏰ Time complexity:
O(n)
, where n is the number of vertices in the polygon - 🧺 Space complexity:
O(k)
, where k is the number of vertices with the same y-coordinate as the test point