Index: Trunk/Modules/Annulus/Annulus.UnitTests/SweptCollisionDetection/PolygonvsPolygonTests.cs =================================================================== --- Trunk/Modules/Annulus/Annulus.UnitTests/SweptCollisionDetection/PolygonvsPolygonTests.cs (revision 993) +++ Trunk/Modules/Annulus/Annulus.UnitTests/SweptCollisionDetection/PolygonvsPolygonTests.cs (working copy) @@ -4350,7 +4350,286 @@ } } - // Sliding + public class GlancingHits : UnitTestSharp.TestFixture + { + public void SquareSpinning() + { + var hSqrt2 = Math.Sqrt(2); + var polygonDiamont = new SimplePolygon(new Vector[] + { + new Vector(0, 1), + new Vector(1, 0), + new Vector(0,-1), + new Vector(-1,0), + }); + var polygonSquare = new SimplePolygon(new Vector[] + { + new Vector(-1, 1), + new Vector( 1, 1), + new Vector( 1,-1), + new Vector(-1,-1), + }); + + var input = new PolygonvsPolygon.Input + { + polygon_A = new PolygonvsPolygon.SimplePolygonInMotion + { + polygon = polygonSquare, + motion = new Motion + { + AngularVelocity = Math.PI / 4, + InitialPosition = new Vector(0, 1 + hSqrt2), + LinearVelocity = new Vector(0, 0), + }, + payload = 7, + }, + + polygon_B = new PolygonvsPolygon.SimplePolygonInMotion + { + polygon = polygonDiamont, + motion = new Motion + { + + }, + + payload = 25, + }, + + impactWindow = new Interval(0, 8), + }; + + int iterations = 0; + var output = PolygonvsPolygon.FindIntersectionsInWindow(input, ref iterations); + + var expected = new PolygonvsPolygon.Hit[] + { + new PolygonvsPolygon.VertexVertexCollision + { + VertexA = polygonSquare.GetVertex(3), + VertexB = polygonDiamont.GetVertex(0), + TOI = 1, + Transition = PolygonvsPolygon.TransitionState.GlancingParallel, + PayloadA = input.polygon_A.payload, + PayloadB = input.polygon_B.payload, + }, + new PolygonvsPolygon.VertexVertexCollision + { + VertexA = polygonSquare.GetVertex(0), + VertexB = polygonDiamont.GetVertex(0), + TOI = 3, + Transition = PolygonvsPolygon.TransitionState.GlancingParallel, + PayloadA = input.polygon_A.payload, + PayloadB = input.polygon_B.payload, + }, + new PolygonvsPolygon.VertexVertexCollision + { + VertexA = polygonSquare.GetVertex(1), + VertexB = polygonDiamont.GetVertex(0), + TOI = 5, + Transition = PolygonvsPolygon.TransitionState.GlancingParallel, + PayloadA = input.polygon_A.payload, + PayloadB = input.polygon_B.payload, + }, + new PolygonvsPolygon.VertexVertexCollision + { + VertexA = polygonSquare.GetVertex(2), + VertexB = polygonDiamont.GetVertex(0), + TOI = 7, + Transition = PolygonvsPolygon.TransitionState.GlancingParallel, + PayloadA = input.polygon_A.payload, + PayloadB = input.polygon_B.payload, + }, + }; + + CheckEqual(expected, output); + } + + public void SquaresSliding() + { + var polygonSquare = new SimplePolygon(new Vector[] + { + new Vector(-1, 1), + new Vector( 1, 1), + new Vector( 1,-1), + new Vector(-1,-1), + }); + + var input = new PolygonvsPolygon.Input + { + polygon_A = new PolygonvsPolygon.SimplePolygonInMotion + { + polygon = polygonSquare, + motion = new Motion + { + InitialPosition = new Vector(3, 2), + LinearVelocity = new Vector(-1, 0), + }, + payload = 7, + }, + + polygon_B = new PolygonvsPolygon.SimplePolygonInMotion + { + polygon = polygonSquare, + motion = new Motion + { + + }, + + payload = 25, + }, + + impactWindow = new Interval(0, 8), + }; + + int iterations = 0; + var output = PolygonvsPolygon.FindIntersectionsInWindow(input, ref iterations); + + var expected = new PolygonvsPolygon.Hit[] + { + new PolygonvsPolygon.VertexVertexCollision + { + VertexA = polygonSquare.GetVertex(3), + VertexB = polygonSquare.GetVertex(1), + TOI = 1, + Transition = PolygonvsPolygon.TransitionState.GlancingParallelEntering, + PayloadA = input.polygon_A.payload, + PayloadB = input.polygon_B.payload, + }, + new PolygonvsPolygon.EdgeEdgeCollision + { + EdgeA = polygonSquare.GetEdge(2), + EdgeB = polygonSquare.GetEdge(0), + TrailingHitFraction = new Tuple(0, 1), + LeadingHitFraction = new Tuple(1, 0), + TOI = 3, + Transition = PolygonvsPolygon.TransitionState.GlancingParallel, + PayloadA = input.polygon_A.payload, + PayloadB = input.polygon_B.payload, + }, + new PolygonvsPolygon.VertexVertexCollision + { + VertexA = polygonSquare.GetVertex(2), + VertexB = polygonSquare.GetVertex(0), + TOI = 5, + Transition = PolygonvsPolygon.TransitionState.GlancingParallelExiting, + PayloadA = input.polygon_A.payload, + PayloadB = input.polygon_B.payload, + }, + }; + + + CheckEqual(expected, output); + + } + + public void SquaresSlideBack() + { + var polygonSquare = new SimplePolygon(new Vector[] + { + new Vector(-1, 1), + new Vector( 1, 1), + new Vector( 1,-1), + new Vector(-1,-1), + }); + + var input = new PolygonvsPolygon.Input + { + polygon_A = new PolygonvsPolygon.SimplePolygonInMotion + { + polygon = polygonSquare, + motion = new Motion + { + InitialPosition = new Vector(12, 2), + LinearVelocity = new Vector(-3.5, 0), + LinearAcceleration = new Vector(0.5, 0), + }, + payload = 7, + }, + + polygon_B = new PolygonvsPolygon.SimplePolygonInMotion + { + polygon = polygonSquare, + motion = new Motion + { + InitialPosition = new Vector(0, 0), + }, + + payload = 25, + }, + + impactWindow = new Interval(0, 20), + }; + + int iterations = 0; + var output = PolygonvsPolygon.FindIntersectionsInWindow(input, ref iterations); + var expected = new PolygonvsPolygon.Hit[] + { + + new PolygonvsPolygon.VertexVertexCollision + { + VertexA = polygonSquare.GetVertex(3), + VertexB = polygonSquare.GetVertex(1), + TOI = 4, + Transition = PolygonvsPolygon.TransitionState.GlancingParallelEntering, + PayloadA = input.polygon_A.payload, + PayloadB = input.polygon_B.payload, + }, + new PolygonvsPolygon.EdgeEdgeCollision + { + EdgeA = polygonSquare.GetEdge(2), + EdgeB = polygonSquare.GetEdge(0), + TOI = 4.8, + TrailingHitFraction = new Tuple(0, 1), + LeadingHitFraction = new Tuple(1, 0), + Transition = PolygonvsPolygon.TransitionState.GlancingParallel, + PayloadA = input.polygon_A.payload, + PayloadB = input.polygon_B.payload, + }, + new PolygonvsPolygon.EdgeEdgeCollision + { + EdgeA = polygonSquare.GetEdge(2), + EdgeB = polygonSquare.GetEdge(0), + TOI = 6, + Transition = PolygonvsPolygon.TransitionState.GlancingParallelExiting, + PayloadA = input.polygon_A.payload, + PayloadB = input.polygon_B.payload, + }, + new PolygonvsPolygon.VertexVertexCollision + { + VertexA = polygonSquare.GetVertex(2), + VertexB = polygonSquare.GetVertex(0), + TOI = 8, + Transition = PolygonvsPolygon.TransitionState.GlancingParallelEntering, + PayloadA = input.polygon_A.payload, + PayloadB = input.polygon_B.payload, + }, + new PolygonvsPolygon.EdgeEdgeCollision + { + EdgeA = polygonSquare.GetEdge(2), + EdgeB = polygonSquare.GetEdge(0), + TOI = 9.2, + TrailingHitFraction = new Tuple(1, 0), + LeadingHitFraction = new Tuple(0, 1), + Transition = PolygonvsPolygon.TransitionState.GlancingParallel, + PayloadA = input.polygon_A.payload, + PayloadB = input.polygon_B.payload, + }, + new PolygonvsPolygon.VertexVertexCollision + { + VertexA = polygonSquare.GetVertex(3), + VertexB = polygonSquare.GetVertex(1), + TOI = 10, + Transition = PolygonvsPolygon.TransitionState.GlancingParallelExiting, + PayloadA = input.polygon_A.payload, + PayloadB = input.polygon_B.payload, + }, + }; + CheckEqual(expected, output); + + } + + } + // edge edge // edge vertex // vertex vertex