Exemplo n.º 1
0
        /// <summary>
        /// Fins the convex hull.
        /// </summary>
        void FindConvexHull()
        {
            // Find the (dimension+1) initial points and create the simplexes.
            InitConvexHull();

            // Expand the convex hull and faces.
            while (UnprocessedFaces.First != null)
            {
                var currentFace = UnprocessedFaces.First;
                CurrentVertex = currentFace.FurthestVertex;

                UpdateCenter();

                // The affected faces get tagged
                TagAffectedFaces(currentFace);

                // Create the cone from the currentVertex and the affected faces horizon.
                if (!SingularVertices.Contains(CurrentVertex) && CreateCone())
                {
                    CommitCone();
                }
                else
                {
                    HandleSingular();
                }

                // Need to reset the tags
                int count = AffectedFaceBuffer.Count;
                for (int i = 0; i < count; i++)
                {
                    AffectedFaceFlags[AffectedFaceBuffer[i]] = false;
                }
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Найти выпуклую оболочку
        /// </summary>
        void FindConvexHull()
        {
            // Найти (размер + 1) начальной точки и создать симплексы
            InitConvexHull();

            // Развернут ьвыпуклую оболочку и грани
            while (UnprocessedFaces.First != null)
            {
                var currentFace = UnprocessedFaces.First;
                CurrentVertex = currentFace.FurthestVertex;

                UpdateCenter();

                // Затронутые грание помечаются
                TagAffectedFaces(currentFace);

                // Создать конус из текущей вершины и затронуть грани горизонта
                if (!SingularVertices.Contains(CurrentVertex) && CreateCone())
                {
                    CommitCone();
                }
                else
                {
                    HandleSingular();
                }

                // Нужно для очистки тегов
                int count = AffectedFaceBuffer.Count;
                for (int i = 0; i < count; i++)
                {
                    AffectedFaceFlags[AffectedFaceBuffer[i]] = false;
                }
            }
        }
Exemplo n.º 3
0
        public void Clear()
        {
            UpdateBuffer  = new SimplexWrap <VERTEX> [Dimension];
            UpdateIndices = new int[Dimension];

            InputVertices  = null;
            CurrentVertex  = null;
            FurthestVertex = null;
            MaxDistance    = float.NegativeInfinity;

            ConvexSimplexs.Clear();
            AffectedFaceBuffer.Clear();
            TraverseStack.Clear();
            SingularVertices.Clear();
            ConeFaceBuffer.Clear();
            ObjectManager.Clear();
            UnprocessedFaces.Clear();
            EmptyBuffer.Clear();
            BeyondBuffer.Clear();

            for (int i = 0; i < CONNECTOR_TABLE_SIZE; i++)
            {
                ConnectorTable[i].Clear();
            }
        }
        /// <summary>
        /// Gets/calculates the convex hull. This is
        /// </summary>
        internal void GetConvexHull()
        {
            // accessing a 1D array is quicker than a jagged array, so the first step is to make this array
            SerializeVerticesToPositions();
            // next the bounding box extremes are found. This is used to shift, scale and find the starting simplex.
            FindBoundingBoxPoints();
            // the positions are shifted to avoid divide by zero problems
            // and if Delaunay or Voronoi, then the parabola terms are scaled back to match the size of the other coords
            ShiftAndScalePositions();
            // Find the (dimension+1) initial points and create the simplexes.
            CreateInitialSimplex();

            // Now, the main loop. These initial faces of a simplex are replaced and expanded
            // outwards to make the convex hull and faces.
            while (UnprocessedFaces.First != null)
            {
                var currentFace = UnprocessedFaces.First;
                CurrentVertex = currentFace.FurthestVertex;

                UpdateCenter();

                // The affected faces get tagged
                TagAffectedFaces(currentFace);

                // Create the cone from the currentVertex and the affected faces horizon.
                if (!SingularVertices.Contains(CurrentVertex) && CreateCone())
                {
                    CommitCone();
                }
                else
                {
                    HandleSingular();
                }

                // Need to reset the tags
                var count = AffectedFaceBuffer.Count;
                for (var i = 0; i < count; i++)
                {
                    AffectedFaceFlags[AffectedFaceBuffer[i]] = false;
                }
            }
        }
        /// <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;
            }
        }
Exemplo n.º 6
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;
            }
        }