判斷兩條線段是否相交


之前一篇文章里寫了一種差乘判斷方法:http://www.cnblogs.com/hont/p/6105997.html

雖然用3D空間的差乘,但是只適用於2D空間

 

bool IsIntersection(Vector3 a, Vector3 b, Vector3 c, Vector3 d)
{
    var crossA = Mathf.Sign(Vector3.Cross(d - c, a - c).y);
    var crossB = Mathf.Sign(Vector3.Cross(d - c, b - c).y);

    if (Mathf.Approximately(crossA, crossB)) return false;

    var crossC = Mathf.Sign(Vector3.Cross(b - a, c - a).y);
    var crossD = Mathf.Sign(Vector3.Cross(b - a, d - a).y);

    if (Mathf.Approximately(crossC, crossD)) return false;

    return true;
}

 

 

后來我找到了另一個封裝好的函數,不僅可以判斷相交而且能查到是否相交於虛交點,是否平行等等。

原版的編寫語言是java,但出處弄丟了

 

以下是我修改的Unity版本:

public static int GetIntersection(Vector3 a, Vector3 b, Vector3 c, Vector3 d, out Vector3 contractPoint)
{
    contractPoint = new Vector3(0, 0);

    if (Mathf.Abs(b.z - a.z) + Mathf.Abs(b.x - a.x) + Mathf.Abs(d.z - c.z)
            + Mathf.Abs(d.x - c.x) == 0)
    {
        if ((c.x - a.x) + (c.z - a.z) == 0)
        {
            //Debug.Log("ABCD是同一個點!");
        }
        else
        {
            //Debug.Log("AB是一個點,CD是一個點,且AC不同!");
        }
        return 0;
    }

    if (Mathf.Abs(b.z - a.z) + Mathf.Abs(b.x - a.x) == 0)
    {
        if ((a.x - d.x) * (c.z - d.z) - (a.z - d.z) * (c.x - d.x) == 0)
        {
            //Debug.Log("A、B是一個點,且在CD線段上!");
        }
        else
        {
            //Debug.Log("A、B是一個點,且不在CD線段上!");
        }
        return 0;
    }
    if (Mathf.Abs(d.z - c.z) + Mathf.Abs(d.x - c.x) == 0)
    {
        if ((d.x - b.x) * (a.z - b.z) - (d.z - b.z) * (a.x - b.x) == 0)
        {
            //Debug.Log("C、D是一個點,且在AB線段上!");
        }
        else
        {
            //Debug.Log("C、D是一個點,且不在AB線段上!");
        }
        return 0;
    }

    if ((b.z - a.z) * (c.x - d.x) - (b.x - a.x) * (c.z - d.z) == 0)
    {
        //Debug.Log("線段平行,無交點!");
        return 0;
    }

    contractPoint.x = ((b.x - a.x) * (c.x - d.x) * (c.z - a.z) -
            c.x * (b.x - a.x) * (c.z - d.z) + a.x * (b.z - a.z) * (c.x - d.x)) /
            ((b.z - a.z) * (c.x - d.x) - (b.x - a.x) * (c.z - d.z));
    contractPoint.z = ((b.z - a.z) * (c.z - d.z) * (c.x - a.x) - c.z
            * (b.z - a.z) * (c.x - d.x) + a.z * (b.x - a.x) * (c.z - d.z))
            / ((b.x - a.x) * (c.z - d.z) - (b.z - a.z) * (c.x - d.x));

    if ((contractPoint.x - a.x) * (contractPoint.x - b.x) <= 0
            && (contractPoint.x - c.x) * (contractPoint.x - d.x) <= 0
            && (contractPoint.z - a.z) * (contractPoint.z - b.z) <= 0
            && (contractPoint.z - c.z) * (contractPoint.z - d.z) <= 0)
    {

        //Debug.Log("線段相交於點(" + contractPoint.x + "," + contractPoint.z + ")!");
        return 1; // '相交  
    }
    else
    {
        //Debug.Log("線段相交於虛交點(" + contractPoint.x + "," + contractPoint.z + ")!");
        return -1; // '相交但不在線段上  
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM