public void SearchNext() { NextVertex = -1; NextTriangle = -1; float lowestAngle = 360.0f; for (int i = 0; i < m_triangles.Count; i++) { if (i == CurrentTriangle) { continue; } Vector3i triangle = m_triangles[i]; if (!triangle.ContainsValue(CurrentVertex)) { continue; } int checkVertexMember = triangle.GetMemberByValue(CurrentVertex); int checkVertex = triangle.GetValueByMember(checkVertexMember + 1); if (m_line.Contains(checkVertex)) { continue; } Vector2f checkVertexValue = m_vertices[checkVertex].ToVector2(); int checkTriangleIndex = i; if (checkVertexValue == CurrentVertexValue) { // recursivly find next non matching vertex m_line.Add(checkVertex); OutsideVertexSearcher deepSearcher = new OutsideVertexSearcher(this); deepSearcher.CurrentTriangle = i; deepSearcher.CurrentVertex = checkVertex; deepSearcher.SearchNext(); m_line.RemoveAt(m_line.Count - 1); if (deepSearcher.NextVertex == -1) { continue; } checkVertex = deepSearcher.NextVertex; checkVertexValue = m_vertices[deepSearcher.NextVertex].ToVector2(); checkTriangleIndex = deepSearcher.NextTriangle; } float angle = Vector2f.AngleFrom3Points(PreviousVertexValue, CurrentVertexValue, checkVertexValue); if (angle <= lowestAngle) { NextVertex = checkVertex; NextTriangle = checkTriangleIndex; lowestAngle = angle; } } }
private static Vector2f[] VerticesToOutline(IReadOnlyList <Vector3f> vertexValues, List <Vector3i> vertices) { FindOutsideVertex(vertices, out int outsideVertexIndex, out int member); Vector3i outsideVertex = vertices[outsideVertexIndex]; List <int> line = new List <int>(); int point1 = outsideVertex.GetValueByMember(member); int point2 = outsideVertex.GetValueByMember(member + 1); line.Add(point1); line.Add(point2); int currentPoint = point2; int currentIndex = outsideVertexIndex; Vector2f prevPointValue = vertexValues[point1].ToVector2(); Vector2f curPointValue = vertexValues[point2].ToVector2(); while (true) { int nextPoint = -1; int nextVertexIndex = -1; float lowestAngle = 360.0f; for (int i = 0; i < vertices.Count; i++) { if (i == currentIndex) { continue; } Vector3i vertex = vertices[i]; if (!vertex.ContainsValue(currentPoint)) { continue; } int checkPointMember = vertex.GetMemberByValue(currentPoint); int checkPoint = vertex.GetValueByMember(checkPointMember + 1); if (line.Contains(checkPoint)) { continue; } Vector2f nextPointValue = vertexValues[checkPoint].ToVector2(); float angle = Vector2f.AngleFrom3Points(prevPointValue, curPointValue, nextPointValue); if (angle < lowestAngle) { nextPoint = checkPoint; nextVertexIndex = i; lowestAngle = angle; } } if (nextVertexIndex == -1) { Vector3i currentVertex = vertices[currentIndex]; int nextPointMember = currentVertex.GetMemberByValue(currentPoint); nextPoint = currentVertex.GetValueByMember(nextPointMember + 1); nextVertexIndex = currentIndex; if (line.Contains(nextPoint)) { break; } } prevPointValue = curPointValue; curPointValue = vertexValues[nextPoint].ToVector2(); currentPoint = nextPoint; line.Add(nextPoint); currentIndex = nextVertexIndex; } Vector2f[] outline = new Vector2f[line.Count]; for (int i = 0; i < line.Count; i++) { outline[i] = vertexValues[line[i]].ToVector2(); } HashSet <int> deletePoints = new HashSet <int>(); foreach (int point in line) { deletePoints.Add(point); } while (true) { bool isNew = false; for (int i = 0; i < vertices.Count; i++) { Vector3i vertex = vertices[i]; if (deletePoints.Contains(vertex.X)) { isNew |= deletePoints.Add(vertex.Y); isNew |= deletePoints.Add(vertex.Z); vertices.RemoveAt(i--); } else if (deletePoints.Contains(vertex.Y)) { isNew |= deletePoints.Add(vertex.Z); isNew |= deletePoints.Add(vertex.X); vertices.RemoveAt(i--); } else if (deletePoints.Contains(vertex.Z)) { isNew |= deletePoints.Add(vertex.X); isNew |= deletePoints.Add(vertex.Y); vertices.RemoveAt(i--); } } if (!isNew) { break; } } return(outline); }