public HalfEdge(Vertex a_Vertex) { // Using new here prevents reference equality. Is it really necessary to copy? m_Origin = new Vertex(a_Vertex.X, a_Vertex.Y, a_Vertex.Ownership); Triangle = null; Twin = null; Next = null; Prev = null; }
public virtual bool AddVertex(Vertex a_Vertex) { Triangle triangle = FindTriangle(a_Vertex); if (triangle == null) { return false; } AddVertex(triangle, a_Vertex); return true; }
protected void AddVertex(Triangle a_Triangle, Vertex a_Vertex) { m_Vertices.Add(a_Vertex); m_Triangles.Remove(a_Triangle); HalfEdge h1 = a_Triangle.HalfEdge; HalfEdge h2 = h1.Next; HalfEdge h3 = h2.Next; HalfEdge h4 = new HalfEdge(h1.Origin); HalfEdge h5 = new HalfEdge(h2.Origin); HalfEdge h6 = new HalfEdge(h3.Origin); HalfEdge h7 = new HalfEdge(a_Vertex); HalfEdge h8 = new HalfEdge(a_Vertex); HalfEdge h9 = new HalfEdge(a_Vertex); m_HalfEdges.AddRange(new List<HalfEdge>() { h4, h5, h6, h7, h8, h9 }); h4.Twin = h7; h7.Twin = h4; h5.Twin = h8; h8.Twin = h5; h6.Twin = h9; h9.Twin = h6; // Set all next h1.Next = h5; h5.Prev = h1; h5.Next = h7; h7.Prev = h5; h7.Next = h1; h1.Prev = h7; h2.Next = h6; h6.Prev = h2; h6.Next = h8; h8.Prev = h6; h8.Next = h2; h2.Prev = h8; h3.Next = h4; h4.Prev = h3; h4.Next = h9; h9.Prev = h4; h9.Next = h3; h3.Prev = h9; m_Triangles.Add(new Triangle(h1)); m_Triangles.Add(new Triangle(h2)); m_Triangles.Add(new Triangle(h3)); }
public override bool AddVertex(Vertex a_Vertex) { Triangle triangle = FindTriangle(a_Vertex); if (triangle == null) { return false; } AddVertex(triangle, a_Vertex); // Find halfedges of triangle HalfEdge h1 = triangle.HalfEdge; HalfEdge h2 = triangle.HalfEdge.Next.Twin.Next; HalfEdge h3 = triangle.HalfEdge.Next.Twin.Next.Next.Twin.Next; // Flip if needed LegalizeEdge(a_Vertex, h1, h1.Triangle); LegalizeEdge(a_Vertex, h2, h2.Triangle); LegalizeEdge(a_Vertex, h3, h3.Triangle); return true; }
private void LegalizeEdge(Vertex a_Vertex, HalfEdge a_HalfEdge, Triangle a_Triangle) { if (a_Vertex == null || a_HalfEdge == null || a_Triangle == null) { Debug.LogError("Invalid call to LegalizeEdge"); return; } Vertex v1, v2, v3; try { // Points to test v1 = a_HalfEdge.Twin.Next.Next.Origin; v2 = a_HalfEdge.Next.Twin.Next.Next.Origin; v3 = a_HalfEdge.Next.Next.Twin.Next.Next.Origin; } catch (NullReferenceException) { Debug.LogError("Null pointers in call to LegalizeEdge"); return; } if (v1 == null || v2 == null || v3 == null) { Debug.LogError("Invalid halfedge in call to LegalizeEdge"); return; } if (a_Triangle.InsideCircumcenter(v1) || a_Triangle.InsideCircumcenter(v2) || a_Triangle.InsideCircumcenter(v3)) { HalfEdge h1 = a_HalfEdge.Twin.Next.Twin; HalfEdge h2 = a_HalfEdge.Twin.Prev.Twin; Flip(a_HalfEdge); LegalizeEdge(a_Vertex, h1.Twin, h1.Twin.Triangle); LegalizeEdge(a_Vertex, h2.Twin, h2.Twin.Triangle); } }
public void Create() { Vertex v1 = new Vertex(-500000, -500000); Vertex v2 = new Vertex(500000, 500000); Vertex v3 = new Vertex(-500000, 500000); Vertex v4 = new Vertex(500000, -500000); m_Vertices.AddRange(new List<Vertex>() { v1, v2, v3, v4 }); HalfEdge h1 = new HalfEdge(v1); HalfEdge h2 = new HalfEdge(v2); HalfEdge h3 = new HalfEdge(v3); m_HalfEdges.AddRange(new List<HalfEdge>() { h1, h2, h3 }); h1.Next = h2; h2.Next = h3; h3.Next = h1; h2.Prev = h1; h3.Prev = h2; h1.Prev = h3; HalfEdge h4 = new HalfEdge(v2); HalfEdge h5 = new HalfEdge(v1); HalfEdge h6 = new HalfEdge(v4); m_HalfEdges.AddRange(new List<HalfEdge>() { h4, h5, h6 }); h4.Twin = h1; h1.Twin = h4; h4.Next = h5; h5.Next = h6; h6.Next = h4; h5.Prev = h4; h6.Prev = h5; h4.Prev = h6; HalfEdge h7 = new HalfEdge(v1); HalfEdge h8 = new HalfEdge(v2); HalfEdge h9 = new HalfEdge(v3); HalfEdge h10 = new HalfEdge(v4); m_HalfEdges.AddRange(new List<HalfEdge>() { h7, h8, h9, h10 }); h10.Next = h7; h7.Prev = h10; h8.Next = h10; h10.Prev = h8; h9.Next = h8; h8.Prev = h9; h7.Next = h9; h9.Prev = h7; h3.Twin = h7; h7.Twin = h3; h8.Twin = h6; h6.Twin = h8; h2.Twin = h9; h9.Twin = h2; h10.Twin = h5; h5.Twin = h10; m_Triangles.Add(new Triangle(h1)); m_Triangles.Add(new Triangle(h4)); }
protected Triangle FindTriangle(Vertex a_Vertex) { foreach (Triangle triangle in m_Triangles) { if (triangle.Inside(a_Vertex)) { return triangle; } } return null; }
public static float SquaredDistance(Vertex v1, Vertex v2) { return Mathf.Pow (v1.X - v2.X, 2) + Mathf.Pow (v1.Y - v2.Y, 2); }
public static float Slope(Vertex v1, Vertex v2) { float value = (v2.Y - v1.Y) / (v2.X - v1.X); return value; }
public static Vertex Midpoint(Vertex v1, Vertex v2) { float mx = (v1.X + v2.X) / 2; float my = (v1.Y + v2.Y) / 2; return new Vertex(mx, my); }
public static float Distance(Vertex v1, Vertex v2) { return Mathf.Sqrt(SquaredDistance(v1, v2)); }
private Vertex CalculateCircumcenterT(Vertex a_VertexA, Vertex a_VertexB, Vertex a_VertexC) { // determine midpoints (average of x & y coordinates) Vertex midAB = Utility.Midpoint(a_VertexA, a_VertexB); Vertex midBC = Utility.Midpoint(a_VertexB, a_VertexC); // determine slope // we need the negative reciprocal of the slope to get the slope of the perpendicular bisector float slopeAB = -1 / Utility.Slope(a_VertexA, a_VertexB); float slopeBC = -1 / Utility.Slope(a_VertexB, a_VertexC); // y = mx + b // solve for b float bAB = midAB.Y - slopeAB * midAB.X; float bBC = midBC.Y - slopeBC * midBC.X; // solve for x & y // x = (b1 - b2) / (m2 - m1) float x = (bAB - bBC) / (slopeBC - slopeAB); return new Vertex (x, (slopeAB * x) + bAB); }
public bool InsideCircumcenter(Vertex a_Vertex) { return (Circumcenter.DeltaSquaredXY (a_Vertex) < CircumcenterRangeSquared); }
public bool Inside(Vertex a_Vertex) { int i, j = m_Vertices.Length - 1; bool oddNodes = false; for (i = 0; i < m_Vertices.Length; i++) { if ((m_Vertices[i].Y < a_Vertex.Y && m_Vertices[j].Y >= a_Vertex.Y || m_Vertices[j].Y < a_Vertex.Y && m_Vertices[i].Y >= a_Vertex.Y) && (m_Vertices[i].X <= a_Vertex.X || m_Vertices[j].X <= a_Vertex.X)) { oddNodes ^= (m_Vertices[i].X + (a_Vertex.Y - m_Vertices[i].Y) / (m_Vertices[j].Y - m_Vertices[i].Y) * (m_Vertices[j].X - m_Vertices[i].X) ) < a_Vertex.X; } j = i; } return oddNodes; }
public float DeltaSquaredXY(Vertex t) { float dx = (X - t.X); float dy = (Y - t.Y); return (dx * dx) + (dy * dy); }