/// <summary>
        /// Commits a cone and adds a vertex to the convex hull.
        /// </summary>
        private void CommitCone()
        {
            // Fill the adjacency.
            for (var 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.Index;
                adjacentFace.AdjacentFaces[face.PivotIndex] = newFace.Index;

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

                // the id adjacent face on the hull? If so, we can use simple method to find beyond vertices.
                if (adjacentFace.VerticesBeyond.Count == 0)
                    FindBeyondVertices(newFace, oldFace.VerticesBeyond);
                // it is slightly more effective if the face with the lower number of beyond vertices comes first.
                else 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.Index);
                    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 (var fIndex = 0; fIndex < AffectedFaceBuffer.Count; fIndex++)
            {
                var face = AffectedFaceBuffer[fIndex];
                UnprocessedFaces.Remove(FacePool[face]);
                ObjectManager.DepositFace(face);
            }
        }
        /// <summary>
        /// Handles singular vertex.
        /// </summary>
        private void HandleSingular()
        {
            SingularVertices.Add(CurrentVertex);

            // This means that all the affected faces must be on the hull and that all their "vertices beyond" are singular.
            for (var fIndex = 0; fIndex < AffectedFaceBuffer.Count; fIndex++)
            {
                var face = FacePool[AffectedFaceBuffer[fIndex]];
                var vb   = face.VerticesBeyond;
                for (var i = 0; i < vb.Count; i++)
                {
                    SingularVertices.Add(vb[i]);
                }

                ConvexFaces.Add(face.Index);
                UnprocessedFaces.Remove(face);
                ObjectManager.DepositVertexBuffer(face.VerticesBeyond);
                face.VerticesBeyond = EmptyBuffer;
            }
        }
Example #3
0
        /// <summary>
        /// Рукоятки исключительных вершин
        /// </summary>
        void HandleSingular()
        {
            RollbackCenter();
            SingularVertices.Add(CurrentVertex);

            // Это означает, что все затронутые грани должны находиться на корпусе и что все "вершины за пределами" единичны
            for (int fIndex = 0; fIndex < AffectedFaceBuffer.Count; fIndex++)
            {
                var face = FacePool[AffectedFaceBuffer[fIndex]];
                var vb   = face.VerticesBeyond;
                for (int i = 0; i < vb.Count; i++)
                {
                    SingularVertices.Add(vb[i]);
                }

                ConvexFaces.Add(face.Index);
                UnprocessedFaces.Remove(face);
                ObjectManager.DepositVertexBuffer(face.VerticesBeyond);
                face.VerticesBeyond = EmptyBuffer;
            }
        }
Example #4
0
        /// <summary>
        /// Фиксирует конус и добавляет вершину к выпуклой оболочки
        /// </summary>
        void CommitCone()
        {
            // Заполнение смежностей
            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.Index;
                adjacentFace.AdjacentFaces[face.PivotIndex] = newFace.Index;

                // Пусть здесь будет соединение
                for (int j = 0; j < Dimension; j++)
                {
                    if (j == orderedPivotIndex)
                    {
                        continue;
                    }
                    var connector = ObjectManager.GetConnector();
                    connector.Update(newFace, j, Dimension);
                    ConnectFace(connector);
                }

                // Идентификатор смежной грани на корпусе? Если да, то мы можем использовать простой метод, чтобы найти вершины за пределами
                if (adjacentFace.VerticesBeyond.Count == 0)
                {
                    FindBeyondVertices(newFace, oldFace.VerticesBeyond);
                }
                // Это более эффективно, если грань с меньшим числом вершин не приходит первой
                else if (adjacentFace.VerticesBeyond.Count < oldFace.VerticesBeyond.Count)
                {
                    FindBeyondVertices(newFace, adjacentFace.VerticesBeyond, oldFace.VerticesBeyond);
                }
                else
                {
                    FindBeyondVertices(newFace, oldFace.VerticesBeyond, adjacentFace.VerticesBeyond);
                }

                // Это лицо, грань, лежит на холме
                if (newFace.VerticesBeyond.Count == 0)
                {
                    ConvexFaces.Add(newFace.Index);
                    UnprocessedFaces.Remove(newFace);
                    ObjectManager.DepositVertexBuffer(newFace.VerticesBeyond);
                    newFace.VerticesBeyond = EmptyBuffer;
                }
                else // Добавить грань в список
                {
                    UnprocessedFaces.Add(newFace);
                }

                // Утилизировать объект
                ObjectManager.DepositDeferredFace(face);
            }

            // Утилизировать поврежденные грани
            for (int fIndex = 0; fIndex < AffectedFaceBuffer.Count; fIndex++)
            {
                var face = AffectedFaceBuffer[fIndex];
                UnprocessedFaces.Remove(FacePool[face]);
                ObjectManager.DepositFace(face);
            }
        }