C++ | 计算几何:判断点与多边形的关系

在屏幕坐标上有一个多边形,给定一个点,判断该点和多边形的关系。
例如在下图中,点A位于多边形内,点B位于多边形外,点C位于多边形上。

注意:
1.屏幕坐标系中,x轴从左往右为正方向,y轴从上到下为正方向,如示例中的坐标轴:
输入:
第一行为多边形数据,第一个数为整数,表示顶点个数,之后是顶点坐标,依次为各个点的x、y坐标的浮点数值。
例如 3 3.7 5 2 4 2.5 1.5 ,则表示有三个点组成的三角形。第二行表示待判断的点坐标,例如1.5 8.3

输出:
如果点在多边形内部,则返回0,如果在多边形上则返回1,如果在多边形外面则返回2

代码:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
struct Point{
    
    
    double x;
    double y;
};
bool PointInPolygon2D(Point p, vector<Point>& Polygon){
    
    //判断点与多边形的关系
    int nPointNumber = Polygon.size();
    if (nPointNumber == 0)
        return false;
    int nSideNumber = nPointNumber;
    if (Polygon[0].x == Polygon[nPointNumber - 1].x && Polygon[0].y == Polygon[nPointNumber - 1].y)
        nSideNumber--;
    double epsilon = 0.000001;
    int nCross = 0;
    for (int i = 0; i < nSideNumber; i++){
    
    
        Point p1 = Polygon[i];
        Point p2 = Polygon[(i + 1) % nSideNumber];
        if (p1.y == p2.y)
            continue;
        if (p.y < min(p1.y, p2.y) || p.y >= max(p1.y, p2.y))
            continue; 
        double x = (double)(p.y - p1.y) * (double)(p2.x - p1.x) / (double)(p2.y - p1.y) + p1.x;
        if ((x - p.x) >= epsilon)
            nCross++;
    }
    if ((nCross % 2) == 1)
        return true;
    else
        return false;
}
bool isEqual(double a, double b) {
    
    //判断两个double是否相等
    return std::fabs(a - b) < 1e-6;
}
bool isPointOnSegment(Point A, Point B, Point C) {
    
    //判断点是否在线段上
    if ((C.x >= min(A.x, B.x) && C.x <= max(A.x, B.x)) &&(C.y >= min(A.y, B.y) && C.y <= max(A.y, B.y))) {
    
    
        double crossProduct = (B.y - A.y) * (C.x - A.x) - (B.x - A.x) * (C.y - A.y);
        if (isEqual(crossProduct, 0.0)) {
    
    
            return true;
        }
    }
    return false;
}
int main(){
    
    
    int n;
    double x, y;
    cin >> n;
    vector<Point> p(n);
    for(int i =0;i<n;i++){
    
    
        cin >> x >> y;
        p[i].x = x;
        p[i].y = y;
    }
    struct Point target;

    cin >> target.x >> target.y;
    for (int i = 0; i < n - 1;i++){
    
    
        if(isPointOnSegment(p[i],p[i+1],target)){
    
    
            cout << "1" << endl;
            return 0;
        }
    }
    if (PointInPolygon2D(target, p)){
    
    
        cout << "0" << endl;
        return 0;
    }
    else{
    
    
        cout << "2" << endl;
        return 0;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/holly_Z_P_F/article/details/133343750