public bool FaceAlreadyExist(VertexWE a, VertexWE b, VertexWE c) { foreach (FaceWE f in Faces) { foreach (EdgeWE e in f.Edges) { bool Afounded = false; bool Bfounded = false; bool Cfounded = false; if (Equals(a, e.Vertex1) || Equals(a, e.Vertex2)) { Afounded = true; } if (Equals(b, e.Vertex1) || Equals(b, e.Vertex2)) { Bfounded = true; } if (Equals(c, e.Vertex1) || Equals(c, e.Vertex2)) { Cfounded = true; } if (Afounded && Bfounded && Cfounded) { return(true); } } } return(false); }
public Vector3 CalculateCircumscribedCircumference(VertexWE a, VertexWE b, VertexWE c) { float rABa, rABb, rABc, rACa, rACb, rACc, mABx, mABy, mACx, mACy, prAB, prAC; Vector3 v1 = a.Position; Vector3 v2 = b.Position; Vector3 v3 = c.Position; rABa = v2.z - v1.z; rABb = v1.x - v2.x; rABc = rABa * v1.x + rABb * v1.z; rACa = v3.z - v1.z; rACb = v1.x - v3.x; rACc = rABa * v1.x + rABb * v1.z; mABx = (v1.x + v2.x) / 2; mABy = (v1.z + v2.z) / 2; mACx = (v1.x + v3.x) / 2; mACy = (v1.z + v3.z) / 2; //c b x a y prAB = -rABb * mABx + rABa * mABy; prAC = -rACb * mACx + rACa * mACy; float determinant = (-rABb) * rACa - (-rACb) * rABa; float x = (rACa * prAB - rABa * prAC) / determinant; float y = ((-rABb) * prAC - (-rACb) * prAB) / determinant; return(new Vector3(x, 0, y)); }
public List <FaceWE> FlipEdge(EdgeWE e) { List <FaceWE> f = new List <FaceWE>(); FaceWE lf = e.LeftFace; FaceWE rf = e.RightFace; VertexWE v1 = e.Vertex1; VertexWE v2 = e.Vertex2; VertexWE rv = null; VertexWE lv = null; List <VertexWE> rfvertices = GetFaceVertices(rf); List <VertexWE> lfvertices = GetFaceVertices(lf); for (int i = 0; i < rfvertices.Count; i++) { if (!Equals(v1, rfvertices[i]) && !Equals(v2, rfvertices[i])) { rv = rfvertices[i]; } if (!Equals(v1, lfvertices[i]) && !Equals(v2, lfvertices[i])) { lv = lfvertices[i]; } } RemoveFace(rf); RemoveFace(lf); f.Add(AddFace(rv, lv, v1)); f.Add(AddFace(rv, lv, v2)); return(f); }
public bool InsideCC(Vector3 c, double r, VertexWE p) { if (Vector3.Distance(c, p.Position) < r) { return(true); } return(false); }
public VertexWE AddVertex(float x, float y, float z) { VertexWE v = ScriptableObject.CreateInstance("VertexWE") as VertexWE; v.Init(x, y, z); v.id = Vertices.Count; Vertices.Add(v); return(v); }
public EdgeWE EdgeAlreadyExist(VertexWE v1, VertexWE v2) { foreach (EdgeWE e in Edges) { if ((v1 == e.Vertex1 && v2 == e.Vertex2) || (v1 == e.Vertex2 && v2 == e.Vertex1)) { return(e); } } return(null); }
public List <FaceWE> AddVertex(FaceWE f, VertexWE v) { List <VertexWE> vertices = GetFaceVertices(f); List <FaceWE> faces = new List <FaceWE>(); RemoveFace(f); faces.Add(AddFace(vertices[0], v, vertices[1])); faces.Add(AddFace(vertices[1], v, vertices[2])); faces.Add(AddFace(vertices[2], v, vertices[0])); return(faces); }
public bool IsClockwise(VertexWE a, VertexWE b, VertexWE c) { Vector3 AB = b.Position - a.Position; Vector3 AC = c.Position - a.Position; Vector3 crossvalue = Vector3.Cross(AB, AC); if (crossvalue.y > 0.0f) { return(true); } return(false); }
public bool Equals(VertexWE a, VertexWE b) { if (a != null && b != null) { if (a.id == b.id) { if (a.Position == b.Position) { return(true); } } } return(false); }
public int CompareTo(object obj) { if (obj == null) { return(1); } VertexWE otherVertex = obj as VertexWE; if (otherVertex != null) { return(this.Position.z.CompareTo(otherVertex.Position.z)); } else { throw new ArgumentException("Object is not a Temperature"); } }
public void CheckEdge(WingedEdge w) { bool aux = false; foreach (EdgeWE e in w.Edges) { if (e.LeftFace != null && e.RightFace != null) { List <VertexWE> v1 = w.GetFaceVertices(e.RightFace); List <VertexWE> v2 = w.GetFaceVertices(e.LeftFace); VertexWE RightOppositeVertex = null; VertexWE LeftOppositeVertex = null; for (int i = 0; i < v1.Count; i++) { if (!Equals(v1[i], e.Vertex1) && !Equals(v1[i], e.Vertex2)) { RightOppositeVertex = v1[i]; } if (!Equals(v2[i], e.Vertex1) && !Equals(v2[i], e.Vertex2)) { LeftOppositeVertex = v2[i]; } } Vector3 Rightcc = CalculateCircumscribedCircumference(v1[0], v1[1], v1[2]); Vector3 Leftcc = CalculateCircumscribedCircumference(v2[0], v2[1], v2[2]); double RightccRadius = CalculateRadius(Rightcc, v1[0], v1[1], v1[2]); double LeftccRadius = CalculateRadius(Leftcc, v2[0], v2[1], v2[2]); if (InsideCC(Rightcc, RightccRadius, LeftOppositeVertex) || InsideCC(Leftcc, LeftccRadius, RightOppositeVertex)) { List <FaceWE> newfaces = w.FlipEdge(e); aux = true; break; } } } if (aux) { CheckEdge(w); } }
public void Continue() { while (pointlist.Count > 0) { VertexWE v = wingededge.AddVertex(pointlist[0].x, pointlist[0].y, pointlist[0].z); pointlist.RemoveAt(0); FaceWE currentFace = wingededge.PointInTriangle(v); List <FaceWE> newFaces = wingededge.AddVertex(currentFace, v); } CheckEdge(wingededge); List <FaceWE> faceToRemove = new List <FaceWE>(); for (int i = wingededge.Faces.Count - 1; i >= 0; i--) { if (wingededge.IsFaceBorder(wingededge.Faces[i])) { faceToRemove.Add(wingededge.Faces[i]); } } for (int i = 0; i < faceToRemove.Count; i++) { wingededge.RemoveFace(faceToRemove[i]); } List <Vector3> VoronoiVertices = new List <Vector3>(); for (int i = 0; i < wingededge.Faces.Count; i++) { List <VertexWE> vertices = wingededge.GetFaceVertices(wingededge.Faces[i]); wingededge.Faces[i].FaceCircumcenter = CalculateCircumscribedCircumference(vertices[0], vertices[1], vertices[2]); } GrahamScan(); TriangulatorGenerator meshGen = GetComponent <TriangulatorGenerator>(); meshGen.GenerateMesh(wingededge); }
public double CalculateRadius(Vector3 cc, VertexWE A, VertexWE B, VertexWE C) { double maxradius = 0; if (Vector3.Distance(cc, A.Position) > maxradius) { maxradius = Vector3.Distance(cc, A.Position); } if (Vector3.Distance(cc, B.Position) > maxradius) { maxradius = Vector3.Distance(cc, B.Position); } if (Vector3.Distance(cc, C.Position) > maxradius) { maxradius = Vector3.Distance(cc, C.Position); } return(maxradius); }
public FaceWE PointInTriangle(VertexWE p) { foreach (FaceWE f in Faces) { List <VertexWE> vrts = GetFaceVertices(f); double A = TriangleArea(vrts[0], vrts[1], vrts[2]); double A1 = TriangleArea(p, vrts[0], vrts[1]); A1 += TriangleArea(vrts[1], p, vrts[2]); A1 += TriangleArea(vrts[2], vrts[0], p); double In = A1 - A; if (In < 0.01) { return(f); } } return(null); }
public List <VertexWE> GetFaceVertices(FaceWE f) { bool v1founded, v2founded; List <VertexWE> vertices = new List <VertexWE>(); for (int i = 0; i < f.Edges.Count; i++) { v1founded = false; v2founded = false; VertexWE v1 = f.Edges[i].Vertex1; VertexWE v2 = f.Edges[i].Vertex2; if (f.Edges[i].LeftFace == f) { v1 = f.Edges[i].Vertex2; v2 = f.Edges[i].Vertex1; } for (int j = 0; j < vertices.Count; j++) { if (vertices[j].id == v1.id) { v1founded = true; } if (vertices[j].id == v2.id) { v2founded = true; } } if (!v1founded) { vertices.Add(v1); } if (!v2founded) { vertices.Add(v2); } } return(vertices); }
/// <summary> /// Inspecte une edge et détermine si un basculement est nécéssaire /// Si un basculement a eu lieu, réinvoque la fonction /// </summary> /// <param name="e"></param> private void InspectEdge(List <EdgeWE> edges, WingedEdgeMesh mesh) { foreach (EdgeWE e in edges) { // On vérifie d'abord que l'arrête relie 2 triangles if (e.LeftFace != null && e.RightFace != null) { List <VertexWE> v1 = mesh.GetFaceVertices(e.LeftFace); List <VertexWE> v2 = mesh.GetFaceVertices(e.RightFace); // Récupère le coté opposé à la face gauche VertexWE leftOppositeVertex = null; for (int i = 0; i < v1.Count; i++) { if ((v1[i] != e.Vertex1) && (v1[i] != e.Vertex2)) { leftOppositeVertex = v1[i]; } } // Récupère le coté opposé à la face droite VertexWE rightOppositeVertex = null; for (int i = 0; i < v2.Count; i++) { if ((v2[i] != e.Vertex1) && (v2[i] != e.Vertex2)) { rightOppositeVertex = v1[i]; } } // On récupère les informations sur les cercle Right et Left Face Vector3 leftCircleCenter = GetCircleCenter(v1[0].Position, v1[1].Position, v1[2].Position); float leftCircleRadius = GetCircleRadius(v1[0].Position, v1[1].Position, v1[2].Position, leftCircleCenter); Vector3 rightCircleCenter = GetCircleCenter(v2[0].Position, v2[1].Position, v2[2].Position); float rightCircleRadius = GetCircleRadius(v2[0].Position, v2[1].Position, v2[2].Position, rightCircleCenter); // On vérifie si un des coté opposé ne rentre pas dans le cercle de la face opposé if (IsPointInCircle(leftOppositeVertex.Position, rightCircleCenter, rightCircleRadius) || IsPointInCircle(rightOppositeVertex.Position, leftCircleCenter, leftCircleRadius)) { // On bascule l'arrête List <FaceWE> newfaces = mesh.FlipEdge(e); // On inspecte les nouvelles arrêtes List <EdgeWE> newEdges = new List <EdgeWE>(); for (int i = 0; i < newfaces.Count; i++) { for (int j = 0; j < newfaces[i].Edges.Count; j++) { if (newEdges.Contains(newfaces[i].Edges[j])) { newEdges.Add(newfaces[i].Edges[j]); } } } InspectEdge(newEdges, mesh); return; } } } return; }
public float TriangleArea(VertexWE a, VertexWE b, VertexWE c) { return(Mathf.Abs((float)a.Position.x * (b.Position.z - c.Position.z) + b.Position.x * (c.Position.z - a.Position.z) + c.Position.x * (a.Position.z - b.Position.z)) / 2.0f); }
public FaceWE AddFace(VertexWE a, VertexWE b, VertexWE c) { if (!FaceAlreadyExist(a, b, c)) { if (!IsClockwise(a, b, c)) { VertexWE aux = a; a = b; b = aux; } FaceWE f = ScriptableObject.CreateInstance("FaceWE") as FaceWE; EdgeWE e1 = EdgeAlreadyExist(a, b); EdgeWE e2 = EdgeAlreadyExist(b, c); EdgeWE e3 = EdgeAlreadyExist(c, a); if (e1 == null) { EdgeWE aux1 = ScriptableObject.CreateInstance("EdgeWE") as EdgeWE; aux1.Init(a, b); a.Edges.Add(aux1); b.Edges.Add(aux1); Edges.Add(aux1); f.Edges.Add(aux1); aux1.RightFace = f; } else { if (e1.RightFace == null) { e1.RightFace = f; } else { e1.LeftFace = f; } f.Edges.Add(e1); } if (e2 == null) { EdgeWE aux2 = ScriptableObject.CreateInstance("EdgeWE") as EdgeWE; aux2.Init(b, c); b.Edges.Add(aux2); c.Edges.Add(aux2); Edges.Add(aux2); aux2.RightFace = f; f.Edges.Add(aux2); } else { if (e2.RightFace == null) { e2.RightFace = f; } else { e2.LeftFace = f; } f.Edges.Add(e2); } if (e3 == null) { EdgeWE aux3 = ScriptableObject.CreateInstance("EdgeWE") as EdgeWE; aux3.Init(c, a); c.Edges.Add(aux3); a.Edges.Add(aux3); Edges.Add(aux3); aux3.RightFace = f; f.Edges.Add(aux3); } else { if (e3.RightFace == null) { e3.RightFace = f; } else { e3.LeftFace = f; } f.Edges.Add(e3); } Faces.Add(f); return(f); } return(null); }
public void Init(VertexWE v1, VertexWE v2) { Vertex1 = v1; Vertex2 = v2; }
/// <summary> /// Check an edge and determine if it needs to be change? If yes the function call itself again /// </summary> /// <param name="e"></param> private void InspectEdge(List <EdgeWE> edges, WingedEdgeMesh mesh) { foreach (EdgeWE e in edges) { // Wefirstcheck that the edge connect 2 triangles if (e.LeftFace != null && e.RightFace != null) { List <VertexWE> v1 = mesh.GetFaceVertices(e.LeftFace); List <VertexWE> v2 = mesh.GetFaceVertices(e.RightFace); // We get the opposite side of the left face VertexWE leftOppositeVertex = null; for (int i = 0; i < v1.Count; i++) { if ((v1[i] != e.Vertex1) && (v1[i] != e.Vertex2)) { leftOppositeVertex = v1[i]; } } //We get the opposite side of the right face VertexWE rightOppositeVertex = null; for (int i = 0; i < v2.Count; i++) { if ((v2[i] != e.Vertex1) && (v2[i] != e.Vertex2)) { rightOppositeVertex = v1[i]; } } // We get back informations about the circles from the left and right face Vector3 leftCircleCenter = GetCircleCenter(v1[0].Position, v1[1].Position, v1[2].Position); float leftCircleRadius = GetCircleRadius(v1[0].Position, v1[1].Position, v1[2].Position, leftCircleCenter); Vector3 rightCircleCenter = GetCircleCenter(v2[0].Position, v2[1].Position, v2[2].Position); float rightCircleRadius = GetCircleRadius(v2[0].Position, v2[1].Position, v2[2].Position, rightCircleCenter); // We check if one of the opposite side can fit in the circle of the opposite face if (IsPointInCircle(leftOppositeVertex.Position, rightCircleCenter, rightCircleRadius) || IsPointInCircle(rightOppositeVertex.Position, leftCircleCenter, leftCircleRadius)) { // We switchover the edge List <FaceWE> newfaces = mesh.FlipEdge(e); // We inspect the new edges List <EdgeWE> newEdges = new List <EdgeWE>(); for (int i = 0; i < newfaces.Count; i++) { for (int j = 0; j < newfaces[i].Edges.Count; j++) { if (newEdges.Contains(newfaces[i].Edges[j])) { newEdges.Add(newfaces[i].Edges[j]); } } } InspectEdge(newEdges, mesh); return; } } } return; }