来自顺丰 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));
    }
};