Пример #1
0
        private void CreateInitialSimplex()
        {
            List <int> list = FindInitialPoints();

            int[] array = new int[NumOfDimensions + 1];
            for (int i = 0; i < NumOfDimensions + 1; i++)
            {
                int[] array2 = new int[NumOfDimensions];
                int   j      = 0;
                int   num    = 0;
                for (; j <= NumOfDimensions; j++)
                {
                    if (i != j)
                    {
                        if (j == list.Count)
                        {
                            int num2 = 0;
                            num2++;
                        }
                        int num3 = list[j];
                        array2[num++] = num3;
                    }
                }
                ConvexFaceInternal convexFaceInternal = FacePool[ObjectManager.GetFace()];
                convexFaceInternal.Vertices = array2;
                Array.Sort(array2);
                mathHelper.CalculateFacePlane(convexFaceInternal, Center);
                array[i] = convexFaceInternal.Index;
            }
            for (int k = 0; k < NumOfDimensions; k++)
            {
                for (int l = k + 1; l < NumOfDimensions + 1; l++)
                {
                    UpdateAdjacency(FacePool[array[k]], FacePool[array[l]]);
                }
            }
            int[] array3 = array;
            foreach (int num5 in array3)
            {
                ConvexFaceInternal convexFaceInternal2 = FacePool[num5];
                FindBeyondVertices(convexFaceInternal2);
                if (convexFaceInternal2.VerticesBeyond.Count == 0)
                {
                    ConvexFaces.Add(convexFaceInternal2.Index);
                }
                else
                {
                    UnprocessedFaces.Add(convexFaceInternal2);
                }
            }
            foreach (int item in list)
            {
                VertexVisited[item] = false;
            }
        }
Пример #2
0
        /// <summary>
        /// Commits a cone and adds a vertex to the convex hull.
        /// </summary>
        void CommitCone()
        {
            // Add the current vertex.
            ConvexHull.Add(CurrentVertex);

            // Fill the adjacency.
            for (int i = 0; i < ConeFaceBuffer.Count; i++)
            {
                var face = ConeFaceBuffer[i];

                var newFace           = face.Face;
                var adjacentFace      = face.Pivot;
                var oldFace           = face.OldFace;
                var orderedPivotIndex = face.FaceIndex;

                newFace.AdjacentFaces[orderedPivotIndex]    = adjacentFace;
                adjacentFace.AdjacentFaces[face.PivotIndex] = newFace;

                // let there be a connection.
                for (int j = 0; j < Dimension; j++)
                {
                    if (j == orderedPivotIndex)
                    {
                        continue;
                    }
                    var connector = ObjectManager.GetConnector();
                    connector.Update(newFace, j, Dimension);
                    ConnectFace(connector);
                }

                // This could slightly help...
                if (adjacentFace.VerticesBeyond.Count < oldFace.VerticesBeyond.Count)
                {
                    FindBeyondVertices(newFace, adjacentFace.VerticesBeyond, oldFace.VerticesBeyond);
                }
                else
                {
                    FindBeyondVertices(newFace, oldFace.VerticesBeyond, adjacentFace.VerticesBeyond);
                }

                // This face will definitely lie on the hull
                if (newFace.VerticesBeyond.Count == 0)
                {
                    ConvexFaces.Add(newFace);
                    UnprocessedFaces.Remove(newFace);
                    ObjectManager.DepositVertexBuffer(newFace.VerticesBeyond);
                    newFace.VerticesBeyond = EmptyBuffer;
                }
                else // Add the face to the list
                {
                    UnprocessedFaces.Add(newFace);
                }

                // recycle the object.
                ObjectManager.DepositDeferredFace(face);
            }

            // Recycle the affected faces.
            for (int fIndex = 0; fIndex < AffectedFaceBuffer.Count; fIndex++)
            {
                var face = AffectedFaceBuffer[fIndex];
                UnprocessedFaces.Remove(face);
                ObjectManager.DepositFace(face);
            }
        }
Пример #3
0
        /// <summary>
        /// Removes the faces "covered" by the current vertex and adds the newly created ones.
        /// </summary>
        private void CreateCone()
        {
            var oldFaces = AffectedFaceBuffer;

            var currentVertexIndex = CurrentVertex.Index;

            for (int fIndex = 0; fIndex < oldFaces.Count; fIndex++)
            {
                var oldFace = oldFaces[fIndex];

                // Find the faces that need to be updated
                int updateCount = 0;
                for (int i = 0; i < Dimension; i++)
                {
                    var af = oldFace.AdjacentFaces[i];
                    if (af.Tag == 0) // Tag == 0 when oldFaces does not contain af
                    {
                        UpdateBuffer[updateCount]  = af;
                        UpdateIndices[updateCount] = i;
                        ++updateCount;
                    }
                }

                // Recycle the face for future use
                if (updateCount == 0)
                {
                    // If the face is present in the unprocessed list, remove it
                    UnprocessedFaces.Remove(oldFace);

                    RecycleFace(oldFace);
                    RecycledFaceStack.Push(oldFace);
                }

                for (int i = 0; i < updateCount; i++)
                {
                    var adjacentFace = UpdateBuffer[i];

                    int oldFaceAdjacentIndex = 0;
                    var adjFaceAdjacency     = adjacentFace.AdjacentFaces;
                    for (int j = 0; j < Dimension; j++)
                    {
                        if (object.ReferenceEquals(oldFace, adjFaceAdjacency[j]))
                        {
                            oldFaceAdjacentIndex = j;
                            break;
                        }
                    }

                    var forbidden = UpdateIndices[i]; // Index of the face that corresponds to this adjacent face

                    ConvexFaceInternal newFace;

                    int          oldVertexIndex;
                    VertexWrap[] vertices;

                    // Recycle the oldFace
                    if (i == updateCount - 1)
                    {
                        RecycleFace(oldFace);
                        newFace        = oldFace;
                        vertices       = newFace.Vertices;
                        oldVertexIndex = vertices[forbidden].Index;
                    }
                    else // Pop a face from the recycled stack or create a new one
                    {
                        newFace  = GetNewFace();
                        vertices = newFace.Vertices;
                        for (int j = 0; j < Dimension; j++)
                        {
                            vertices[j] = oldFace.Vertices[j];
                        }
                        oldVertexIndex = vertices[forbidden].Index;
                    }

                    int orderedPivotIndex;

                    // correct the ordering
                    if (currentVertexIndex < oldVertexIndex)
                    {
                        orderedPivotIndex = 0;
                        for (int j = forbidden - 1; j >= 0; j--)
                        {
                            if (vertices[j].Index > currentVertexIndex)
                            {
                                vertices[j + 1] = vertices[j];
                            }
                            else
                            {
                                orderedPivotIndex = j + 1;
                                break;
                            }
                        }
                    }
                    else
                    {
                        orderedPivotIndex = Dimension - 1;
                        for (int j = forbidden + 1; j < Dimension; j++)
                        {
                            if (vertices[j].Index < currentVertexIndex)
                            {
                                vertices[j - 1] = vertices[j];
                            }
                            else
                            {
                                orderedPivotIndex = j - 1;
                                break;
                            }
                        }
                    }

                    vertices[orderedPivotIndex] = CurrentVertex;

                    CalculateFacePlane(newFace);
                    newFace.AdjacentFaces[orderedPivotIndex]         = adjacentFace;
                    adjacentFace.AdjacentFaces[oldFaceAdjacentIndex] = newFace;

                    // let there be a connection.
                    for (int j = 0; j < Dimension; j++)
                    {
                        if (j == orderedPivotIndex)
                        {
                            continue;
                        }
                        var connector = GetNewConnector();
                        connector.Update(newFace, j, Dimension);
                        ConnectFace(connector);
                    }

                    // This could slightly help...
                    if (adjacentFace.VerticesBeyond.Count < oldFace.VerticesBeyond.Count)
                    {
                        FindBeyondVertices(newFace, adjacentFace.VerticesBeyond, oldFace.VerticesBeyond);
                    }
                    else
                    {
                        FindBeyondVertices(newFace, oldFace.VerticesBeyond, adjacentFace.VerticesBeyond);
                    }

                    // This face will definitely lie on the hull
                    if (newFace.VerticesBeyond.Count == 0)
                    {
                        ConvexFaces.Add(newFace);
                        UnprocessedFaces.Remove(newFace);
                        EmptyBufferStack.Push(newFace.VerticesBeyond);
                        newFace.VerticesBeyond = EmptyBuffer;
                    }
                    else // Add the face to the list
                    {
                        UnprocessedFaces.Add(newFace);
                    }
                }
            }
        }