Determine si los dos segmentos de línea se cruzan y encuentre el punto de intersección

 

 

Primero, el esquema anterior.

Según la ilustración, el segmento de línea a se representa como los puntos finales a1 y a2, y el segmento de línea b se representa como los puntos finales b1 y b2. Para utilizar la relación de producto cruzado de los vectores, los puntos finales del segmento de línea se consideran como cuatro vectores, y los vectores se representan en negrita a continuación. De acuerdo con las operaciones vectoriales Se puede ver que 
a = a2-a1, 
b = b2-b1. 
Exprese el segmento de recta como una ecuación paramétrica: 
a = a1 + ta 
b = b1 + ub 
donde los parámetros t, u toman el valor [0,1]

La intersección de dos segmentos de línea tiene la siguiente relación: 
a1 + ta = b1 + ub 
. Multiplica ambos lados de la ecuación anterior por b al mismo tiempo para obtener: 
(a1 + ta) xb = (b1 + ub) xb 
Dado que bxb = 0, podemos obtener 
a1 xb + taxb = b1 xb 
resuelve el parámetro t 
t = (b1-a1) xb / (axb) lo 
mismo, resuelve el parámetro u 
u = ax (a1-b1) / (axb)

Cuando 0 <= t <= 1 y 0 <= u <= 1, los dos segmentos de recta tienen intersecciones. 
Sustituyendo en la ecuación paramétrica del segmento de recta a, puede obtener las coordenadas de intersección del segmento de recta: 
a1 + ta 
usa el intermedio variable en la fórmula anterior La representación del punto final del segmento de línea original puede obtener el punto de intersección representado por el punto final del segmento de línea.

codigo 1

// Devuelve 1 si las líneas se cruzan, en caso contrario 0. Además, si las líneas 
// se cruzan, el punto de intersección puede almacenarse en los flotadores i_x e i_y.
char get_line_intersection (float p0_x, float p0_y, float p1_x, float p1_y, 
    float p2_x, float p2_y, float p3_x, float p3_y, float * i_x, float * i_y)
{     float s1_x, s1_y, s2_y;     s1_x = p1_x - p0_x; s1_y = p1_y - p0_y;     s2_x = p3_x - p2_x; s2_y = p3_y - p2_y;


    float s, t;
    s = (-s1_y * (p0_x - p2_x) + s1_x * (p0_y - p2_y)) / (-s2_x * s1_y + s1_x * s2_y);
    t = ( s2_x * (p0_y - p2_y) - s2_y * (p0_x - p2_x)) / (-s2_x * s1_y + s1_x * s2_y);

    if (s> = 0 && s <= 1 && t> = 0 && t <= 1)
    {         // Colisión detectada         if (i_x! = NULL)             * i_x = p0_x + (t * s1_x);         if (i_y! = NULL)             * i_y = p0_y + (t * s1_y);         return 1;     }






    return 0; // Sin colisión
}
código 2

Versión optimizada para excluir segmentos de línea paralelos y evitar errores de precisión

int get_line_intersection (float p0_x, float p0_y, float p1_x, float p1_y, 
    float p2_x, float p2_y, float p3_x, float p3_y, float * i_x, float * i_y)
{     float s02_x, s02x, s10_y, s_n , t_numer, denom, t;     s10_x = p1_x - p0_x;     s10_y = p1_y - p0_y;     s32_x = p3_x - p2_x;     s32_y = p3_y - p2_y;




    denom = s10_x * s32_y-s32_x * s10_y;
    if (denom == 0) //
        Retorno paralelo o colineal 0; //
    Colineal bool denomPositive = denom> 0;

    s02_x = p0_x-p2_x;
    s02_y = p0_y-p2_y;
    s_numer = s10_x * s02_y-s10_y * s02_x;
    if ((s_numer <0) == denomPositive) // Los parámetros deben ser mayores o iguales a 0 y menores o iguales a 1, y el numerador y el denominador deben ser el mismo Número y el numerador es menor o igual que el denominador
        devuelve 0; // Sin colisión

    t_numer = s32_x * s02_y - s32_y * s02_x;
    if ((t_numer <0) == denomPositive)
        return 0; // No hubo colisión

    if (fabs (s_numer)> fabs (denom) || fabs (t_numer)> fabs (denom))
        return 0; // Sin colisión
    // Colisión detectada
    t = t_numer / denom;
    si (i_x! = NULL)
        * i_x = p0_x + (t * s10_x);
    if (i_y! = NULL)
        * i_y = p0_y + (t * s10_y);

    return 1;
}

Supongo que te gusta

Origin blog.csdn.net/u011105442/article/details/88746870
Recomendado
Clasificación