C++ | Geometría computacional: determinación de la relación entre puntos y polígonos

Hay un polígono en las coordenadas de la pantalla. Dado un punto, determine la relación entre el punto y el polígono.
Por ejemplo, en la siguiente figura, el punto A está dentro del polígono, el punto B está fuera del polígono y el punto C está en el polígono.

Nota:
1. En el sistema de coordenadas de la pantalla, el eje x es la dirección positiva de izquierda a derecha y el eje y es la dirección positiva de arriba a abajo. Por ejemplo, los ejes de coordenadas en el ejemplo: Entrada
:
El La primera línea son datos de polígonos y el primer número es un número entero, que indica el número de vértices, seguido de las coordenadas de los vértices, seguido de los valores de coma flotante de las coordenadas xey de cada punto.
Por ejemplo, 3 3,7 5 2 4 2,5 1,5 significa un triángulo compuesto por tres puntos. La segunda línea representa las coordenadas del punto a juzgar, como 1,5 8,3

Salida:
Devuelve 0 si el punto está dentro del polígono, 1 si está en el polígono y 2 si está fuera del polígono.

Código:

#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;
}

Supongo que te gusta

Origin blog.csdn.net/holly_Z_P_F/article/details/133343750
Recomendado
Clasificación