Exemplo n.º 1
0
        /// Create a loop. This automatically adjusts connectivity.
        /// @param vertices an array of vertices, these are copied
        /// @param count the vertex count
        public void CreateLoop(Vector2[] vertices, int count = -1)
        {
            if (count == -1)
            {
                count = vertices.Length;
            }

            Debug.Assert(Vertices == null && Count == 0);
            Debug.Assert(count >= 3);
            if (count < 3)
            {
                return;
            }

            for (var i = 1; i < count; ++i)
            {
                var v1 = vertices[i - 1];
                var v2 = vertices[i];

                // If the code crashes here, it means your vertices are too close together.
                Debug.Assert(Vector2.DistanceSquared(v1, v2) > Settings.LinearSlop * Settings.LinearSlop);
            }

            Count    = count + 1;
            Vertices = new Vector2[Count];
            Array.Copy(vertices, Vertices, count);
            Vertices[count] = Vertices[0];
            PrevVertex      = Vertices[Count - 2];
            NextVertex      = Vertices[1];
        }
Exemplo n.º 2
0
        /// <summary>
        /// Create a chain with ghost vertices to connect multiple chains together.
        /// </summary>
        /// <param name="vertices">an array of vertices, these are copied</param>
        /// <param name="count">the vertex count</param>
        /// <param name="prevVertex">previous vertex from chain that connects to the start</param>
        /// <param name="nextVertex">next vertex from chain that connects to the end</param>
        public void CreateChain(Vector2[] vertices, int count, Vector2 prevVertex, Vector2 nextVertex)
        {
            Debug.Assert(Vertices == null && Count == 0);
            Debug.Assert(count >= 2);
            for (var i = 1; i < count; ++i)
            {
                // If the code crashes here, it means your vertices are too close together.
                Debug.Assert(
                    Vector2.DistanceSquared(vertices[i - 1], vertices[i])
                    > Settings.LinearSlop * Settings.LinearSlop);
            }

            Count    = count;
            Vertices = new Vector2[count];
            Array.Copy(vertices, Vertices, count);

            PrevVertex = prevVertex;
            NextVertex = nextVertex;
        }
Exemplo n.º 3
0
        /// Create a convex hull from the given array of local points.
        /// The count must be in the range [3, b2_maxPolygonVertices].
        /// @warning the points may be re-ordered, even if they form a convex polygon
        /// @warning collinear points are handled but not removed. Collinear points
        /// may lead to poor stacking behavior.
        public void Set(Vector2[] vertices, int count = -1)
        {
            if (count == -1)
            {
                count = vertices.Length;
            }

            Debug.Assert(3 <= count && count <= MaxPolygonVertices);

            // 顶点数小于3,视为盒子
            if (count < 3)
            {
                SetAsBox(1.0f, 1.0f);
                return;
            }

            // 顶点数最大为 MaxPolygonVertices
            var n = Math.Min(count, MaxPolygonVertices);

            // Perform welding and copy vertices into local buffer.
            Span <Vector2> ps = stackalloc Vector2[MaxPolygonVertices];

            var tempCount = 0;

            for (var i = 0; i < n; ++i)
            {
                var v = vertices[i];

                var unique = true;
                for (var j = 0; j < tempCount; ++j)
                {
                    if (Vector2.DistanceSquared(v, ps[j])
                        < 0.5f * Settings.LinearSlop * (0.5f * Settings.LinearSlop))
                    {
                        unique = false;
                        break;
                    }
                }

                if (unique)
                {
                    ps[tempCount] = v;
                    tempCount++;
                }
            }

            n = tempCount;
            if (n < 3)
            {
                // Polygon is degenerate.
                throw new InvalidOperationException("Invalid polygon shape");
            }

            // Create the convex hull using the Gift wrapping algorithm
            // http://en.wikipedia.org/wiki/Gift_wrapping_algorithm

            // Find the right most point on the hull
            var i0 = 0;
            var x0 = ps[0].x;

            for (var i = 1; i < n; ++i)
            {
                var x = ps[i].x;
                if (x > x0 || x.Equals(x0) && ps[i].y < ps[i0].y)
                {
                    i0 = i;
                    x0 = x;
                }
            }

            Span <int> hull = stackalloc int[MaxPolygonVertices];
            var        m    = 0;
            var        ih   = i0;

            for (;;)
            {
                Debug.Assert(m < MaxPolygonVertices);
                hull[m] = ih;

                var ie = 0;
                for (var j = 1; j < n; ++j)
                {
                    if (ie == ih)
                    {
                        ie = j;
                        continue;
                    }

                    var r = ps[ie] - ps[hull[m]];
                    var v = ps[j] - ps[hull[m]];
                    var c = MathUtils.Cross(r, v);
                    if (c < 0.0f)
                    {
                        ie = j;
                    }

                    // Collinearity check
                    if (c.Equals(0.0f) && v.LengthSquared() > r.LengthSquared())
                    {
                        ie = j;
                    }
                }

                ++m;
                ih = ie;

                if (ie == i0)
                {
                    break;
                }
            }

            if (m < 3)
            {
                // Polygon is degenerate.
                throw new InvalidOperationException("Invalid polygon shape");
            }

            Count = m;

            // Copy vertices.
            for (var i = 0; i < m; ++i)
            {
                Vertices[i] = ps[hull[i]];
            }

            // Compute normals. Ensure the edges have non-zero length.
            for (var i = 0; i < m; ++i)
            {
                var i1   = i;
                var i2   = i + 1 < m ? i + 1 : 0;
                var edge = Vertices[i2] - Vertices[i1];
                Debug.Assert(edge.LengthSquared() > Settings.Epsilon * Settings.Epsilon);
                Normals[i] = MathUtils.Cross(edge, 1.0f);
                Normals[i].Normalize();
            }

            // Compute the polygon centroid.
            Centroid = ComputeCentroid(Vertices, m);
        }