Estoy tratando de encontrar si un rectángulo cruza un polígono cóncavo. ¿Tiene este algoritmo lograr eso?

votos
7

Estoy tratando de encontrar si un rectángulo cruza un polígono cóncavo. He encontrado este algoritmo:

double determinant(Vector2D vec1, Vector2D vec2){
    return vec1.x*vec2.y-vec1.y*vec2.x;
}

//one edge is a-b, the other is c-d
Vector2D edgeIntersection(Vector2D a, Vector2D b, Vector2D c, Vector2D d){
    double det=determinant(b-a,c-d);
    double t=determinant(c-a,c-d)/det;
    double u=determinant(b-a,c-a)/det;
    if ((t<0)||(u<0)||(t>1)||(u>1))return NO_INTERSECTION;
    return a*(1-t)+t*b;
}

Si realizo esto 4 veces (de arriba a derecha, de arriba a abajo a la izquierda, de arriba a abajo a la derecha, abajo a la derecha) * (todos los bordes de mi polígono) sería de manera eficaz y precisa dime si el rectángulo tiene parte o toda la cóncava polígono interior? Si no es lo que le faltaría?

Gracias

Publicado el 11/08/2010 a las 23:05
fuente por usuario
En otros idiomas...                            


3 respuestas

votos
2

Creo que el siguiente debería funcionar:

(1) for each e1 in rectangle_edges, e2 in polygon_edges
    (1.1) if edgeIntersection(e1,e2) != NO_INTERSECTION
        (1.1.1) return true
(2) if (max_polygon_x < max_rectangle_x) and (min_polygon_x > min_rectangle_x) and (max_polygon_y < max_rectangle_y) and (min_polygon_y > min_rectangle_y)
    (2.1) return true
(2) return false

Editar : comprobación añadida de si el polígono está dentro del rectángulo.

Respondida el 11/08/2010 a las 23:12
fuente por usuario

votos
13

El código intenta encontrar el punto de intersección de dos segmentos - AB y CD.

Hay muchas maneras diferentes para explicar la forma en que lo está haciendo, dependiendo de cómo se interprete estas operaciones.

Digamos que el punto A tiene coordenadas (xa, ya), B - (xb, yb) y así sucesivamente. Digamos

dxAB = xb - xa
dyAB = yb - ya
dxCD = xd - xc
dyCD = yd - yc

El siguiente sistema de dos ecuaciones lineales

| dxAB dxCD |   | t |   | xc-xa |
|           | * |   | = |       |
| dyAB dyCD |   | u |   | yc-ya |

si resuelve para ty u, le dará la posición proporcional del punto de intersección de la línea AB (valor t) y en la línea CD (valor u). Estos valores se encuentran en el rango de [0, 1]si el punto pertenece al segmento correspondiente y fuera de ese rango si el punto se encuentra fuera del segmento (en la línea que contiene el segmento).

Con el fin de resolver este sistema de ecuaciones lineales que podemos utilizar la conocida regla de Cramer . Para que vamos a necesitar el determinante de

| dxAB dxCD |
|           |
| dyAB dyCD |

que es exactamente determinant(b - a, c - d)desde el código. (En realidad, lo que tengo aquí es determinant(b - a, d - c), pero no es realmente importante para los propósitos de esta explicación. El código que envió por alguna razón intercambia C y D, véase la nota de la EP más abajo).

Y también necesitaremos determinante de

| xc-xa dxCD |
|            |
| yc-ya dyCD |

que es exactamente determinant(c-a,c-d)de su código y determinante de

| dxAB xc-xa |
|            |
| dyAB yc-ya |

que es exactamente determinant(b-a,c-a).

La división de estos determinantes de conformidad con la regla de Cramer nos dará los valores de ty u, que es exactamente lo que se hace en el código que envió.

El código procede entonces a prueba los valores de ty upara verificar si los segmentos realmente se cruzan, es decir, si ambos ty upertenecen a [0, 1]oscilar. Y si lo hacen, se calcula el punto de intersección real mediante la evaluación a*t+b*(1-t)(que es equivalente, se podría evaluar c*u+d*(1-u)). (Una vez más, consulte la nota de la EP más abajo).

PS En el código original de los puntos D y C se "intercambian" en un sentido que hace el código c - d, donde hago d - cen mi explicación. Pero esto no hace ninguna diferencia para la idea general del algoritmo, siempre y cuando uno de cuidado con los signos.

Este intercambio del punto C y D es también la razón de a*(1-t)+t*bla expresión se utiliza cuando se evalúa el punto de intersección. Normalmente, como en mi explicación, one'd esperar ver algo como a*t+b*(1-t)allí. (Tengo mis dudas acerca de esto, sin embargo. Yo esperaría a ver a*t+b*(1-t)allí, incluso en su versión. Podría ser un error.)

PPS El autor si el código se olvidó de comprobar det == 0(o muy cerca a 0), lo que sucederá en el caso cuando los segmentos son paralelos.

Respondida el 11/08/2010 a las 23:30
fuente por usuario

votos
0

Por lo que yo puedo decir después de un rápido vistazo, se trata de determinar si 2 segmentos de línea se cruzan, y si lo hacen, lo que las coordenadas del punto de intersección son.

No, no es lo suficientemente bueno como para determinar si su rectángulo y su polígono se cruzan, ya que todavía faltaría el caso en que sea el polígono está completamente dentro del rectángulo, o al revés.

Respondida el 11/08/2010 a las 23:56
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more