public void TestExcuteParticleCollisionDetector() { var pA = new Particle { Mass = 1, Position = new Vector2D(0, 0) }; var pB = new Particle { Mass = 1, Position = new Vector2D(2, 0) }; pA.BindShape(new Circle(5)); pB.BindShape(new Circle(5)); var objects = new HashSet <PhysicsObject> { pA, pB }; var edge = new Edge(0, 4, 4, 4); var edges = new HashSet <Edge> { edge }; var shapes = ContactRegistry.CollectAllShapes(objects, edges); var contacts = ContactRegistry.ExcuteParticleCollisionDetector(shapes); var count = 0; foreach (var contact in contacts) { count++; } Assert.AreEqual(3, count, "应当产生三个碰撞"); shapes = new List <Shape> { edge, pA.Shape, pB.Shape }; contacts = ContactRegistry.ExcuteParticleCollisionDetector(shapes); count = 0; foreach (var contact in contacts) { count++; } Assert.AreEqual(3, count, "形状列表的次序不影响结果"); pA.BindShape(new Circle(5, 1)); pB.BindShape(new Circle(5, 1)); shapes = new List <Shape> { pA.Shape, edge, pB.Shape }; contacts = ContactRegistry.ExcuteParticleCollisionDetector(shapes); count = 0; foreach (var contact in contacts) { count++; } Assert.AreEqual(2, count, "形状标识符一致的物体不执行碰撞检测"); }
public void TestCircleAndEdgeCollided() { Particle pA = new Particle { Position = new Vector2D(0, 2), Restitution = 1 }; Edge edge = new Edge(0, 0, 5, 0); pA.BindShape(new Circle(5)); TestDetectorsResult( new ParticleContact(pA, null, 1, 3, new Vector2D(0, 1)), ParticleCollisionDetector.CircleAndEdge(pA.Shape as Circle, edge), "圆心投影在边沿上"); pA.Position = new Vector2D(-1, 2); TestDetectorsResult( new ParticleContact(pA, null, 1, 5 - Math.Sqrt(5), (new Vector2D(-1, 2)).Normalize()), ParticleCollisionDetector.CircleAndEdge(pA.Shape as Circle, edge), "圆心投影在边沿左延长线上"); pA.Position = new Vector2D(6, 2); TestDetectorsResult( new ParticleContact(pA, null, 1, 5 - Math.Sqrt(5), (new Vector2D(1, 2)).Normalize()), ParticleCollisionDetector.CircleAndEdge(pA.Shape as Circle, edge), "圆心投影在边沿右延长线上"); pA.Position = new Vector2D(-1, 0); TestDetectorsResult( new ParticleContact(pA, null, 1, 4, new Vector2D(-1, 0)), ParticleCollisionDetector.CircleAndEdge(pA.Shape as Circle, edge), "圆心在边沿的延长线上"); pA.PrePosition = new Vector2D(2.5, 10); pA.Position = new Vector2D(2.5, -10); TestDetectorsResult( new ParticleContact(pA, null, 1, 5, new Vector2D(0, 1)), ParticleCollisionDetector.CircleAndEdge(pA.Shape as Circle, edge), "发生了穿越"); }
public void TestAddAndRemoveEdge() { var world = new World(); var obj = new Particle { Mass = 1, Position = new Vector2D(0, 5), Velocity = new Vector2D(0, 5) }; obj.BindShape(new Circle(2)); var edgeA = new Edge(-5, 0, 5, 0); var edgeB = new Edge(-5, 10, 5, 10); world.AddObject(obj); world.AddEdge(edgeA); world.AddEdge(edgeB); world.Update(1); Assert.AreEqual(new Vector2D(0, -5), obj.Velocity, "质体会被反弹"); world.Update(1); world.Update(1); Assert.AreEqual(new Vector2D(0, 5), obj.Velocity, "质体会被再次反弹"); world.RemoveEdge(edgeB); world.Update(1); world.Update(1); Assert.AreEqual(new Vector2D(0, 5), obj.Velocity, "移除边缘后质体不会被反弹"); }
public void TestDispatchToDetector() { var pA = new Particle { Mass = 1, Position = new Vector2D(0, 0) }; var pB = new Particle { Mass = 1, Position = new Vector2D(2, 0) }; pA.BindShape(new Circle(5)); pB.BindShape(new Circle(5)); var contact = ContactRegistry.DispatchToDetector( ContactRegistry.ContactTypeMap[(int)pA.Shape.Type, (int)pB.Shape.Type], pA.Shape, pB.Shape); Assert.IsNotNull(contact, "发生圆圆碰撞"); var edge = new Edge(0, 4, 4, 4); contact = ContactRegistry.DispatchToDetector( ContactRegistry.ContactTypeMap[(int)pA.Shape.Type, (int)edge.Type], pA.Shape, edge); Assert.IsNotNull(contact, "发生圆边碰撞"); }
public void TestResolveContactsStopIteration() { Settings.ContactIteration = 2; var pA = new Particle { Mass = 1, Position = new Vector2D(0, 0) }; var pB = new Particle { Mass = 1, Position = new Vector2D(2, 0) }; pA.BindShape(new Circle(5)); pB.BindShape(new Circle(5)); var objects = new HashSet <PhysicsObject> { pA, pB }; var contactRegistry = new ContactRegistry(objects, new HashSet <Edge>()); contactRegistry.OnContactEvent += (s, a) => { _isRan = true; Assert.AreEqual(contactRegistry, s); Assert.AreEqual(1, a.ContactList.Count); }; contactRegistry.ResolveContacts(1 / 60.0); Assert.IsTrue(_isRan); }
public void TestResolveContactsNotAddMoreContact() { Settings.ContactIteration = 1; Settings.MaxContacts = 0; var pA = new Particle { Mass = 1, Position = new Vector2D(0, 0) }; var pB = new Particle { Mass = 1, Position = new Vector2D(2, 0) }; pA.BindShape(new Circle(5)); pB.BindShape(new Circle(5)); var contactRegistry = new ContactRegistry(new HashSet <PhysicsObject>(), new HashSet <Edge>()); contactRegistry.Add(new ParticleRope(2, 0, pA, pB)); contactRegistry.OnContactEvent += (s, a) => { Assert.AreEqual(contactRegistry, s); Assert.AreEqual(0, a.ContactList.Count); }; contactRegistry.ResolveContacts(1 / 60.0); Settings.MaxContacts = 500; }
public void TestResolveContacts() { Settings.ContactIteration = 1; var pA = new Particle { Mass = 1, Position = new Vector2D(0, 0) }; var pB = new Particle { Mass = 1, Position = new Vector2D(2, 0) }; pA.BindShape(new Circle(5)); pB.BindShape(new Circle(5)); var objects = new HashSet <PhysicsObject> { pA, pB }; var edge = new Edge(0, 4, 4, 4); var edges = new HashSet <Edge> { edge }; var contactRegistry = new ContactRegistry(objects, edges); contactRegistry.OnContactEvent += (s, a) => { Assert.AreEqual(contactRegistry, s); Assert.AreEqual(3, a.ContactList.Count); }; contactRegistry.ResolveContacts(1 / 60.0); }
public void TestBindShape() { Particle obj = new Particle { Position = new Vector2D(0, 50) }; obj.BindShape(new Circle(10)); Assert.IsNotNull(obj.Shape as Circle); Assert.IsTrue(obj.Shape.Body == obj); }
public void TestCircleAndCircleNotCollided() { Particle pA = new Particle { Position = new Vector2D(0, 0) }; Particle pB = new Particle { Position = new Vector2D(0, 3) }; pA.BindShape(new Circle(1)); pB.BindShape(new Circle(1)); Assert.IsNull(ParticleCollisionDetector.CircleAndCircle(pA.Shape as Circle, pB.Shape as Circle)); }
public void TestCircleAndCircleCollided() { Particle pA = new Particle { Position = new Vector2D(0, 0), Restitution = 1 }; Particle pB = new Particle { Position = new Vector2D(0, 3), Restitution = 0.5 }; pA.BindShape(new Circle(2)); pB.BindShape(new Circle(2)); TestDetectorsResult( new ParticleContact(pA, pB, 0.75, 1, new Vector2D(0, -1)), ParticleCollisionDetector.CircleAndCircle(pA.Shape as Circle, pB.Shape as Circle)); }
public void TestCircleAndEdgeNotCollided() { Particle pA = new Particle { Position = new Vector2D(-1, 6), Restitution = 1 }; Edge edge = new Edge(0, 0, 5, 0); pA.BindShape(new Circle(5)); Assert.IsNull(ParticleCollisionDetector.CircleAndEdge(pA.Shape as Circle, edge), "圆心投影在边沿左延长线上"); pA.Position = new Vector2D(6, 6); Assert.IsNull(ParticleCollisionDetector.CircleAndEdge(pA.Shape as Circle, edge), "圆心投影在边沿右延长线上"); pA.Position = new Vector2D(2.5, 6); Assert.IsNull(ParticleCollisionDetector.CircleAndEdge(pA.Shape as Circle, edge), "圆心投影在边沿上"); pA.Position = new Vector2D(-6, 0); Assert.IsNull(ParticleCollisionDetector.CircleAndEdge(pA.Shape as Circle, edge), "圆心在边沿的延长线上"); }
public void TestCollectAllShapes() { var pA = new Particle { Mass = 1, Position = new Vector2D(0, 0) }; var pB = new Particle { Mass = 1, Position = new Vector2D(2, 0) }; pA.BindShape(new Circle(5)); pB.BindShape(new Point()); var objects = new HashSet <PhysicsObject> { pA, pB }; var edges = new HashSet <Edge> { new Edge(0, 4, 4, 4) }; var shapes = ContactRegistry.CollectAllShapes(objects, edges); Assert.AreEqual(2, shapes.Count); }