In computational geometry, we come across a problem to determine whether a given point lies inside, outside, or on the boundary of a polygon. This problem, known as the "Point in Polygon" (PIP) problem. It has numerous applications in computer graphics, geographic information systems (GIS), and robotics.
In this article, we will learn how to check if a given point lies inside or outside a polygon in C language. We will also look at different methods to achieve this.
Example:
Input:
Polygon: { { 0, 0 }, { 10, 0 }, { 10, 10 }, { 0, 10 } }
Point: {20, 20};
Output:
Point is outside the polygon.

Approaches to Solve Point in Polygon in C Language
Method 1: Using Ray Casting Algorithm
In this method, we first cast a horizontal ray from the point in question to infinity and count how many times the ray intersects the edges of the polygon. If the number of intersections is odd, the point is inside the polygon. If even, the point is outside.
As seen in below diagram Point A and C has one intersection with polygon edges which is odd in number thus the point A and C are inside the polygon whereas Point B and D have two intersections with polygon edges which is even thus the point B and D are outside the polygon and also Point E has 0 intersection with polygon edges which is also even and thus lying outside the polygon. We can confirm above speculation from the diagram are true.

Approach
- Initialize a counter for intersections to zero.
- For each edge of the polygon:
- Check if the edge intersects the horizontal ray extending to the right from the point.
- If it does, increment the intersection counter.
- If the intersection counter is odd, the point is inside the polygon; if even, it is outside.
C Program to Check Point in Polygon using Ray Casting Algorithm
The below program demonstrates how we can check if a point lies inside or outside a polygon using ray casting algorithmin C.
// C program to check if a point is inside a polygon using
// ray-casting algorithm
#include <float.h>
#include <math.h>
#include <stdio.h>
// Structure for a point
typedef struct {
double x, y;
} Point;
// Function to check if a point is on the boundary of a
// polygon edge
int onSegment(Point p, Point q, Point r)
{
if (q.x <= fmax(p.x, r.x) && q.x >= fmin(p.x, r.x)
&& q.y <= fmax(p.y, r.y) && q.y >= fmin(p.y, r.y))
return 1;
return 0;
}
// Function to find the orientation of the triplet (p, q, r)
// 0 --> p, q and r are collinear
// 1 --> Clockwise
// 2 --> Counterclockwise
int orientation(Point p, Point q, Point r)
{
double val = (q.y - p.y) * (r.x - q.x)
- (q.x - p.x) * (r.y - q.y);
// collinear
if (val == 0)
return 0;
// clock or counterclock wise
return (val > 0) ? 1 : 2;
}
// Function to check if two line segments intersect
int doIntersect(Point p1, Point q1, Point p2, Point q2)
{
int o1 = orientation(p1, q1, p2);
int o2 = orientation(p1, q1, q2);
int o3 = orientation(p2, q2, p1);
int o4 = orientation(p2, q2, q1);
// General case
if (o1 != o2 && o3 != o4)
return 1;
// Special Cases
// p1, q1 and p2 are collinear and p2 lies on segment
// p1q1
if (o1 == 0 && onSegment(p1, p2, q1))
return 1;
// p1, q1 and p2 are collinear and q2 lies on segment
// p1q1
if (o2 == 0 && onSegment(p1, q2, q1))
return 1;
// p2, q2 and p1 are collinear and p1 lies on segment
// p2q2
if (o3 == 0 && onSegment(p2, p1, q2))
return 1;
// p2, q2 and q1 are collinear and q1 lies on segment
// p2q2
if (o4 == 0 && onSegment(p2, q1, q2))
return 1;
return 0; // Doesn't fall in any of the above cases
}
// Function to check if the point p is inside the polygon
int isInside(Point polygon[], int n, Point p)
{
// Create a point for the ray (a point far outside the
// polygon)
Point extreme = { DBL_MAX, p.y };
int count = 0, i = 0;
do {
int next = (i + 1) % n;
if (doIntersect(polygon[i], polygon[next], p,
extreme)) {
if (orientation(polygon[i], p, polygon[next])
== 0)
return onSegment(polygon[i], p,
polygon[next]);
count++;
}
i = next;
} while (i != 0);
// Return true if count is odd, false otherwise
return count & 1;
}
int main()
{
Point polygon[]
= { { 0, 0 }, { 10, 0 }, { 10, 10 }, { 0, 10 } };
int n = sizeof(polygon) / sizeof(polygon[0]);
Point p = { 20, 20 };
isInside(polygon, n, p)
? printf("Point is inside the polygon.\n")
: printf("Point is outside the polygon.\n");
return 0;
}
Output
Point is outside the polygon.
Time Complexity: O(n), where n is the number of vertices in the polygon.
Auxiliary Space: O(1)
Method 2: Using Winding Number Algorithm
In this method we count the number of times the polygon winds around the point. If the winding number is non-zero, the point is inside; otherwise, it is outside. This method is robust and handles complex polygons, including those with holes.
Approach
- Initialize the winding number to zero.
- For each edge of the polygon:
- Check the edge direction (upwards or downwards) and whether the point is between the edge's y-coordinates.
- Adjust the winding number based on the edge direction and whether the point lies to the left or right of the edge.
- If the winding number is non-zero, the point is inside the polygon; otherwise, it is outside.
C Program to Check Point in Polygon using Winding Number Algorithm
The below program demonstrates how we can check if a point lies inside or outside a polygon using Winding Number Algorithm in C.
// C program to check if a point lies inside a polygon using
// the winding number algorithm
#include <math.h>
#include <stdio.h>
// Point structure
typedef struct {
double x;
double y;
} Point;
// Function to calculate the minimum of two numbers
double my_min(double a, double b) { return a < b ? a : b; }
// Function to calculate the maximum of two numbers
double my_max(double a, double b) { return a > b ? a : b; }
// Function to calculate the cross product of vectors AB and
// AC
double cross_product(Point A, Point B, Point C)
{
return (B.x - A.x) * (C.y - A.y)
- (B.y - A.y) * (C.x - A.x);
}
// Function to determine if a point P is on segment AB
int is_point_on_segment(Point P, Point A, Point B)
{
if (P.x >= my_min(A.x, B.x) && P.x <= my_max(A.x, B.x)
&& P.y >= my_min(A.y, B.y)
&& P.y <= my_max(A.y, B.y)) {
return 1;
}
else {
return 0;
}
}
// Function to check if a point P lies inside the polygon
// defined by vertices poly with 'n' vertices
int is_point_inside_polygon(Point P, Point poly[], int n)
{
int winding_number = 0;
for (int i = 0; i < n; i++) {
Point current_vertex = poly[i];
Point next_vertex = poly[(i + 1) % n];
// Check if P is on the edge
if (is_point_on_segment(P, current_vertex,
next_vertex)) {
// Point P is on the boundary of the polygon
return 1;
}
// Calculate the cross product
double cross_product_value
= cross_product(current_vertex, next_vertex, P);
// Determine the relative position of P to the edge
if (current_vertex.y <= P.y) {
if (next_vertex.y > P.y
&& cross_product_value > 0) {
winding_number++;
}
}
else {
if (next_vertex.y <= P.y
&& cross_product_value < 0) {
winding_number--;
}
}
}
// If winding number is non-zero, P is inside the
// polygon; otherwise, it's outside
return (winding_number != 0);
}
// Example usage
int main()
{
// Define a polygon (example triangle)
Point polygon[]
= { { 0, 0 }, { 10, 0 }, { 10, 10 }, { 0, 10 } };
int n = sizeof(polygon) / sizeof(polygon[0]);
// Test point
Point test_point = { 20, 20 };
// Check if the test point is inside the polygon
if (is_point_inside_polygon(test_point, polygon, n)) {
printf(
"Point (%.1f, %.1f) is inside the polygon.\n",
test_point.x, test_point.y);
}
else {
printf(
"Point (%.1f, %.1f) is outside the polygon.\n",
test_point.x, test_point.y);
}
return 0;
}
Output
Point (20.0, 20.0) is outside the polygon.
Time Complexity: O(n), where n is the number of vertices in the polygon.
Auxiliary Space: O(1)
Method 3: Using Crossing Number Algorithm
The Crossing Number algorithm is similar to the Ray-Casting algorithm but uses a vertical ray instead. It counts the number of times the vertical ray from the point intersects the polygon’s edges. If the count is odd, the point is inside; if even, it is outside.
Approach
- Initialize a boolean variable inside to false to keep a track whether the point is inside the polygon based on the number of edge crossings.
- Start iterating through each edge of the polygon:
- Determine if the point lies on the same side of the edge’s y-range as the polygon.
- Count edge crossings from one side to the other using linear interpolation to find the x-coordinate where the ray crosses the edge.
- If the number of crossings is odd, toggle the inside variable to true and if the number of crossings is even, the point remains outside the polygon.
C Program to Check Point in Polygon using Crossing Number Algorithm
The below program demonstrates how we can check if a point lies inside or outside a polygon using crossing numbw algorithm C.
#include <stdio.h>
// Structure to represent a point
typedef struct {
double x, y;
} Point;
// Function to check if a point q lies on the segment pr
int onSegment(Point p, Point q, Point r) {
// Check if q lies between p and r
if (q.x <= fmax(p.x, r.x) && q.x >= fmin(p.x, r.x) &&
q.y <= fmax(p.y, r.y) && q.y >= fmin(p.y, r.y)) {
return 1;
}
return 0;
}
// Function to find the orientation of the ordered triplet (p, q, r)
// The function returns:
// 0 -> p, q, and r are collinear
// 1 -> Clockwise
// 2 -> Counterclockwise
int orientation(Point p, Point q, Point r) {
double val = (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
if (val == 0) return 0; // Collinear
return (val > 0) ? 1 : 2; // Clockwise or Counterclockwise
}
// Function to check if two line segments p1q1 and p2q2 intersect
int doIntersect(Point p1, Point q1, Point p2, Point q2) {
// Find the four orientations needed for the general and special cases
int o1 = orientation(p1, q1, p2);
int o2 = orientation(p1, q1, q2);
int o3 = orientation(p2, q2, p1);
int o4 = orientation(p2, q2, q1);
// General case
if (o1 != o2 && o3 != o4) return 1;
// Special cases
if (o1 == 0 && onSegment(p1, p2, q1)) return 1;
if (o2 == 0 && onSegment(p1, q2, q1)) return 1;
if (o3 == 0 && onSegment(p2, p1, q2)) return 1;
if (o4 == 0 && onSegment(p2, q1, q2)) return 1;
return 0; // Doesn't intersect
}
// Function to check if a point p lies inside the polygon with n vertices
int isPointInPolygon(Point polygon[], int n, Point p) {
// There must be at least 3 vertices in polygon
if (n < 3) return 0;
// Create a point for the line segment from p to infinity
Point extreme = {10000, p.y};
// Count intersections of the above line with the sides of the polygon
int count = 0, i = 0;
do {
int next = (i + 1) % n;
// Check if the line segment from 'p' to 'extreme' intersects
// with the line segment from 'polygon[i]' to 'polygon[next]'
if (doIntersect(polygon[i], polygon[next], p, extreme)) {
// If the point 'p' is collinear with line segment 'i-next',
// then check if it lies on segment. If it lies, return true.
if (orientation(polygon[i], p, polygon[next]) == 0) {
return onSegment(polygon[i], p, polygon[next]);
}
count++;
}
i = next;
} while (i != 0);
// Return true if count is odd, false otherwise
return count % 2 == 1;
}
// Main function
int main() {
// Define the polygon as a list of points
Point polygon[] = {{1, 1}, {1, 5}, {5, 5}, {5, 1}};
int n = sizeof(polygon) / sizeof(polygon[0]);
// Define the point to be checked
Point p = {3, 3};
// Check if the point is inside the polygon
if (isPointInPolygon(polygon, n, p)) {
printf("Point is inside the polygon.\n");
} else {
printf("Point is outside the polygon.\n");
}
return 0;
}
Time Complexity: O(n), where n is the number of vertices in the polygon.
Auxiliary Space: O(1)
Conclusion
In this article we understood that Point in Polygon (PIP) problem is fundamental in computational geometry with various practical applications, including computer graphics, geographic information systems (GIS), and robotics. Also, we discussed three methods —Ray Casting Algorithm, Winding Number Algorithm, and Edge Crossing Method—offer different approaches to determine whether a point lies inside a polygon.