private void CommitCone() { for (int i = 0; i < ConeFaceBuffer.Count; i++) { DeferredFace deferredFace = ConeFaceBuffer[i]; ConvexFaceInternal face = deferredFace.Face; ConvexFaceInternal pivot = deferredFace.Pivot; ConvexFaceInternal oldFace = deferredFace.OldFace; int faceIndex = deferredFace.FaceIndex; face.AdjacentFaces[faceIndex] = pivot.Index; pivot.AdjacentFaces[deferredFace.PivotIndex] = face.Index; for (int j = 0; j < NumOfDimensions; j++) { if (j != faceIndex) { FaceConnector connector = ObjectManager.GetConnector(); connector.Update(face, j, NumOfDimensions); ConnectFace(connector); } } if (pivot.VerticesBeyond.Count == 0) { FindBeyondVertices(face, oldFace.VerticesBeyond); } else if (pivot.VerticesBeyond.Count < oldFace.VerticesBeyond.Count) { FindBeyondVertices(face, pivot.VerticesBeyond, oldFace.VerticesBeyond); } else { FindBeyondVertices(face, oldFace.VerticesBeyond, pivot.VerticesBeyond); } if (face.VerticesBeyond.Count == 0) { ConvexFaces.Add(face.Index); UnprocessedFaces.Remove(face); ObjectManager.DepositVertexBuffer(face.VerticesBeyond); face.VerticesBeyond = EmptyBuffer; } else { UnprocessedFaces.Add(face); } ObjectManager.DepositDeferredFace(deferredFace); } for (int k = 0; k < AffectedFaceBuffer.Count; k++) { int num = AffectedFaceBuffer[k]; UnprocessedFaces.Remove(FacePool[num]); ObjectManager.DepositFace(num); } }
/// <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); } } } }