Ejemplo n.º 1
0
    // this is the general case. Really really general
    public static Vector2[] GetLineSegLineSegIntersectionInterval(Vector2 a1, Vector2 a2, Vector2 b1, Vector2 b2)
    {
        // PointEqualsEpsilon is needed, or this for example falsely returns true:
        // MathUtil.CheckLineSegLineSegIntersection(new Vector2(-7.642176f, -3.406708f), new Vector2(-7.642176f, -3.406707f), new Vector2(0f, -3f), new Vector2(1f, -4f)));

        if (a1.PointEqualEpsilon(a2) && b1.PointEqualEpsilon(b2))
        {
            // both "segments" are points, return either point
            if (a1.PointEqualEpsilon(b1))
                return new Vector2[] { a1 };
            else // both "segments" are different points, return empty set
                return new Vector2[] { };
        }
        else if (b1.PointEqualEpsilon(b2)) // b is a point, a is a segment
        {
            if (PointOnLine(b1, a1, a2))
                return new Vector2[] { b1 };
            else
                return new Vector2[] { };
        }
        else if (a1.PointEqualEpsilon(a2)) // a is a point, b is a segment
        {
            if (PointOnLine(a1, b1, b2))
                return new Vector2[] { a1 };
            else
                return new Vector2[] { };
        }

        // at this point we know both a and b are actual segments

        float ua_t = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x);
        float ub_t = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x);
        float u_b = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y);

        // Infinite lines intersect somewhere
        if (!(-MyEpsilon < u_b && u_b < MyEpsilon))   // e.g. u_b != 0.0
        {
            float ua = ua_t / u_b;
            float ub = ub_t / u_b;
            if (0.0f <= ua && ua <= 1.0f && 0.0f <= ub && ub <= 1.0f)
            {
                // Intersection
                return new Vector2[] {
                    new Vector2(a1.x + ua * (a2.x - a1.x),
                        a1.y + ua * (a2.y - a1.y)) };
            }
            else
            {
                // No Intersection
                return new Vector2[] { };
            }
        }
        else // lines (not just segments) are parallel or the same line
        {
            // Coincident
            // find the common overlapping section of the lines
            // first find the distance (squared) from one point (a1) to each point
            if ((-MyEpsilon < ua_t && ua_t < MyEpsilon)
               || (-MyEpsilon < ub_t && ub_t < MyEpsilon))
            {
                if (a1.Equals(a2)) // danger!
                    return OneDIntersection(b1, b2, a1, a2);
                else // safe
                    return OneDIntersection(a1, a2, b1, b2);
            }
            else
            {
                // Parallel
                return new Vector2[] { };
            }
        }
    }