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\$
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\$
  • \$\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 '16 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\$ – sam hocevar May 14 '16 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 '16 at 13:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.