Vectores geométricos: intersección de líneas no paralelas en un plano bidimensional (corrección)

      Hoy de repente descubrí que había un problema con la intersección de planos y líneas no paralelas antes, estaba demasiado relacionado con el blog anterior, por lo que tuve que escribir un artículo especial para la corrección de errores.
      Solo se puede decir que nunca antes me había encontrado con una situación así, es increíble, el código es el siguiente:

    /// <summary>
    /// 计算两射线交点
    /// </summary>
    /// <param name="p1"></param>
    /// <param name="p2"></param>
    /// <param name="p4"></param>
    /// <param name="p3"></param>
    /// <returns></returns>
    private Vector2 CalculateLineCross(Vector2 p1, Vector2 p2, Vector2 p4, Vector2 p3)
    {
    
    
        //构建直线参数k和a
        float k1 = (p2.y - p1.y) / (p2.x - p1.x);
        float a1 = p2.y - k1 * p2.x;

        float k2 = (p3.y - p4.y) / (p3.x - p4.x);
        float a2 = p3.y - k2 * p3.x;
        //根据求解计算交点
        float y = (k2 * a1 - k1 * a2) / (k2 - k1);
        float x = 0;
        if (k1 != 0)
        {
    
    
            x = (y - a1) / k1;
        }
        else if (k2 != 0)
        {
    
    
            x = (y - a2) / k2;
        }
        return new Vector2(x, y);
    }

      Vea el problema, si (p2.x - p1.x), o (p3.x - p4.x) es igual a 0, entonces la pendiente k no existe, y el resultado calculado en base a esta pendiente k inexistente es incorrecto.
      Sin embargo, el denominador de la operación matemática de C# = 0 no informa un error, y el escenario de desarrollo real no encuentra el resultado del cálculo de que la pendiente k no existe, por lo que se ignora.
      Entonces ahora tenemos que completar la adaptabilidad de este cálculo, y usar el sistema de ecuaciones lineales para resolverlo, de la siguiente manera:
inserte la descripción de la imagen aquí
      Luego solo necesitamos construir los parámetros de la ecuación lineal a través de cuatro coordenadas, de la siguiente manera:
inserte la descripción de la imagen aquí

      Luego construye el algoritmo:

 /// <summary>
    /// 计算平面直线相交
    /// </summary>
    /// <param name="p1"></param>
    /// <param name="p2"></param>
    /// <param name="p4"></param>
    /// <param name="p3"></param>
    /// <returns></returns>
    private Vector2 CalculateLineCross(Vector2 p1, Vector2 p2, Vector2 p4, Vector2 p3)
    {
    
    
        float[] abc1 = GetLineEquationParams(p1, p2);
        float[] abc2 = GetLineEquationParams(p4, p3);

        float a1 = abc1[0], b1 = abc1[1], c1 = abc1[2];
        float a2 = abc2[0], b2 = abc2[1], c2 = abc2[2];

        float x = (c2 * b1 - c1 * b2) / (a1 * b2 - a2 * b1);
        float y = (c2 * a1 - c1 * a2) / (b1 * a2 - b2 * a1);

        return new Vector2(x, y);
    }
    /// <summary>
    /// 构建平面直线方程参数A、B、C
    /// </summary>
    /// <param name="p1"></param>
    /// <param name="p2"></param>
    /// <returns></returns>
    private float[] GetLineEquationParams(Vector2 p1, Vector2 p2)
    {
    
    
        float a, b, c;
        //L1
        if (p1.y == p2.y)
        {
    
    
            a = 0;
            b = 1;
            c = -p1.y;
        }
        //L2
        else if (p1.x == p2.x)
        {
    
    
            a = 1;
            b = 0;
            c = -p1.x;
        }
        //L3
        else
        {
    
    
            float k = (p2.y - p1.y) / (p2.x - p1.x);
            //y-y1=k(x-x1)
            a = k;
            b = -1;
            c = p1.y - k * p1.x;
        }
        return new float[] {
    
     a, b, c };
    }

      Recién probado con el proyecto real, el efecto es el siguiente:
inserte la descripción de la imagen aquí      Este es el método de corrección para la intersección de líneas planas no paralelas.

Supongo que te gusta

Origin blog.csdn.net/yinhun2012/article/details/124752375
Recomendado
Clasificación