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; } }
/// <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); } }
/// <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); } } } }