Search code examples
c#unity-game-enginevectorlineintersection

Check when two Vector3 lines intersect - Unity3D


I want to know when four Vector 3 positions intersect, as in the image, from point to point a1 to a2 and b1 to b2 if they intersect each other from each of their positions. Does anyone have any idea how to do this?

enter image description here


Solution

  • The Unity community wiki has a page of math functions that includes a very helpful procedure for this. Copied (and edited slightly) below:

    public static bool LineLineIntersection(out Vector3 intersection, Vector3 linePoint1,
            Vector3 lineVec1, Vector3 linePoint2, Vector3 lineVec2){
    
        Vector3 lineVec3 = linePoint2 - linePoint1;
        Vector3 crossVec1and2 = Vector3.Cross(lineVec1, lineVec2);
        Vector3 crossVec3and2 = Vector3.Cross(lineVec3, lineVec2);
    
        float planarFactor = Vector3.Dot(lineVec3, crossVec1and2);
    
        //is coplanar, and not parallel
        if( Mathf.Abs(planarFactor) < 0.0001f 
                && crossVec1and2.sqrMagnitude > 0.0001f)
        {
            float s = Vector3.Dot(crossVec3and2, crossVec1and2) 
                    / crossVec1and2.sqrMagnitude;
            intersection = linePoint1 + (lineVec1 * s);
            return true;
        }
        else
        {
            intersection = Vector3.zero;
            return false;
        }
    }
    

    So, in your situation, you could use that, then check if the intersection point is between a1 and a2 and b1 and b2:

    Vector3 intersection;
    Vector3 aDiff = a2-a1;
    Vector3 bDiff = b2-b1;
    if (LineLineIntersection(out intersection, a1, aDiff, b1, bDiff))
    {
        float aSqrMagnitude = aDiff.sqrMagnitude;
        float bSqrMagnitude = bDiff.sqrMagnitude;
    
        if (    (intersection - a1).sqrMagnitude <= aSqrMagnitude  
             && (intersection - a2).sqrMagnitude <= aSqrMagnitude  
             && (intersection - b1).sqrMagnitude <= bSqrMagnitude 
             && (intersection - b2).sqrMagnitude <= bSqrMagnitude)
        {
            // there is an intersection between the two segments and 
            //   it is at intersection
        }
    }