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), "发生了穿越");
        }
Exemple #3
0
        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);
        }