コード例 #1
0
        // Find the separation between poly1 and poly2 for a give edge normal on poly1.
        private static float EdgeSeparation(
            int edge1,
            PolygonFixture poly1,
            WorldTransform xf1,
            PolygonFixture poly2,
            WorldTransform xf2)
        {
            var vertices1 = poly1.Vertices;
            var normals1  = poly1.Normals;

            var count2    = poly2.Count;
            var vertices2 = poly2.Vertices;

            System.Diagnostics.Debug.Assert(0 <= edge1 && edge1 < poly1.Count);

            // Convert normal from poly1's frame into poly2's frame.
            var normal1World = xf1.Rotation * normals1[edge1];
            var normal1      = -xf2.Rotation * normal1World;

            // Find support vertex on poly2 for -normal.
            var index  = 0;
            var minDot = float.MaxValue;

            for (var i = 0; i < count2; ++i)
            {
                var dot = Vector2Util.Dot(ref vertices2[i], ref normal1);
                if (dot < minDot)
                {
                    minDot = dot;
                    index  = i;
                }
            }

            var v1 = xf1.ToGlobal(vertices1[edge1]);
            var v2 = xf2.ToGlobal(vertices2[index]);
// ReSharper disable RedundantCast Necessary for FarPhysics.
            var separation = Vector2Util.Dot((Vector2)(v2 - v1), normal1World);

// ReSharper restore RedundantCast
            return(separation);
        }
コード例 #2
0
        // Find the max separation between poly1 and poly2 using edge normals from poly1.
        private static float FindMaxSeparation(
            out int edgeIndex,
            PolygonFixture poly1,
            WorldTransform xf1,
            PolygonFixture poly2,
            WorldTransform xf2)
        {
            var count1   = poly1.Count;
            var normals1 = poly1.Normals;

            // Vector pointing from the centroid of poly1 to the centroid of poly2.
// ReSharper disable RedundantCast Necessary for FarPhysics.
            var d = (Vector2)(xf2.ToGlobal(poly2.Centroid) - xf1.ToGlobal(poly1.Centroid));
// ReSharper restore RedundantCast
            var dLocal1 = -xf1.Rotation * d;

            // Find edge normal on poly1 that has the largest projection onto d.
            var edge   = 0;
            var maxDot = float.MinValue;

            for (var i = 0; i < count1; ++i)
            {
                var dot = Vector2Util.Dot(ref normals1[i], ref dLocal1);
                if (dot > maxDot)
                {
                    maxDot = dot;
                    edge   = i;
                }
            }

            // Get the separation for the edge normal.
            var s = EdgeSeparation(edge, poly1, xf1, poly2, xf2);

            // Check the separation for the previous edge normal.
            var prevEdge = edge - 1 >= 0 ? edge - 1 : count1 - 1;
            var sPrev    = EdgeSeparation(prevEdge, poly1, xf1, poly2, xf2);

            // Check the separation for the next edge normal.
            var nextEdge = edge + 1 < count1 ? edge + 1 : 0;
            var sNext    = EdgeSeparation(nextEdge, poly1, xf1, poly2, xf2);

            // Find the best edge and the search direction.
            int   bestEdge;
            float bestSeparation;
            int   increment;

            if (sPrev > s && sPrev > sNext)
            {
                increment      = -1;
                bestEdge       = prevEdge;
                bestSeparation = sPrev;
            }
            else if (sNext > s)
            {
                increment      = 1;
                bestEdge       = nextEdge;
                bestSeparation = sNext;
            }
            else
            {
                edgeIndex = edge;
                return(s);
            }

            // Perform a local search for the best edge normal.
            for (;;)
            {
                if (increment == -1)
                {
                    edge = bestEdge - 1 >= 0 ? bestEdge - 1 : count1 - 1;
                }
                else
                {
                    edge = bestEdge + 1 < count1 ? bestEdge + 1 : 0;
                }

                s = EdgeSeparation(edge, poly1, xf1, poly2, xf2);

                if (s <= bestSeparation)
                {
                    break;
                }

                bestEdge       = edge;
                bestSeparation = s;
            }

            edgeIndex = bestEdge;
            return(bestSeparation);
        }