Solution
In order to determine if a point is inside a polygon, we can imagine a ray being cast from that point towards any direction. Resulting in three possible scenarios:
- If the ray intersects with odd number of edges, then the point is inside.
- If the ray intersects with even number of edges, then the point is outside.
- If the origin point is on a line segment, then the point is on the edge.
This algorithm is known as the Ray Casting Algorithm.
Line segment & Line segment intersection
Given two line segments and , how can we efficiently check if they intersect each other? We will first have to use a concept from linear algebra called the determinant.
Complementary resource
This youtube video provides a handy in-depth explanation of determinants.
We will define the determinant of two vectors as . Given two vectors and . If gives a positive area then points to the left of , if it gives a negative area then points to the right of , and if it gives a zero area then and are parallel.
To check if and intersect with each other, is equal to checking if intersects with the line from line segment , and checking if intersects with the line from line segment . For the first of two condition to be true, and from must be on the opposite directions of . To define this mathematically, let
The condition will be true if and only if . Verifying the second of the two cases is equivalent to the procedure above, except and are switched with and .
As all geometry problem go, edge cases are a must. One edge case one might consider in our method above is that if both and are equal and are equal to 0, then they can still intersect as long as they overlap with each other. But let me let you in on a secret, due to the way this problem is structured, all vertices are on lattice points, meaning that they have whole numbers as coordinates. And since one of the is customizable (we get to pick the point the point cast its ray at), we can just set its coordinate to . This way, the ray will have a slope of close to , successfully avoiding all possible lattice point intersections. One trick to rule all the edge cases!
Implementation
Time Complexity:
C++
#include <bits/stdc++.h>using namespace std;typedef long long ll;struct Point {ll x, y;};// Compute the determinant of two vectors (p1,p2) and (p3,p4)ll det(Point p1, Point p2, Point p3, Point p4) {
Join the USACO Forum!
Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!