Exemple #1
0
        public static bool Collide(out ContactManifold manifold,
                                   CircleShape circle1, Transform2D transform1,
                                   CircleShape circle2, Transform2D transform2)
        {
            var center1 = transform1.Transform(circle1.Center);
            var center2 = transform2.Transform(circle2.Center);

            // 两个圆是否碰撞,计算两个圆心的距离,是否比两者的半径之和小
            var totalRadius = circle1.Radius + circle2.Radius;

            if ((center1 - center2).LengthSquared() > totalRadius * totalRadius)
            {
                manifold = null;
                return(false);
            }

            manifold = new ContactManifold()
            {
                LocalPoint  = circle1.Center,
                LocalNormal = Vector2D.Zero,        // 为什么圆和圆的法线为 0 向量?
                Points      = new[] { new ContactPoint()
                                      {
                                          LocalPoint = circle2.Center
                                      } },
            };
            return(true);
        }
Exemple #2
0
        public static bool Collide(out ContactManifold manifold,
                                   PolygonShape polygon1, Transform2D transform1,
                                   PolygonShape polygon2, Transform2D transform2)
        {
            var radius = Configuration.PolygonRadius * 2;

            var seperation1 = FindMaxSeperation(out int edge1, polygon1, transform1, polygon2, transform2);

            if (seperation1 > radius)
            {
                manifold = null;
                return(false);
            }

            var seperation2 = FindMaxSeperation(out int edge2, polygon2, transform2, polygon1, transform1);

            if (seperation2 > radius)
            {
                manifold = null;
                return(false);
            }

            var flip = 0;
            var tol  = 0.1f * Configuration.LinearSlop;

            if (seperation2 > seperation1 + tol)
            {
                MathT.Swap(ref polygon1, ref polygon2);
                MathT.Swap(ref transform1, ref transform2);
                MathT.Swap(ref edge1, ref edge2);
                flip = 1;
            }

            var incidentEdge = FindIncidentEdge(polygon1, transform1, edge1, polygon2, transform2);

            throw new NotImplementedException();
        }
Exemple #3
0
        public static bool Collide(out ContactManifold manifold,
                                   PolygonShape polygon1, Transform2D transform1,
                                   CircleShape circle2, Transform2D transform2)
        {
            // 将圆心坐标转换到多边形的本地坐标系中
            var c = transform2.InverseTransform(transform1.Transform(circle2.Center));

            var radius      = Configuration.PolygonRadius + circle2.Radius;
            var normalIndex = 0;
            var seperation  = float.MinValue;

            for (int i = 0; i < polygon1.Verticles.Length; ++i)
            {
                // 将圆心到顶点的向量,投影到顶点所在边的法线上
                var s = Vector2D.Dot(polygon1.Normals[i], c - polygon1.Verticles[i]);
                // 如果投影长度大于圆的半径,即不存在相交
                if (s > radius)
                {
                    manifold = null;
                    return(false);
                }

                // 找到相交最浅的顶点
                if (s > seperation)
                {
                    normalIndex = i;
                    seperation  = s;
                }
            }

            // 得到最浅相交的接触边的两个顶点
            var v1 = polygon1.Verticles[normalIndex];
            var v2 = polygon1.Verticles[normalIndex + 1 < polygon1.Verticles.Length ? normalIndex + 1 : 0];

            // 如果圆心在多边形内部
            if (seperation < float.Epsilon)
            {
                manifold = new ContactManifold()
                {
                    LocalPoint  = (v1 + v2) * 0.5f,
                    LocalNormal = polygon1.Normals[normalIndex],
                    Points      = new[] { new ContactPoint()
                                          {
                                              LocalPoint = circle2.Center
                                          } }
                };
                return(true);
            }

            // 如果圆心的投影在 v1 顶点的外侧
            var u1 = Vector2D.Dot(c - v1, v2 - v1);

            if (u1 <= 0f)
            {
                if ((c - v1).LengthSquared() > radius * radius)
                {
                    manifold = null;
                    return(false);
                }

                manifold = new ContactManifold()
                {
                    LocalPoint  = v1,
                    LocalNormal = c - v1,
                    Points      = new[] { new ContactPoint()
                                          {
                                              LocalPoint = circle2.Center
                                          } }
                };
                manifold.LocalNormal.Normalize();
                return(true);
            }

            // 如果圆心的投影在 v2 顶点的外侧
            var u2 = Vector2D.Dot(c - v2, v1 - v2);

            if (u2 <= 0f)
            {
                if ((c - v2).LengthSquared() > radius * radius)
                {
                    manifold = null;
                    return(false);
                }

                manifold = new ContactManifold()
                {
                    LocalPoint  = v2,
                    LocalNormal = c - v2,
                    Points      = new[] { new ContactPoint()
                                          {
                                              LocalPoint = circle2.Center
                                          } }
                };
                manifold.LocalNormal.Normalize();
                return(true);
            }

            // 如果圆心的投影在 v1 和 v2 顶点的边上
            {
                var faceCenter = 0.5f * (v1 + v2);
                var s          = Vector2D.Dot(c - faceCenter, polygon1.Normals[normalIndex]);
                if (s > radius)
                {
                    manifold = null;
                    return(false);
                }

                manifold = new ContactManifold()
                {
                    LocalPoint  = faceCenter,
                    LocalNormal = polygon1.Normals[normalIndex],
                    Points      = new[] { new ContactPoint()
                                          {
                                              LocalPoint = circle2.Center
                                          } }
                };
                return(true);
            }
        }