/// <summary> /// Calculate the triangulation of the supplied vertices. /// /// This overload allows you to reuse the result object, to prevent /// garbage from being created. /// </summary> /// <param name="verts">List of vertices to use for calculation</param> /// <param name="result">Result object to store the triangulation in</param> public void CalculateTriangulation(IList <Vector2> verts, ref DelaunayTriangulation result) { if (verts == null) { throw new ArgumentNullException("points"); } if (verts.Count < 3) { throw new ArgumentException("You need at least 3 points for a triangulation"); } triangles.Clear(); this.verts = verts; highest = 0; for (int i = 0; i < verts.Count; i++) { if (Higher(highest, i)) { highest = i; } } //ShuffleIndices(); // Add first triangle, the bounding triangle. triangles.Add(new TriangleNode(-2, -1, highest)); RunBowyerWatson(); GenerateResult(ref result); this.verts = null; }
/// <summary> /// Filter the points array and triangle tree into a readable result. /// </summary> void GenerateResult(ref DelaunayTriangulation result) { if (result == null) { result = new DelaunayTriangulation(); } result.Clear(); for (int i = 0; i < verts.Count; i++) { result.Vertices.Add(verts[i]); } for (int i = 1; i < triangles.Count; i++) { var t = triangles[i]; if (t.IsLeaf && t.IsInner) { result.Triangles.Add(t.P0); result.Triangles.Add(t.P1); result.Triangles.Add(t.P2); } } }
internal VoronoiDiagram() { Triangulation = new DelaunayTriangulation(); Sites = Triangulation.Vertices; Vertices = new List <Vector2>(); Edges = new List <Edge>(); FirstEdgeBySite = new List <int>(); }
/// <summary> /// Calculate the triangulation of the supplied vertices /// </summary> /// <param name="verts">List of vertices to use for calculation</param> /// <returns>The calculated Delaunay triangulation<returns> public DelaunayTriangulation CalculateTriangulation(IList <Vector2> verts) { DelaunayTriangulation result = null; CalculateTriangulation(verts, ref result); return(result); }
/// <summary> /// Calculate the triangulation of the supplied vertices. /// /// This overload allows you to reuse the result object, to prevent /// garbage from being created. /// </summary> /// <param name="verts">List of vertices to use for calculation</param> /// <param name="result">Result object to store the triangulation in</param> public void CalculateTriangulation(IList <Vector2> verts, ref DelaunayTriangulation result) { if (verts == null) { throw new ArgumentNullException("points"); } if (verts.Count < 3) { throw new ArgumentException("You need at least 3 points for a triangulation"); } triangles.Clear(); this.verts = verts; highest = 0; for (int i = 0; i < verts.Count; i++) { if (Higher(highest, i)) { highest = i; } } //ShuffleIndices(); // Add first triangle, the bounding triangle. triangles.Add(new TriangleNode(-2, -1, highest)); RunBowyerWatson(); GenerateResult(ref result); for (int i = 0; i < result.Triangles.Count; i += 3) { float dot = Mathf.Abs(Vector2.Dot((result.Vertices[result.Triangles[i]] - result.Vertices[result.Triangles[i + 1]]).normalized, (result.Vertices[result.Triangles[i]] - result.Vertices[result.Triangles[i + 2]]).normalized)); if (dot > 0.999f) { //Debug.LogWarning("REMOVED: " + dot); result.Triangles.RemoveAt(i); result.Triangles.RemoveAt(i); result.Triangles.RemoveAt(i); i -= 3; } else { //Debug.Log( dot); } } this.verts = null; }
public Section(float[] points, int[] tri, int xyz, float value, Vector3 maxVer, Vector3 minVer) { //xyz截面方向,value截面值 direction = xyz; sectionValue = value; vMax = maxVer; vMin = minVer; if (vMax.x - vMin.x > vMax.y - vMin.y) { if (vMax.x - vMin.x > vMax.z - vMin.z) { Max = vMax.x; Min = vMin.x; } else { Max = vMax.z; Min = vMin.z; } } else { if (vMax.y - vMin.y > vMax.z - vMin.z) { Max = vMax.y; Min = vMin.y; } else { Max = vMax.z; Min = vMin.z; } } int pointNum = points.Length / 3; int triNum = tri.Length / 3; //int[] mark = new int[pointNum * pointNum]; List <long> mark = new List <long>(); List <int> n0 = new List <int>(); List <int> n1 = new List <int>(); List <float> frac = new List <float>(); List <Vector2> v2 = new List <Vector2>(); List <Vector3> v3 = new List <Vector3>(); int[] pointIndex = new int[] { 0, 1, 1, 2, 2, 0 }; int ni0 = 0, ni1 = 0; float f = 0; for (int i = 0; i < triNum; ++i) { for (int pointIndexI = 0; pointIndexI < 3; ++pointIndexI) { int triPoint0 = tri[3 * i + pointIndex[2 * pointIndexI]]; int triPoint1 = tri[3 * i + pointIndex[2 * pointIndexI + 1]]; bool isSection = false; if (points[3 * triPoint0 + xyz] < value) { if (points[3 * triPoint1 + xyz] > value) { ni0 = triPoint0; ni1 = triPoint1; f = (value - points[3 * ni0 + xyz]) / (points[3 * ni1 + xyz] - points[3 * ni0 + xyz]); isSection = true; } else if (points[3 * triPoint1 + xyz] == value) { ni0 = triPoint1; ni1 = triPoint1; f = 0; isSection = true; } } else if (points[3 * triPoint0 + xyz] > value) { if (points[3 * triPoint1 + xyz] < value) { ni0 = triPoint1; ni1 = triPoint0; f = (value - points[3 * ni0 + xyz]) / (points[3 * ni1 + xyz] - points[3 * ni0 + xyz]); isSection = true; } else if (points[3 * triPoint1 + xyz] == value) { ni0 = triPoint1; ni1 = triPoint1; f = 0; isSection = true; } } else if (points[3 * triPoint0 + xyz] == value) { if (points[3 * triPoint1 + xyz] < value) { ni0 = triPoint0; ni1 = triPoint0; f = 0; isSection = true; } else if (points[3 * triPoint1 + xyz] > value) { ni0 = triPoint0; ni1 = triPoint0; f = 0; isSection = true; } } if (isSection && !mark.Contains(ni0 * pointNum + ni1)) { n0.Add(ni0); n1.Add(ni1); frac.Add(f); float xx, yy; switch (xyz) { case 0: xx = points[3 * ni0 + 1] + f * (points[3 * ni1 + 1] - points[3 * ni0 + 1]); yy = points[3 * ni0 + 2] + f * (points[3 * ni1 + 2] - points[3 * ni0 + 2]); v2.Add(new Vector2(xx, yy)); v3.Add(new Vector3(10 * (value - vMin.x) / (Max - Min) - 5 , 5 - 10 * (xx - vMin.y) / (Max - Min), 10 * (yy - vMin.z) / (Max - Min) - 5)); break; case 1: xx = points[3 * ni0] + f * (points[3 * ni1] - points[3 * ni0]); yy = points[3 * ni0 + 2] + f * (points[3 * ni1 + 2] - points[3 * ni0 + 2]); v2.Add(new Vector2(xx, yy)); v3.Add(new Vector3(10 * (xx - vMin.x) / (Max - Min) - 5 , 5 - 10 * (value - vMin.y) / (Max - Min), 10 * (yy - vMin.z) / (Max - Min) - 5)); break; case 2: xx = points[3 * ni0] + f * (points[3 * ni1] - points[3 * ni0]); yy = points[3 * ni0 + 1] + f * (points[3 * ni1 + 1] - points[3 * ni0 + 1]); v2.Add(new Vector2(xx, yy)); v3.Add(new Vector3(10 * (xx - vMin.x) / (Max - Min) - 5 , 5 - 10 * (yy - vMin.y) / (Max - Min), 10 * (value - vMin.z) / (Max - Min) - 5)); break; } mark.Add(ni0 * pointNum + ni1); } } } node0 = n0.ToArray(); node1 = n1.ToArray(); nodeNum = node0.Length; fraction = frac.ToArray(); vertices = v3.ToArray(); // Delaunay 三角剖分 DelaunayTriangulation delaunayTriangulation = null; DelaunayCalculator delaunayCalculator = new DelaunayCalculator(); if (vertices.Length > 0) { delaunayCalculator.CalculateTriangulation(v2, ref delaunayTriangulation); triangles = delaunayTriangulation.Triangles.ToArray(); } }