来自顺丰 04
c++
class Solution {
public:
const double eps = 1e-6;
struct Point {
double x, y;
Point(double x = 0, double y = 0): x(x), y(y) {}
//向量+
Point operator +(const Point &b)const
{
return Point(x+b.x,y+b.y);
}
//向量-
Point operator -(const Point &b)const
{
return Point(x-b.x,y-b.y);
}
//点积
double operator *(const Point &b)const
{
return x*b.x + y*b.y;
}
//叉积
//P^Q>0,P在Q的顺时针方向;<0,P在Q的逆时针方向;=0,P,Q共线,可能同向或反向
double operator ^(const Point &b)const
{
return x*b.y - b.x*y;
}
};
int dcmp(double x) // 判断两个 double 在 eps 精度下的大小关系
{
if (fabs(x) < eps) return 0;
else return x < 0 ? -1 : 1;
}
bool onSeg(Point p1, Point p2, Point q) // 判断 q 是否在 p1 p2 的线段上
{
return dcmp((p1 - q) ^ (p2 - q)) == 0 && dcmp((p1 - q) * (p2 - q)) <= 0;
}
bool isPointInPolygon(double x, double y, vector<double>& coords) {
vector<Point> polygon;
int n = coords.size();
for (int i = 0; i < n; i += 2) polygon.push_back(Point(coords[i], coords[i + 1]));
n = polygon.size();
auto inPolygon = [&](Point p) -> bool
{
bool flag = false;
Point p1, p2;
for (int i = 0, j = n - 1; i < n; j = i ++)
{
p1 = polygon[i];
p2 = polygon[j];
if (onSeg(p1, p2, p)) return true; // 在多边形的一条线上
if ((dcmp(p1.y - p.y) > 0 != dcmp(p2.y - p.y) > 0) && dcmp(p.x - (p.y - p1.y) * (p1.x - p2.x) / (p1.y - p2.y) - p1.x) < 0)
flag = !flag;
}
return flag;
};
return inPolygon(Point(x, y));
}
};