Beispiel #1
0
 public void TestVerticalParallelLines()
 {
     Assert.IsFalse(
         Line2Line2Collider.FindContacts(
             Vector2.Zero, Vector2.UnitY,
             Vector2.Zero, Vector2.UnitY
             ).HasContact
         );
 }
Beispiel #2
0
 public void TestHorizontalParallelLines()
 {
     Assert.IsFalse(
         Line2Line2Collider.FindContacts(
             Vector2.Zero, Vector2.UnitX,
             Vector2.Zero, Vector2.UnitX
             ).HasContact
         );
 }
Beispiel #3
0
        public void TestDiagonallyCrossingLines()
        {
            LineContacts contacts = Line2Line2Collider.FindContacts(
                new Vector2(1.0f, 0.0f), Vector2.Normalize(Vector2.One),
                Vector2.Zero, Vector2.UnitY
                );
            float touchTime = -1.4142135623730950488016887242097f;

            Assert.That(
                contacts.EntryTime,
                Is.EqualTo(touchTime).Within(Specifications.MaximumDeviation).Ulps
                );
            Assert.That(
                contacts.ExitTime,
                Is.EqualTo(touchTime).Within(Specifications.MaximumDeviation).Ulps
                );
        }
Beispiel #4
0
        public void TestOrthogonallyCrossingLines()
        {
            LineContacts contacts = Line2Line2Collider.FindContacts(
                new Vector2(-1.0f, 0.0f), Vector2.UnitX,
                Vector2.Zero, Vector2.UnitY
                );
            float touchTime = 1.0f;

            Assert.That(
                contacts.EntryTime,
                Is.EqualTo(touchTime).Within(Specifications.MaximumDeviation).Ulps
                );
            Assert.That(
                contacts.ExitTime,
                Is.EqualTo(touchTime).Within(Specifications.MaximumDeviation).Ulps
                );
        }
        /// <summary>Determines where a ray will hit a line, if at all</summary>
        /// <param name="rayStart">Starting point of the ray</param>
        /// <param name="rayDirection">Direction into which the ray extends</param>
        /// <param name="lineOffset">Offset of the line</param>
        /// <param name="lineDirection">Direction along which the line extends</param>
        /// <returns>The intersection points between the ray and the line, if any</returns>
        public static LineContacts FindContacts(
            Vector2 rayStart, Vector2 rayDirection,
            Vector2 lineOffset, Vector2 lineDirection
            )
        {
            LineContacts contacts = Line2Line2Collider.FindContacts(
                rayStart, rayDirection, lineOffset, lineDirection
                );

            // If the contact occured before the starting offset of the ray,
            // no collision took place since we're a ray
            if (!float.IsNaN(contacts.EntryTime))
            {
                if (contacts.EntryTime < 0.0f)
                {
                    return(LineContacts.None);
                }
            }

            return(contacts);
        }
        /// <summary>Determines the contact location between a line and a triangle</summary>
        /// <param name="lineOffset">
        ///   Offset of the line from the coordinate system's center
        /// </param>
        /// <param name="lineDirection">Direction and length of the line</param>
        /// <param name="triangleA">
        ///   First corner point of triangle in counter-clockwise order
        /// </param>
        /// <param name="triangleB">
        ///   Second corner point of triangle in counter-clockwise order
        /// </param>
        /// <param name="triangleC">
        ///   Third corner point of triangle in counter-clockwise order
        /// </param>
        /// <returns>The point of intersection of the line with the triangle, if any</returns>
        /// <remarks>
        ///   Everyone seems to know how to do 3D line / triangle intersections, but there
        ///   are no resources whatsoever on 2D line / triangle intersections. The code in here
        ///   is hand-written by myself. Instead of fancy math tricks, it simply tries to be
        ///   efficient using the existing code. It requires 4 line checks to find the accurate
        ///   intersection point with the triangle.
        /// </remarks>
        internal static LineContacts FindContacts(
            Vector2 lineOffset, Vector2 lineDirection,
            Vector2 triangleA, Vector2 triangleB, Vector2 triangleC
            )
        {
            Vector2 ab = triangleB - triangleA;
            Vector2 bc = triangleC - triangleB;
            Vector2 ca = triangleA - triangleC;

            float abLength = ab.Length();
            float bcLength = bc.Length();
            float caLength = ca.Length();

            Vector2 abNormalized = ab / abLength;
            Vector2 bcNormalized = bc / bcLength;
            Vector2 caNormalized = ca / caLength;

            LineContacts abContacts = Line2Line2Collider.FindContacts(
                triangleA, abNormalized, lineOffset, lineDirection
                );
            LineContacts bcContacts = Line2Line2Collider.FindContacts(
                triangleB, bcNormalized, lineOffset, lineDirection
                );

            // Does the line cross the A-B line of the triangle?
            if (isWithin(abContacts, abLength))
            {
                abContacts = Line2Line2Collider.FindContacts(
                    lineOffset, lineDirection, triangleA, ab / abLength
                    );

                // Find out which other line it crosses: B-C or C-A?
                if (isWithin(bcContacts, bcLength))
                {
                    bcContacts = Line2Line2Collider.FindContacts(
                        lineOffset, lineDirection, triangleB, bc / bcLength
                        );
                }
                else
                {
                    bcContacts = Line2Line2Collider.FindContacts(
                        lineOffset, lineDirection, triangleC, ca / caLength
                        );
                }

                // Report the contacts in the right order
                if (abContacts.EntryTime < bcContacts.EntryTime)
                {
                    return(new LineContacts(abContacts.EntryTime, bcContacts.EntryTime));
                }
                else
                {
                    return(new LineContacts(bcContacts.EntryTime, abContacts.EntryTime));
                }
            }
            else if (isWithin(bcContacts, bcLength)) // Does is cross the B-C line?

            {
                bcContacts = Line2Line2Collider.FindContacts(
                    lineOffset, lineDirection, triangleB, bc / abLength
                    );

                // We already checked A-B, so the other line it crosses must be C-A!
                abContacts = Line2Line2Collider.FindContacts(
                    lineOffset, lineDirection, triangleC, ca / caLength
                    );

                // Report the contacts in the right order
                if (bcContacts.EntryTime < abContacts.EntryTime)
                {
                    return(new LineContacts(bcContacts.EntryTime, abContacts.EntryTime));
                }
                else
                {
                    return(new LineContacts(abContacts.EntryTime, bcContacts.EntryTime));
                }
            }
            else // No contact on A-B or B-C, contact is impossible
            {
                return(LineContacts.None);
            }
        }