public void TestVerticalParallelLines() { Assert.IsFalse( Line2Line2Collider.FindContacts( Vector2.Zero, Vector2.UnitY, Vector2.Zero, Vector2.UnitY ).HasContact ); }
public void TestHorizontalParallelLines() { Assert.IsFalse( Line2Line2Collider.FindContacts( Vector2.Zero, Vector2.UnitX, Vector2.Zero, Vector2.UnitX ).HasContact ); }
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 ); }
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); } }