0
\$\begingroup\$

I'm using the following method to determine the intersection point of two vector2:

public static Vector2 LineIntersectionPoint(Vector2 startPoint1, Vector2 endPoint1, Vector2 startPoint2, Vector2 endPoint2)
{
    // Get A,B,C of first line - points : startPoint1 to endPoint1
    float A1 = endPoint1.y - startPoint1.y;
    float B1 = startPoint1.x - endPoint1.x;
    float C1 = A1 * startPoint1.x + B1 * startPoint1.y;

    // Get A,B,C of second line - points : startPoint2 to endPoint2
    float A2 = endPoint2.y - startPoint2.y;
    float B2 = startPoint2.x - endPoint2.x;
    float C2 = A2 * startPoint2.x + B2 * startPoint2.y;

    // Check if the lines are parallel
    float delta = A1 * B2 - A2 * B1;
    if (delta == 0)
        throw new System.Exception("Lines are parallel");

    // Return the intersection point
    return new Vector2(
        (B2 * C1 - B1 * C2) / delta,
        (A1 * C2 - A2 * C1) / delta
    );
}

Currently the method throws an exception for parallel lines but I don't like the idea to wrap every call of that function in a try/catch.

Is there a better solution for this? I can't return null because Vector2 is a struct.

Maybe somthing like the following?

public static bool LineIntersectionPoint(Vector2 startPoint1, Vector2 endPoint1, Vector2 startPoint2, Vector2 endPoint2, out Vector2 intersectionPoint)
\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

You can return a Nullable Vector2?

public static Vector2? LineIntersectionPoint(Vector2 startPoint1, Vector2 endPoint1, Vector2 startPoint2, Vector2 endPoint2)
{
    // Get A,B,C of first line - points : startPoint1 to endPoint1
    float A1 = endPoint1.y - startPoint1.y;
    float B1 = startPoint1.x - endPoint1.x;
    float C1 = A1 * startPoint1.x + B1 * startPoint1.y;

    // Get A,B,C of second line - points : startPoint2 to endPoint2
    float A2 = endPoint2.y - startPoint2.y;
    float B2 = startPoint2.x - endPoint2.x;
    float C2 = A2 * startPoint2.x + B2 * startPoint2.y;

    // Check if the lines are parallel
    float delta = A1 * B2 - A2 * B1;
    if (delta == 0)
        return null;

    // Return the intersection point
    return new Vector2(
        (B2 * C1 - B1 * C2) / delta,
        (A1 * C2 - A2 * C1) / delta
    );
}

It lets you use a simple if(intersectionPoint.HasValue) instead of a try-catch at the call site.

\$\endgroup\$
4
\$\begingroup\$

I suggest changing your API so that it tells you explicitly whether the lines intersect:

public static bool LineIntersectionPoint(Vector2 startPoint1, Vector2 endPoint1,
                                         Vector2 startPoint2, Vector2 endPoint2,
                                         out Vector2 intersectionPoint)
{
    // ...

    if (delta == 0)
    {
        intersectionPoint = Vector2.zero;
        return false;
    }

    // Return the intersection point
    intersectionPoint = new Vector2(
        (B2 * C1 - B1 * C2) / delta,
        (A1 * C2 - A2 * C1) / delta
    );
    return true;
}

You can then use it like this:

if (LineIntersectionPoint(...., out intersectionPoint))
{
     // do something with intersectionPoint
}
else
{
     // possible fallback code
}

Edit: assign point to zero in the no-intersection case.

\$\endgroup\$
3
  • \$\begingroup\$ I thought about using that (like Unity does with 3D raycasts) but I don't like having the assignment in an if-statement. \$\endgroup\$
    – Superwayne
    May 14, 2016 at 11:30
  • 1
    \$\begingroup\$ I added a zero assignation in the no-intersection case. Note that using bool/out to try something is a standard idiom in the .NET API, see Dictionary.TryGetValue or Int32.TryParse. \$\endgroup\$ May 14, 2016 at 13:09
  • \$\begingroup\$ Guess I will add both to my math utils: Vector2? LineIntersectionPoint(...) and bool TryLineIntersectionpoint(... out Vector2 intersectionPoint) \$\endgroup\$
    – Superwayne
    May 14, 2016 at 13:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .