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