Algoritmo GJK, detección de colisiones (notas de autoaprendizaje, infracción eliminada)

Aprenda 哔哩哔哩 "Problemas complejos aparentemente simples, soluciones extrañas y elegantes (algoritmo GJK) |

 

1. Los conceptos básicos de formas convexas y cóncavas.

Todos los gráficos se pueden dividir en dos tipos: convexos y cóncavos, como se muestra en la Figura 1.1.

Figura 1.1 Formas convexas y cóncavas

 Las propiedades de una forma convexa son:

  1. La línea que conecta dos puntos cualesquiera de la forma debe estar dentro de la forma, que es más fácil de manejar que una forma cóncava.
  2. Para cada punto de su forma, debe haber una dirección tal que el televisor sea el punto más lejano en esta dirección. Es decir, atravesar todas las direcciones posibles de la forma y encontrar el punto más lejano en la dirección inevitablemente obtendrá todos los puntos de la forma.

La forma cóncava no obedece a las características anteriores, por lo que al tratarse de la forma cóncava, se puede dividir en múltiples formas convexas para simplificar el cálculo, por lo que todos los juicios de intersección entre formas pueden transformarse en el problema de intersección de formas convexas.

Figura 1.2 La forma cóncava se transforma en múltiples formas convexas

2. Las características relevantes de la intersección de dos formas.

La razón por la que aparece el concepto de "origen" en el juicio de la intersección de dos formas se muestra en la figura 2.1. Cuando dos formas convexas se cortan, debe haber dos puntos (vectores) cuya diferencia sea el origen, y esto también prueba que hay una intersección entre los dos.

Figura 2.1 La relación entre la intersección de dos formas y el origen

El método de solución de "origen" mencionado anteriormente propone además el concepto de sumas/diferencias de Minkowski (sumas/diferencias de Minkowski).

2.1 suma/diferencia de Minkowski

Suma de Minkowski: Suma todos los puntos dentro de una forma a todos los puntos dentro de otra forma. Y cada punto de cada forma se trata como un vector a partir del origen.

Diferencia de Minkowski: resta todos los puntos dentro de una forma de todos los puntos dentro de otra forma.

Figura 2.2 Minkowski y

Figura 2.3 Diferencia de Minkowski

La diferencia de Minkowski también tiene las siguientes dos propiedades:

  1. La forma obtenida por la diferencia de Minkowski de dos formas convexas también es convexa, de acuerdo con la naturaleza de la forma convexa, esto significa que la línea de dos puntos cualesquiera debe existir en la diferencia de Minkowski;
  2. Cuando dos formas se cruzan, su diferencia de Minkowski debe contener el origen, es decir, al menos las dos formas tienen al menos un punto en común (el mismo principio que en la Figura 3);

 Por lo tanto, el problema de juzgar la intersección de dos formas se convierte en un problema de juzgar si la diferencia de Minkowski de dos formas incluye el origen.

Seleccione la diferencia de tres puntos en dos formas convexas A y B para formar un triángulo (estos tres lados deben estar en la diferencia de Minkowski); cuando el origen está incluido en el triángulo, significa que el origen también debe existir en la diferencia de Minkowski , y luego se puede juzgar que las formas A y B se intersecan.

Figura 2.4 El origen del triángulo contiene la relación de intersección con las formas convexas A y B

Por lo tanto, el problema de juzgar la intersección de dos formas se puede simplificar aún más si se pueden encontrar tres puntos en la diferencia de Minkowski de formas convexas A y B para formar un triángulo cerca del origen (es decir, un triángulo que contiene el origen), como se muestra en la Figura 2.5. Este triángulo se llama símplex.

Figura 2.5 Simplificación de problemas de intersección y triángulo

2.2 Fila única (símplex)

En diferentes dimensiones, la forma de una sola fila no es la misma. En 2D, una sola fila es un triángulo; en 3D, una sola fila es un tetraedro.

Figura 2.6 Introducción de una sola fila

2.3 Función de soporte (función de soporte)

De acuerdo con la característica 2 de la forma convexa, la dirección se puede asignar al punto de la forma convexa, y la función que asigna el vector de dirección al punto más lejano de la forma se llama función de soporte, y el punto correspondiente se llama el punto de apoyo.

El punto muy interesante de esta función de soporte es que la suma de dos funciones de soporte convexas puede obtener la función de soporte y el punto de soporte de su suma de Minkowski.

Figura 2.7 La relación entre la función de soporte convexa, punto de soporte y la función de soporte de suma de Minkowski, punto de soporte

 Al enfrentar la diferencia de Minkowski, especifique la dirección del vector de la primera forma convexa A para encontrar su punto de apoyo; luego use la dirección opuesta a esta dirección como la dirección en la segunda forma convexa B para encontrar el punto de apoyo en la forma convexa B . La resta de estos dos puntos es el punto de apoyo en el límite de diferencia de Minkowski. Esto es útil para encontrar triángulos que contengan el origen en la diferencia de Minkowski.

Figura 2.8 Relación entre el punto de apoyo convexo y el punto de apoyo de la diferencia de Minkowski

 Curiosamente, al observar la Figura 2.7-2.8, se puede encontrar que al encontrar los puntos de apoyo de la suma de Minkowski, las direcciones seleccionadas en las formas convexas A y B son las mismas, y al encontrar los puntos de apoyo de la diferencia de Minkowski, el forma convexa A , La dirección seleccionada en B es horizontalmente opuesta. La fuente de esta diferencia tiene que ver con la definición de Minkowski y \pobre en sí misma.

Cálculo de la función de soporte: 

La función de soporte devuelve el punto v más lejano en la dirección d especificada por el borde convexo. Como se muestra en la fórmula de la figura 2.9, el producto escalar puede medir la similitud direccional entre dos vectores. Cuanto más similares sean las direcciones de los dos vectores, mayor será el valor del producto escalar y cuanto más lejos esté el punto en una dirección tendrá un producto escalar más alto. Esta propiedad permite resolver los puntos de apoyo.

Figura 2.9 Cálculo de la Función de Soporte

3. Algoritmo GJK y sus detalles de implementación

3.1 Algoritmo GJK

1. Primero, selecciona una dirección aleatoria y encuentra el punto de apoyo en esta dirección, que es el primer punto del símplex.

2. Tome el punto de soporte actual como el punto inicial del vector, encuentre el vector que apunta al origen como la nueva dirección d y encuentre el segundo punto de soporte.

3. Determine si el resultado del producto escalar del segundo punto de apoyo y la dirección actual d es menor que 0. A través de la naturaleza del producto escalar, podemos saber que el producto escalar de los dos vectores requeridos no es menor que 0, y el ángulo entre los dos vectores es [0°, 90°]. Si las dos formas se intersecan, el ángulo entre el vector formado por el origen y el segundo punto de apoyo y la dirección actual d es [0°, 90° ], y se muestra el rango razonable de la posición del segundo punto de apoyo en el área azul de la Figura 3.0.

        1) Si el producto punto del segundo punto de apoyo y la dirección d es menor que 0, significa que no hay ningún punto de apoyo que pueda cruzar el origen en la dirección de iteración actual, es decir, el segundo punto de apoyo no cae en el área azul de la Figura 3.0, las dos formas no se cruzan, salga del algoritmo GJK.

        2) Por el contrario, agregue el segundo punto de apoyo actual al símplex.

4. Si el segundo punto de apoyo es razonable, entonces los dos puntos de apoyo se conectan en una línea recta, y el vector perpendicular a la línea es la nueva dirección d, y el nuevo punto de apoyo se calcula para formar un triángulo.

5. Compruebe si el triángulo actual contiene el origen. Si es así, las dos formas se cruzan; de lo contrario, actualice la orientación, agregando un nuevo punto de apoyo. Seleccione el vector vertical del lado del triángulo cuya distancia es la más cercana al origen y mantenga dos puntos en este lado, elimine el punto restante y use este vector vertical como la nueva dirección d para encontrar el tercer punto de apoyo nuevamente, haga lo siguiente tiempo Iteración y juicio.

Figura 3.0 El área razonable del segundo punto de apoyo que puede cruzar el origen (parte azul)

 

3.2 Detalles de implementación 

pregunta:

  1. ¿Cómo sabes si un punto en la diferencia de Minkowski cruza el origen?
  2. ¿Cómo elegimos una nueva dirección cuando tenemos dos puntos?
  3. ¿Cómo podemos detectar si el triángulo actualmente formado contiene el origen?
  4. ¿Cómo elegimos la siguiente dirección si el triángulo actual no contiene el origen?

Pregunta 1: ¿Cómo saber si un punto de la diferencia de Minkowski cruza el origen?

Compruebe si un punto A pasa por el origen de la manera que se muestra en la figura 3.1. Desde el origen, el punto A se considera un vector, juzgado por el producto escalar entre el vector y la dirección d, cuando el producto escalar es negativo, el punto actual no pasa por el origen; de lo contrario, viceversa.

Figura 3.1 Criterios para juzgar que el punto actual pasa el origen

 Pregunta 2: ¿Cómo elegimos una nueva dirección cuando tenemos dos puntos?

En primer lugar, cuando tenemos dos puntos, el punto A suele ser el último punto añadido y el punto B es el primer punto añadido. Primero construimos el vector AO(OA) y el vector AB(BA), y resolvemos el vector perpendicular a estos dos vectores y vertical hacia arriba multiplicando en cruz los dos vectores; en segundo lugar, resolvemos un vector vertical y un vector AB Vector (producto triple). Esta es la nueva dirección que mencionamos d.

Figura 3.2 Método para seleccionar una nueva dirección basada en dos puntos
Figura 3.3 Método de cálculo de la nueva dirección d

Pregunta 3 y Pregunta 4: ¿Cómo detectar si el triángulo formado actualmente contiene el origen? ¿Cómo elegimos la siguiente dirección si el triángulo actual no contiene el origen?

Supongamos que tenemos tres puntos A, B y C (donde A suele ser el último punto de apoyo añadido) formando un triángulo, y trazamos una línea vertical a cada lado del triángulo para definir el área del espacio, formando el área de Voronoi; asumiendo que los puntos B 1 y C son fijos, dadas todas las posiciones posibles del punto A, el área correspondiente también cambiará. Para determinar en qué áreas es probable que termine el origen, debemos analizarlo.

Figura 3.4 Región de Voronoi

3.1 Regiones que no pueden contener el origen y su análisis:

Rc: Dado que el punto de apoyo C es el primer punto de apoyo, cuando queremos seleccionar el siguiente punto de apoyo, debemos tomar el punto C como punto de partida y apuntar al origen como la próxima nueva dirección d para encontrar el punto de apoyo, que significa que debemos buscar hacia el origen en sentido contrario a Rc, por lo que el origen no puede estar en Rc.

Rb: cuando el origen está en Rb, significa que el punto B no puede exceder el origen, porque el simplex actual no es válido y el punto B actualmente seleccionado no es válido.

Ra: cuando el origen está en Ra, significa que el punto A no puede exceder el origen, porque el simplex actual no es válido y el punto A actualmente seleccionado no es válido.

Figura 3.5 Detección y análisis de áreas

Rbc: La línea vertical en la dirección de BC se usa para encontrar el punto A, que es completamente opuesto a la dirección de Rbc, porque Rbc no puede contener el origen. 

3.2 Es necesario verificar si la región que contiene el origen y su análisis:

Rab: Si el punto A se convierte en un punto válido, cruzará el origen en una dirección dada (es decir, incluirá el origen), entonces el área donde se encuentra el punto A se muestra en la Figura 3.6. En este rango, Rab tiene el potencial de contener el origen.

Figura 3.6 El área donde se encuentra el punto efectivo A

 Para verificar la conjetura anterior, se define un vector perpendicular a AB mediante el teorema del triple producto, cuando el producto escalar del vector vertical actual y el vector A0 es mayor que 0, significa que el origen está en Rab, por lo que la corriente simplex no es adecuado Necesitamos volver a seleccionar y actualizar este simplex, eliminamos el punto C del simplex, el vector perpendicular a AB se usa como la nueva dirección d para encontrar el tercer punto de apoyo, por lo que Rab tiene que verificar.

Figura 3.7 Lógica de verificación de Rab

 Rac: La lógica de comprobación de esta zona es similar a la de Rab. Cuando el origen está en Rac, eliminamos el punto B actual y volvemos a seleccionar el punto.

Figura 3.8 Lógica de verificación de Rac

Uno de los controles de área más importantes:

Solo se controlan dos áreas, Rab y Rac. Cuando ni la región Rab ni la Rac contienen el origen, es decir, cuando el producto escalar del vector perpendicular a AB y AC y el vector AO es menor que 0, significa que el origen actual está en el resto de Rabc.

Figura 3.9 El método para juzgar si el origen está en Rabc

3.3 Detalles del algoritmo GJK 

def GJK(s1,s2)
#两个形状s1,s2相交则返回True。所有的向量/点都是三维的,例如([x,y,0])
#第一步:选择一个初始方向,这个初始方向可以是随机选择的,但通常来说是两个形状中心之间的向量,即:
    d= normalize(s2.center-s1.center)
#第二步:找到支撑点,即第一个支撑点
    simplex=[support(s1,s2,d)]
#第三步:找到第一个支撑点后,以第一个支撑点为起点指向原点O的方向为新方向d
     d=ORIGIN-simplex[0]
#第四步:开始循环,找下一个支撑点
    while True
        A=[support(s1,s2,d)]
#当新的支撑点A没有经过原点,那我们就返回False,即两个形状没有相交
        if dot(A,d) <0:
            return False
#否则,我们就将该点A加入到simplex中
        simplex.append(A)
#handleSimplex负责主要逻辑部分。主要负责处理寻找新方向和更新simplex的逻辑内容,当当前simplex包含原点,则返回Ture
        if handleSimplex(simplex,d):
            return Ture

def handleSimplex(simplex,d)
#如果当前的simplex为直线情况,则进入lineCase(simplex,d)函数,寻找下一个方向d,并返回False,即直线情况下的simplex不包含原点
    if len(simplex==2):
        return lineCase(simplex,d)
#如果当前的simplex为三角情况,则进入triangleCase(simplex,d,
    return triangleCase(simplex,d)

def  lineCase(simplex,d)
#构建向量AB与AO,并使用三重积得到下一个方向
    B,A = simplex
    AB,AO=B-A,ORIGIN-A
    ABprep= tripleProd(AB,AO,AB)
    d.set(ABprep)
#由于一条直线的情况下,原点不能包含在simplex中,所以返回False
    return False

def triangleCase(simplex,d)
#构建向量AB,AC与AO,并来检测原点在空间的哪个区域。
    C,B,A = simplex
    AB,AC,AO=B-A,C-A,ORIGIN-A
#通过三重积分别得到垂直于AB、AC的向量,检测区域Rab、Rac中是否包含原点。
    ABprep= tripleProd(AC,AB,AB)
    ACprep= tripleProd(AB,AC,AC)
#如果原点在AB区域中,我们移除点C以寻找更加完美的simplex,新的方向就是垂直于AB的向量
    if dot(ABprep,AO)>0:
       simplex.remove(C);d.set(ABprep) 
       return False
#如果原点在AC区域中,我们移除点B以寻找更加完美的simplex,新的方向就是垂直于AC的向量
    elif dot(ACprep,AO)>0:
       simplex.remove(Ba);d.set(ACprep) 
       return False
#如果这两种情况都不符合,那就说明当前的三角形中包含原点,两个形状相交
    return Ture

def support(s1,s2,d)
#取第一个形状上方向d上最远点并减去第二个形状上相反反向(-d)上最远的点
    return s1.furthestPoint(d)-s2.furthestPoint(-d)

Solo para fortalecer mi comprensión y memoria, si se trata de problemas de infracción, comuníquese conmigo y lo eliminaré ~

Supongo que te gusta

Origin blog.csdn.net/qwerpoiu66/article/details/131370634
Recomendado
Clasificación