// C++ program to check if a point lies inside or outside a
// polygon using Winding Number Algorithm
#include <cmath>
#include <iostream>
#include <vector>
using namespace std;
struct Point {
double x, y;
};
// Function to compute the cross product of vectors (p1p2)
// and (p1p3)
double crossProduct(const Point& p1, const Point& p2,
const Point& p3)
{
return (p2.x - p1.x) * (p3.y - p1.y)
- (p2.y - p1.y) * (p3.x - p1.x);
}
// Function to check if point p lies on segment p1p2
bool isPointOnSegment(const Point& p, const Point& p1,
const Point& p2)
{
// Check if point p lies on the line segment p1p2 and
// within the bounding box of p1p2
return crossProduct(p1, p2, p) == 0
&& p.x >= min(p1.x, p2.x)
&& p.x <= max(p1.x, p2.x)
&& p.y >= min(p1.y, p2.y)
&& p.y <= max(p1.y, p2.y);
}
// Function to compute the winding number of a point with
// respect to a polygon
int windingNumber(const vector<Point>& polygon,
const Point& point)
{
int n = polygon.size();
int windingNumber = 0;
// Iterate through each edge of the polygon
for (int i = 0; i < n; i++) {
Point p1 = polygon[i];
// Next vertex in the polygon
Point p2 = polygon[(i + 1) % n];
// Check if the point lies on the current edge
if (isPointOnSegment(point, p1, p2)) {
// Point is on the polygon boundary
return 0;
}
// Calculate the cross product to determine winding
// direction
if (p1.y <= point.y) {
if (p2.y > point.y
&& crossProduct(p1, p2, point) > 0) {
windingNumber++;
}
}
else {
if (p2.y <= point.y
&& crossProduct(p1, p2, point) < 0) {
windingNumber--;
}
}
}
// Return the winding number
return windingNumber;
}
// Function to check if a point is inside a polygon using
// the winding number algorithm
bool isPointInPolygon(const vector<Point>& polygon,
const Point& point)
{
// Compute the winding number for the point with respect
// to the polygon
return windingNumber(polygon, point) != 0;
}
int main()
{
// Define a polygon
vector<Point> polygon
= { { 1, 1 }, { 1, 5 }, { 5, 5 }, { 5, 1 } };
// Define a point to check
Point point = { 3, 3 };
// Check if the point is inside the polygon using the
// winding number algorithm
if (isPointInPolygon(polygon, point)) {
cout << "Point is inside the polygon." << endl;
}
else {
cout << "Point is outside the polygon." << endl;
}
return 0;
}