GetFace() 공개 메소드

Return index of an unused face or creates a new one.
public GetFace ( ) : int
리턴 int
예제 #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>
        /// Create the first faces from (dimension + 1) vertices.
        /// </summary>
        /// <returns></returns>
        int[] CreateInitialHull(List <int> initialPoints)
        {
            var faces = new int[Dimension + 1];

            for (var i = 0; i < Dimension + 1; i++)
            {
                var vertices = new int[Dimension];
                for (int j = 0, k = 0; j <= Dimension; j++)
                {
                    if (i != j)
                    {
                        vertices[k++] = initialPoints[j];
                    }
                }
                var newFace = FacePool[ObjectManager.GetFace()];
                newFace.Vertices = vertices;
                Array.Sort(vertices);
                MathHelper.CalculateFacePlane(newFace, Center);
                faces[i] = newFace.Index;
            }

            // update the adjacency (check all pairs of faces)
            for (var i = 0; i < Dimension; i++)
            {
                for (var j = i + 1; j < Dimension + 1; j++)
                {
                    UpdateAdjacency(FacePool[faces[i]], FacePool[faces[j]]);
                }
            }

            return(faces);
        }
예제 #3
0
        /// <summary>
        /// Init the hull if Vertices.Length == Dimension.
        /// </summary>
        void InitSingle()
        {
            var vertices = new int[Dimension];

            for (int i = 0; i < Vertices.Length; i++)
            {
                vertices[i] = i;
            }

            var newFace = FacePool[ObjectManager.GetFace()];

            newFace.Vertices = vertices;
            Array.Sort(vertices);
            MathHelper.CalculateFacePlane(newFace, Center);

            // Make sure the normal point downwards in case this is used for triangulation
            if (newFace.Normal[Dimension - 1] >= 0.0)
            {
                for (int i = 0; i < Dimension; i++)
                {
                    newFace.Normal[i] *= -1.0;
                }
                newFace.Offset          = -newFace.Offset;
                newFace.IsNormalFlipped = !newFace.IsNormalFlipped;
            }

            ConvexFaces.Add(newFace.Index);
        }
        /// <summary>
        /// Find the (dimension+1) initial points and create the simplexes.
        /// Creates the initial simplex of n+1 vertices by using points from the bounding box.
        /// Special care is taken to ensure that the vertices chosen do not result in a degenerate shape
        /// where vertices are collinear (co-planar, etc). This would technically be resolved when additional
        /// vertices are checked in the main loop, but: 1) a degenerate simplex would not eliminate any other
        /// vertices (thus no savings there), 2) the creation of the face normal is prone to error.
        /// </summary>
        private void CreateInitialSimplex()
        {
            var initialPoints = FindInitialPoints();

            #region Create the first faces from (dimension + 1) vertices.

            var faces = new int[NumOfDimensions + 1];

            for (var i = 0; i < NumOfDimensions + 1; i++)
            {
                var vertices = new int[NumOfDimensions];
                for (int j = 0, k = 0; j <= NumOfDimensions; j++)
                {
                    if (i != j)
                    {
                        vertices[k++] = initialPoints[j];
                    }
                }
                var newFace = FacePool[ObjectManager.GetFace()];
                newFace.Vertices = vertices;
                Array.Sort(vertices);
                mathHelper.CalculateFacePlane(newFace, Center);
                faces[i] = newFace.Index;
            }
            // update the adjacency (check all pairs of faces)
            for (var i = 0; i < NumOfDimensions; i++)
            {
                for (var j = i + 1; j < NumOfDimensions + 1; j++)
                {
                    UpdateAdjacency(FacePool[faces[i]], FacePool[faces[j]]);
                }
            }

            #endregion

            #region Init the vertex beyond buffers.

            foreach (var faceIndex in faces)
            {
                var face = FacePool[faceIndex];
                FindBeyondVertices(face);
                if (face.VerticesBeyond.Count == 0)
                {
                    ConvexFaces.Add(face.Index);                                 // The face is on the hull
                }
                else
                {
                    UnprocessedFaces.Add(face);
                }
            }

            #endregion

            // Set all vertices to false (unvisited).
            foreach (var vertex in initialPoints)
            {
                VertexVisited[vertex] = false;
            }
        }
        /// <summary>
        /// Removes the faces "covered" by the current vertex and adds the newly created ones.
        /// </summary>
        /// <returns><c>true</c> if possible, <c>false</c> otherwise.</returns>
        private bool CreateCone()
        {
            var currentVertexIndex = CurrentVertex;

            ConeFaceBuffer.Clear();

            for (var fIndex = 0; fIndex < AffectedFaceBuffer.Count; fIndex++)
            {
                var oldFaceIndex = AffectedFaceBuffer[fIndex];
                var oldFace      = FacePool[oldFaceIndex];

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

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

                    var oldFaceAdjacentIndex = 0;
                    var adjFaceAdjacency     = adjacentFace.AdjacentFaces;
                    for (var j = 0; j < adjFaceAdjacency.Length; j++)
                    {
                        if (oldFaceIndex == adjFaceAdjacency[j])
                        {
                            oldFaceAdjacentIndex = j;
                            break;
                        }
                    }

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

                    var newFaceIndex = ObjectManager.GetFace();
                    var newFace      = FacePool[newFaceIndex];
                    var vertices     = newFace.Vertices;
                    for (var j = 0; j < NumOfDimensions; j++)
                    {
                        vertices[j] = oldFace.Vertices[j];
                    }
                    var oldVertexIndex = vertices[forbidden];

                    int orderedPivotIndex;

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

                    vertices[orderedPivotIndex] = CurrentVertex;

                    if (!mathHelper.CalculateFacePlane(newFace, InsidePoint))
                    {
                        return(false);
                    }

                    ConeFaceBuffer.Add(MakeDeferredFace(newFace, orderedPivotIndex, adjacentFace, oldFaceAdjacentIndex,
                                                        oldFace));
                }
            }

            return(true);
        }
예제 #6
0
        /// <summary>
        /// Removes the faces "covered" by the current vertex and adds the newly created ones.
        /// </summary>
        private bool CreateCone()
        {
            var currentVertexIndex = CurrentVertex.Index;

            ConeFaceBuffer.Clear();

            for (int fIndex = 0; fIndex < AffectedFaceBuffer.Count; fIndex++)
            {
                var oldFace = AffectedFaceBuffer[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;
                    }
                }

                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;

                    newFace  = ObjectManager.GetFace();
                    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;

                    if (!CalculateFacePlane(newFace))
                    {
                        return(false);
                    }

                    ConeFaceBuffer.Add(MakeDeferredFace(newFace, orderedPivotIndex, adjacentFace, oldFaceAdjacentIndex, oldFace));
                }
            }

            return(true);
        }