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