1. Descripción del problema
Dado el punto P(x,y) y el polígono polígono, determina si el punto P(x,y) está dentro del polígono.
Dos, la solución
método de rayos x
Con el punto P como punto final, dibuja un rayo L a la izquierda Como el polígono está acotado, el extremo izquierdo del rayo L debe estar fuera del polígono. Considere moverse de izquierda a derecha a lo largo de L desde la nada. Cuando encuentre el primer punto de intersección con el polígono, ingresará al interior del polígono. Cuando encuentre el segundo punto de intersección, dejará el polígono. Por tanto, cuando el número de intersección C de L y el polígono es impar, P está dentro del polígono, y si es par, entonces P está fuera del polígono.
El análisis de casos especiales se muestra en la figura (a), (b), (c) y (d) a continuación.
1 En la figura (a), L se cruza con los vértices del polígono y solo se puede calcular un punto de intersección.
2 En la figura (b), no se debe calcular la intersección de L y los vértices del polígono.
3 En las Figuras (c) y (d), L coincide con un lado del polígono, y este lado debe ignorarse.
3. Implementación del código
//判断点是否在多边形内部/
// The function will return YES if the point x,y is inside the polygon, or
// NO if it is not. If the point is exactly on the edge of the polygon,
// then the function may return YES or NO.
bool IsPointInPolygon(const std::vector<cv::Point> &poly, const cv::Point &pt)
{
int i, j;
bool c = false;
int count = poly.size();
for (i = 0, j = count - 1; i < count; j = i++)
{
if ((((poly[i].y <= pt.y) && (pt.y < poly[j].y)) ||
((poly[j].y <= pt.y) && (pt.y < poly[i].y)))
&& (pt.x < (poly[j].x - poly[i].x) * (pt.y - poly[i].y) / (poly[j].y - poly[i].y) + poly[i].x))
{
c = !c;
}
}
return c;
}
análisis de código
Condición 1
((ploy[i].y <= pt.y) && (pt.y < poly[j].y)) || ((ploy[j].y <= pt.y) && (pt.y < poly[i].y))
Dado que el proceso de juicio es principalmente para juzgar si hay un punto de intersección entre el rayo L y cada lado del polígono, y el rayo L es paralelo al eje X, la condición 1 es equivalente a juzgar que el punto P está entre Pi y Pj en la distancia vertical.
Condición 2
(pt.x < (poli[j].x - poli[i].x) * (pt.y - poli[i].y)/(poli[j].y - poli[i].y) + poli[i].x)
La condición 2 se puede transformar en: (pt.x - poly[i].x) * (poly[j].y - poly[i].y) - (poly[j].x - poly[i].x ) * (pt.y - poly[i].y) < 0, que es equivalente al producto vectorial del vector PiP y el vector PiPj.
Cuando el producto vectorial del vector PiP y el vector PiPj es menor que 0, el vector PiP está en la dirección contraria a las manecillas del reloj del vector PiPj, lo que significa que el vector PiP está en el lado derecho del vector PiPj, y el rayo L se emite desde el lado izquierdo, y el punto P está entre Pi y Pj. Por lo tanto, la distancia perpendicular entre la condición de cruce de los rayos L y PiPj se corta.