using System; using System.Collections.Generic; using System.Linq; using System.Text; using Annulus.SweptCollisionDetection; using Azimuth; using Azimuth.RootFinding; namespace Annulus.UnitTests.SweptCollisionDetection { public class RotatingCornervsRotatingSegmentTests : UnitTestSharp.TestFixture { public class EdgeEdge : UnitTestSharp.TestFixture { public void LinearMotion_Velocity_CleanHit() { var corner = new RotatingCornervsRotatingSegment.Corner { prevVertex = new Vector(-1, 1), vertex = new Vector(1, 1), nextVertex = new Vector(1, -1), initialPosition = new Vector(2, 0), initialLinearVelocity = new Vector(0, -1), linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(-2, 0), vertex2 = new Vector(3, 0), initialPosition = new Vector(2, 10), initialLinearVelocity = new Vector(0, -10), linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 100), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.SUCCESS, success); CheckNotNull(output); if (output != null) { CheckEqual(CollisionType.EDGE_EDGE_PREV, output.collisionType); CheckEqual(new Interval(1.0 / 5, 3.0 / 5), output.segmentHitFraction); CheckEqual(1, output.TOI); } } public void LinearMotion_Velocity_SidewaysMiss() { var corner = new RotatingCornervsRotatingSegment.Corner { prevVertex = new Vector(-1, 1), vertex = new Vector(1, 1), nextVertex = new Vector(1, -1), initialPosition = new Vector(-4, 0), initialLinearVelocity = new Vector(0, -1), linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(-2, 0), vertex2 = new Vector(3, 0), initialPosition = new Vector(2, 10), initialLinearVelocity = new Vector(0, -10), linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 100), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.BOUNDS_EXCEEDED, success); CheckNull(output); } public void LinearMotion_Velocity_CleanMiss() { var corner = new RotatingCornervsRotatingSegment.Corner { prevVertex = new Vector(-1, 1), vertex = new Vector(1, 1), nextVertex = new Vector(1, -1), initialPosition = new Vector(2, 0), initialLinearVelocity = new Vector(0, -1), linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(-2, 0), vertex2 = new Vector(3, 0), initialPosition = new Vector(2, 10), initialLinearVelocity = new Vector(0, 10), linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 100), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.BOUNDS_EXCEEDED, success); CheckNull(output); } public void LinearMotion_Acceleration_CleanHit() { var corner = new RotatingCornervsRotatingSegment.Corner { prevVertex = new Vector(-1, 1), vertex = new Vector(1, 1), nextVertex = new Vector(1, -1), initialPosition = new Vector(2, 0), initialLinearVelocity = new Vector(0, 0), linearAcceleration = new Vector(0, -2), angularVelocity = 0, initialOrientation = 0, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(-2, 0), vertex2 = new Vector(3, 0), initialPosition = new Vector(2, 10), initialLinearVelocity = new Vector(0, 0), linearAcceleration = new Vector(0, -20), angularVelocity = 0, initialOrientation = 0, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 100), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.SUCCESS, success); CheckNotNull(output); if (output != null) { CheckEqual(CollisionType.EDGE_EDGE_PREV, output.collisionType); CheckEqual(new Interval(1.0 / 5, 3.0 / 5), output.segmentHitFraction); CheckEqual(1, output.TOI); } } public void LinearMotion_Acceleration_CleanMiss() { var corner = new RotatingCornervsRotatingSegment.Corner { prevVertex = new Vector(-1, 1), vertex = new Vector(1, 1), nextVertex = new Vector(1, -1), initialPosition = new Vector(2, 0), initialLinearVelocity = new Vector(0, 0), linearAcceleration = new Vector(0, -2), angularVelocity = 0, initialOrientation = 0, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(-2, 0), vertex2 = new Vector(3, 0), initialPosition = new Vector(2, 10), initialLinearVelocity = new Vector(0, 0), linearAcceleration = new Vector(0, 20), angularVelocity = 0, initialOrientation = 0, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 100), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.BOUNDS_EXCEEDED, success); CheckNull(output); } public void ImpactWindow_WouldHit() { var corner = new RotatingCornervsRotatingSegment.Corner { prevVertex = new Vector(-1, 1), vertex = new Vector(1, 1), nextVertex = new Vector(1, -1), initialPosition = new Vector(2, 0), initialLinearVelocity = new Vector(0, -1), linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(-2, 0), vertex2 = new Vector(3, 0), initialPosition = new Vector(2, 10), initialLinearVelocity = new Vector(0, -10), linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 1 - 10 * Scalar.FuzzyEqualityEpsilon), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.BOUNDS_EXCEEDED, success); CheckNull(output); } public void ImpactWindow_WouldMiss() { var corner = new RotatingCornervsRotatingSegment.Corner { prevVertex = new Vector(-1, 1), vertex = new Vector(1, 1), nextVertex = new Vector(1, -1), initialPosition = new Vector(2, 0), initialLinearVelocity = new Vector(0, -1), linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(-2, 0), vertex2 = new Vector(3, 0), initialPosition = new Vector(2, 10), initialLinearVelocity = new Vector(0, 10), linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 1 - 10 * Scalar.FuzzyEqualityEpsilon), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.BOUNDS_EXCEEDED, success); CheckNull(output); } public void IterationsExceeded() { var corner = new RotatingCornervsRotatingSegment.Corner { prevVertex = new Vector(-1, 1), vertex = new Vector(1, 1), nextVertex = new Vector(1, -1), initialPosition = new Vector(2, 0), initialLinearVelocity = new Vector(0, -1), linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(-2, 0), vertex2 = new Vector(3, 0), initialPosition = new Vector(2, 10), initialLinearVelocity = new Vector(0, -10), linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 100), maxIterations = 3, }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.MAX_ITERATIONS_EXCEEDED, success); CheckEqual(iterations, input.maxIterations); CheckNull(output); } public void AngularMotion_Corner_CleanHit() { var corner = new RotatingCornervsRotatingSegment.Corner { prevVertex = new Vector(-10, 10), vertex = new Vector(10, 10), nextVertex = new Vector(10, -10), initialPosition = new Vector(-10, -10), initialLinearVelocity = Vector.Zero, linearAcceleration = Vector.Zero, angularVelocity = -Math.PI/4, initialOrientation = Math.PI/4, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(1, 0), vertex2 = new Vector(-1, 0), initialPosition = new Vector(0, 0), initialLinearVelocity = Vector.Zero, linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 100), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.SUCCESS, success); CheckNotNull(output); if (output != null) { CheckEqual(CollisionType.EDGE_EDGE_PREV, output.collisionType); CheckEqual(new Interval(0.5, 1), output.segmentHitFraction); CheckEqual(1, output.TOI); } } public void AngularMotion_Corner_CleanMiss() { var corner = new RotatingCornervsRotatingSegment.Corner { prevVertex = new Vector(-10, 10), vertex = new Vector(10, 10), nextVertex = new Vector(10, -10), initialPosition = new Vector(22, -10), initialLinearVelocity = Vector.Zero, linearAcceleration = Vector.Zero, angularVelocity = -Math.PI / 4, initialOrientation = Math.PI / 4, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(1, 0), vertex2 = new Vector(-1, 0), initialPosition = new Vector(0, 0), initialLinearVelocity = Vector.Zero, linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 100), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.BOUNDS_EXCEEDED, success); CheckNull(output); } public void AngularMotion_Segment_CleanHit() { var corner = new RotatingCornervsRotatingSegment.Corner { prevVertex = new Vector(-10, 10), vertex = new Vector(10, 10), nextVertex = new Vector(10, -10), initialPosition = new Vector(-10, -10), initialLinearVelocity = Vector.Zero, linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(-3, 0), vertex2 = new Vector(3, 0), initialPosition = new Vector(1, 0), initialLinearVelocity = Vector.Zero, linearAcceleration = Vector.Zero, angularVelocity = -Math.PI/4, initialOrientation = Math.PI/4, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 100), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.SUCCESS, success); CheckNotNull(output); if (output != null) { CheckEqual(CollisionType.EDGE_EDGE_PREV, output.collisionType); CheckEqual(new Interval(0, 1.0/3), output.segmentHitFraction); CheckEqual(1, output.TOI); } } public void AngularMotion_Segment_CleanMiss() { var corner = new RotatingCornervsRotatingSegment.Corner { prevVertex = new Vector(-10, 10), vertex = new Vector(10, 10), nextVertex = new Vector(10, -10), initialPosition = new Vector(-10, -10), initialLinearVelocity = Vector.Zero, linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(-3, 0), vertex2 = new Vector(3, 0), initialPosition = new Vector(5, 0), initialLinearVelocity = Vector.Zero, linearAcceleration = Vector.Zero, angularVelocity = -Math.PI / 4, initialOrientation = Math.PI / 4, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 100), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.BOUNDS_EXCEEDED, success); CheckNull(output); } public void AngularMotion_VerticalSegment_CleanHit() { var corner = new RotatingCornervsRotatingSegment.Corner { prevVertex = new Vector(-10, 10), vertex = new Vector(10, 10), nextVertex = new Vector(10, -10), initialPosition = new Vector(-10, -10), initialLinearVelocity = Vector.Zero, linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(0, -3), vertex2 = new Vector(0, 3), initialPosition = new Vector(1, 0), initialLinearVelocity = Vector.Zero, linearAcceleration = Vector.Zero, angularVelocity = -Math.PI / 4, initialOrientation = Math.PI / 4 + Math.PI / 2, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 100), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.SUCCESS, success); CheckNotNull(output); if (output != null) { CheckEqual(CollisionType.EDGE_EDGE_PREV, output.collisionType); CheckEqual(new Interval(2.0/3.0, 1.0), output.segmentHitFraction); CheckEqual(1, output.TOI); } } public void AngularMotion_VerticalSegment_Reverse() { var corner = new RotatingCornervsRotatingSegment.Corner { prevVertex = new Vector(-10, 10), vertex = new Vector(10, 10), nextVertex = new Vector(10, -10), initialPosition = new Vector(-10, -10), initialLinearVelocity = Vector.Zero, linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(0, 3), vertex2 = new Vector(0, -3), initialPosition = new Vector(1, 0), initialLinearVelocity = Vector.Zero, linearAcceleration = Vector.Zero, angularVelocity = -Math.PI / 4, initialOrientation = Math.PI / 4 + Math.PI / 2, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 100), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.SUCCESS, success); CheckNotNull(output); if (output != null) { CheckEqual(CollisionType.EDGE_EDGE_PREV, output.collisionType); CheckEqual(new Interval(0, 1.0/3.0), output.segmentHitFraction); CheckEqual(1, output.TOI); } } public void DoubleRoot() { var corner = new RotatingCornervsRotatingSegment.Corner { prevVertex = new Vector(-10, 10), vertex = new Vector(10, 10), nextVertex = new Vector(10, 20), initialPosition = new Vector(0, -10), initialLinearVelocity = Vector.Zero, linearAcceleration = Vector.Zero, angularVelocity = -Math.PI / 8, initialOrientation = Math.PI / 4, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(0, -3), vertex2 = new Vector(0, 3), initialPosition = new Vector(10, -10), initialLinearVelocity = new Vector(0, 5), linearAcceleration = new Vector(0, 5), angularVelocity = Math.PI / 8, initialOrientation = -Math.PI / 4, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 10), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.SUCCESS, success); CheckNotNull(output); if (output != null) { CheckEqual(CollisionType.EDGE_EDGE_NEXT, output.collisionType); CheckEqual(new Interval(0, 0.5), output.segmentHitFraction); CheckEqual(2, output.TOI); } } public void DoubleRoot_Backward() { var corner = new RotatingCornervsRotatingSegment.Corner { prevVertex = new Vector(-10, 10), vertex = new Vector(10, 10), nextVertex = new Vector(10, 20), initialPosition = new Vector(0, -10), initialLinearVelocity = Vector.Zero, linearAcceleration = Vector.Zero, angularVelocity = -Math.PI / 8, initialOrientation = Math.PI / 4, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(0, 3), vertex2 = new Vector(0, -3), initialPosition = new Vector(10, -10), initialLinearVelocity = new Vector(0, 5), linearAcceleration = new Vector(0, 5), angularVelocity = Math.PI / 8, initialOrientation = -Math.PI / 4, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 10), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.SUCCESS, success); CheckNotNull(output); if (output != null) { CheckEqual(CollisionType.EDGE_EDGE_NEXT, output.collisionType); CheckEqual(new Interval(0.5, 1), output.segmentHitFraction); CheckEqual(2, output.TOI); } } public void CompositeMotion_CleanHit() { var corner = new RotatingCornervsRotatingSegment.Corner { prevVertex = new Vector(-10, 10), vertex = new Vector(10, 10), nextVertex = new Vector(10, 20), initialPosition = new Vector(10, 0), initialLinearVelocity = new Vector(-2.5, -2.5), linearAcceleration = new Vector(-2.5, -2.5), angularVelocity = -Math.PI / 8, initialOrientation = Math.PI / 4, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(0, -3), vertex2 = new Vector(0, 3), initialPosition = new Vector(10, -10), initialLinearVelocity = new Vector(-6, 2.5), linearAcceleration = new Vector(6, 2.5), angularVelocity = -Math.PI / 8, initialOrientation = -Math.PI / 4, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 10), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.SUCCESS, success); CheckNotNull(output); if (output != null) { CheckEqual(CollisionType.EDGE_EDGE_PREV, output.collisionType); CheckEqual(new Interval(0, 0.5), output.segmentHitFraction); CheckEqual(2, output.TOI); } } } public class VertexEdge : UnitTestSharp.TestFixture { public void LinearMotion_Velocity_CleanHit() { var corner = new RotatingCornervsRotatingSegment.Corner { vertex = new Vector(1, 1), initialPosition = new Vector(0, 0), initialLinearVelocity = new Vector(0, -1), linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(-2, 0), vertex2 = new Vector(3, 0), initialPosition = new Vector(0, 0), initialLinearVelocity = new Vector(0, 0), linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 100), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.SUCCESS, success); CheckNotNull(output); if (output != null) { CheckEqual(CollisionType.VERTEX_EDGE, output.collisionType); CheckEqual(new Interval(3.0/5.0), output.segmentHitFraction); CheckEqual(1, output.TOI); } } public void LinearMotion_Velocity_CleanMiss() { var corner = new RotatingCornervsRotatingSegment.Corner { vertex = new Vector(1, 1), initialPosition = new Vector(20, 0), initialLinearVelocity = new Vector(0, -1), linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(-2, 0), vertex2 = new Vector(3, 0), initialPosition = new Vector(0, 0), initialLinearVelocity = new Vector(0, 0), linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 100), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.BOUNDS_EXCEEDED, success); CheckNull(output); } public void LinearMotion_Acceleration_CleanHit() { var corner = new RotatingCornervsRotatingSegment.Corner { vertex = new Vector(1, 1), initialPosition = new Vector(0, 0), initialLinearVelocity = new Vector(0, 0), linearAcceleration = new Vector(0, -1), angularVelocity = 0, initialOrientation = 0, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(-2, 0), vertex2 = new Vector(3, 0), initialPosition = new Vector(0, 0), initialLinearVelocity = new Vector(0, 0), linearAcceleration = new Vector(0, 1), angularVelocity = 0, initialOrientation = 0, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 100), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.SUCCESS, success); CheckNotNull(output); if (output != null) { CheckEqual(CollisionType.VERTEX_EDGE, output.collisionType); CheckEqual(new Interval(3.0 / 5.0), output.segmentHitFraction); CheckEqual(1, output.TOI); } } public void LinearMotion_Acceleration_CleanMiss() { var corner = new RotatingCornervsRotatingSegment.Corner { vertex = new Vector(1, 1), initialPosition = new Vector(0, 0), initialLinearVelocity = new Vector(0, 0), linearAcceleration = new Vector(0, 1), angularVelocity = 0, initialOrientation = 0, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(-2, 0), vertex2 = new Vector(3, 0), initialPosition = new Vector(0, 0), initialLinearVelocity = new Vector(0, 0), linearAcceleration = new Vector(0, -1), angularVelocity = 0, initialOrientation = 0, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 100), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.BOUNDS_EXCEEDED, success); CheckNull(output); } public void LinearMotion_Aggregate_CleanHit() { var corner = new RotatingCornervsRotatingSegment.Corner { vertex = new Vector(1, 4), initialPosition = new Vector(0, 0), initialLinearVelocity = new Vector(-1, -1), linearAcceleration = new Vector(2, -2), angularVelocity = 0, initialOrientation = 0, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(-2, 0), vertex2 = new Vector(3, 0), initialPosition = new Vector(0, 0), initialLinearVelocity = new Vector(1, 1), linearAcceleration = new Vector(-2, 2), angularVelocity = 0, initialOrientation = 0, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 100), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.SUCCESS, success); CheckNotNull(output); if (output != null) { CheckEqual(CollisionType.VERTEX_EDGE, output.collisionType); CheckEqual(new Interval(3.0 / 5.0), output.segmentHitFraction); CheckEqual(1, output.TOI); } } public void LinearMotion_Aggregate_CleanMiss() { var corner = new RotatingCornervsRotatingSegment.Corner { vertex = new Vector(1, 4), initialPosition = new Vector(0, 0), initialLinearVelocity = new Vector(1, 1), linearAcceleration = new Vector(-2, 2), angularVelocity = 0, initialOrientation = 0, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(-2, 0), vertex2 = new Vector(3, 0), initialPosition = new Vector(0, 0), initialLinearVelocity = new Vector(-1, -1), linearAcceleration = new Vector(2, -2), angularVelocity = 0, initialOrientation = 0, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 100), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.BOUNDS_EXCEEDED, success); CheckNull(output); } public void MaxIterationsExceeded() { var corner = new RotatingCornervsRotatingSegment.Corner { vertex = new Vector(1, 4), initialPosition = new Vector(0, 0), initialLinearVelocity = new Vector(-1, -1), linearAcceleration = new Vector(2, -2), angularVelocity = 0, initialOrientation = 0, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(-2, 0), vertex2 = new Vector(3, 0), initialPosition = new Vector(0, 0), initialLinearVelocity = new Vector(1, 1), linearAcceleration = new Vector(-2, 2), angularVelocity = 0, initialOrientation = 0, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 100), maxIterations = 4, }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.MAX_ITERATIONS_EXCEEDED, success); CheckEqual(4, iterations); CheckNull(output); } public void BoundsExceeded_ButWouldHit() { var corner = new RotatingCornervsRotatingSegment.Corner { vertex = new Vector(1, 4), initialPosition = new Vector(0, 0), initialLinearVelocity = new Vector(-1, -1), linearAcceleration = new Vector(2, -2), angularVelocity = 0, initialOrientation = 0, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(-2, 0), vertex2 = new Vector(3, 0), initialPosition = new Vector(0, 0), initialLinearVelocity = new Vector(1, 1), linearAcceleration = new Vector(-2, 2), angularVelocity = 0, initialOrientation = 0, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 0.99), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.BOUNDS_EXCEEDED, success); CheckNull(output); } public void AngularMotion_Corner_CleanHit() { var corner = new RotatingCornervsRotatingSegment.Corner { prevVertex = new Vector(1, 0), vertex = new Vector(1, 0), nextVertex = new Vector(1, 0), initialPosition = Vector.Zero, initialLinearVelocity = Vector.Zero, linearAcceleration = Vector.Zero, angularVelocity = -1, initialOrientation = 1, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(-2, 0), vertex2 = new Vector(3, 0), initialPosition = Vector.Zero, initialLinearVelocity = Vector.Zero, linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 100), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.SUCCESS, success); CheckNotNull(output); if (output != null) { CheckEqual(CollisionType.VERTEX_EDGE, output.collisionType); CheckEqual(new Interval(3.0 / 5.0), output.segmentHitFraction); CheckEqual(1, output.TOI); } } public void AngularMotion_Corner_CleanMiss() { var corner = new RotatingCornervsRotatingSegment.Corner { prevVertex = new Vector(1, 0), vertex = new Vector(1, 0), nextVertex = new Vector(1, 0), initialPosition = Vector.Zero, initialLinearVelocity = Vector.Zero, linearAcceleration = Vector.Zero, angularVelocity = 1, initialOrientation = .1, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(-2, 0), vertex2 = new Vector(3, 0), initialPosition = Vector.Zero, initialLinearVelocity = Vector.Zero, linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 1), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.BOUNDS_EXCEEDED, success); CheckNull(output); } public void AngularMotion_Segment_CleanHit() { var corner = new RotatingCornervsRotatingSegment.Corner { prevVertex = new Vector(1, 0), vertex = new Vector(1, 0), nextVertex = new Vector(1, 0), initialPosition = Vector.Zero, initialLinearVelocity = Vector.Zero, linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(-2, 0), vertex2 = new Vector(3, 0), initialPosition = Vector.Zero, initialLinearVelocity = Vector.Zero, linearAcceleration = Vector.Zero, angularVelocity = -1, initialOrientation = 1, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 100), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.SUCCESS, success); CheckNotNull(output); if (output != null) { CheckEqual(CollisionType.VERTEX_EDGE, output.collisionType); CheckEqual(new Interval(3.0 / 5.0), output.segmentHitFraction); CheckEqual(1, output.TOI); } } public void AngularMotion_Segment_CleanMiss() { var corner = new RotatingCornervsRotatingSegment.Corner { prevVertex = new Vector(1, 0), vertex = new Vector(1, 0), nextVertex = new Vector(1, 0), initialPosition = Vector.Zero, initialLinearVelocity = Vector.Zero, linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(-2, 0), vertex2 = new Vector(3, 0), initialPosition = Vector.Zero, initialLinearVelocity = Vector.Zero, linearAcceleration = Vector.Zero, angularVelocity = 1, initialOrientation = .1, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 1.25), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.BOUNDS_EXCEEDED, success); CheckNull(output); } public void AngularMotion_Aggregate_CleanHit() { var corner = new RotatingCornervsRotatingSegment.Corner { prevVertex = new Vector(1, 0), vertex = new Vector(1, 0), nextVertex = new Vector(1, 0), initialPosition = Vector.Zero, initialLinearVelocity = Vector.Zero, linearAcceleration = Vector.Zero, angularVelocity = -0.5, initialOrientation = 0.5, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(-2, 0), vertex2 = new Vector(3, 0), initialPosition = Vector.Zero, initialLinearVelocity = Vector.Zero, linearAcceleration = Vector.Zero, angularVelocity = 0.5, initialOrientation = -0.5, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 1.25), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.SUCCESS, success); CheckNotNull(output); if (output != null) { CheckEqual(CollisionType.VERTEX_EDGE, output.collisionType); CheckEqual(new Interval(3.0 / 5.0), output.segmentHitFraction); CheckEqual(1, output.TOI); } } public void AngularMotion_Aggregate_CleanMiss() { var corner = new RotatingCornervsRotatingSegment.Corner { prevVertex = new Vector(1, 0), vertex = new Vector(1, 0), nextVertex = new Vector(1, 0), initialPosition = Vector.Zero, initialLinearVelocity = Vector.Zero, linearAcceleration = Vector.Zero, angularVelocity = 0.5, initialOrientation = 0.5, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(-2, 0), vertex2 = new Vector(3, 0), initialPosition = Vector.Zero, initialLinearVelocity = Vector.Zero, linearAcceleration = Vector.Zero, angularVelocity = -0.5, initialOrientation = -0.5, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 0.5), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.BOUNDS_EXCEEDED, success); CheckNull(output); } public void ComplicatedMotion_CleanHit() { var corner = new RotatingCornervsRotatingSegment.Corner { prevVertex = new Vector(1, 0), vertex = new Vector(1, 0), nextVertex = new Vector(1, 0), initialPosition = Vector.Zero, initialLinearVelocity = new Vector(-2, 1), linearAcceleration = new Vector(4, -2), angularVelocity = -0.5, initialOrientation = 0.5, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(-2, 0), vertex2 = new Vector(3, 0), initialPosition = Vector.Zero, initialLinearVelocity = new Vector(-2, 1), linearAcceleration = new Vector(4, -2), angularVelocity = 0.5, initialOrientation = -0.5, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 1.25), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.SUCCESS, success); CheckNotNull(output); if (output != null) { CheckEqual(CollisionType.VERTEX_EDGE, output.collisionType); CheckEqual(new Interval(3.0 / 5.0), output.segmentHitFraction); CheckEqual(1, output.TOI); } } public void ComplicatedMotion_CleanMiss() { var corner = new RotatingCornervsRotatingSegment.Corner { prevVertex = new Vector(1, 0), vertex = new Vector(1, 0), nextVertex = new Vector(1, 0), initialPosition = Vector.Zero, initialLinearVelocity = new Vector(-2, 1), linearAcceleration = new Vector(4, 2), angularVelocity = -0.5, initialOrientation = 0.5, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(-2, 0), vertex2 = new Vector(3, 0), initialPosition = Vector.Zero, initialLinearVelocity = new Vector(-2, 1), linearAcceleration = new Vector(4, -2), angularVelocity = 0.5, initialOrientation = -0.5, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 1.25), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.BOUNDS_EXCEEDED, success); CheckNull(output); } } public class VertexVertex : UnitTestSharp.TestFixture { public void LinearVelocity_Grinding_ScapingMiss() { var corner = new RotatingCornervsRotatingSegment.Corner { vertex = new Vector(1, 1), initialPosition = new Vector(0, 0), initialLinearVelocity = new Vector(0, -1), linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(1, 0), vertex2 = new Vector(1, -10), initialPosition = new Vector(0, 0), initialLinearVelocity = new Vector(0, 0), linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 100), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.BOUNDS_EXCEEDED, success); CheckNull(output); } public void LinearVelocity_Grinding_SolidHit() { var corner = new RotatingCornervsRotatingSegment.Corner { prevVertex = new Vector(0, 2), vertex = new Vector(1, 1), nextVertex = new Vector(2, 2), initialPosition = new Vector(0, 0), initialLinearVelocity = new Vector(0, -1), linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var segment = new RotatingCornervsRotatingSegment.Segment { vertex1 = new Vector(1, 0), vertex2 = new Vector(1, -10), initialPosition = new Vector(0, 0), initialLinearVelocity = new Vector(0, 0), linearAcceleration = Vector.Zero, angularVelocity = 0, initialOrientation = 0, }; var input = new RotatingCornervsRotatingSegment.Input { corner = corner, segment = segment, windowOfInterest = new Interval(0, 100), }; int iterations = 0; RotatingCornervsRotatingSegment.Output output; var success = RotatingCornervsRotatingSegment.FindNextIntersection(input, out output, ref iterations); CheckEqual(EndingState.SUCCESS, success); CheckNotNull(output); if (output != null) { CheckEqual(CollisionType.VERTEX_EDGE, output.collisionType); CheckEqual(new Interval(3.0 / 5.0), output.segmentHitFraction); CheckEqual(1, output.TOI); } } } } }