public DCELHalfEdge2D(DCELVertex2D origin, DCELFace2D face, DCELHalfEdge2D twin, DCELHalfEdge2D next) { Origin = origin; Face = face; Twin = twin; Next = next; }
/// <summary> /// Verifica se la faccia è convessa. Un poligono semplice è strettamente convesso se ogni /// angolo interno è strettamente inferiore a 180 gradi. /// </summary> /// <returns>True se la faccia è convessa, false altrimenti.</returns> public bool IsConvex() { DCELHalfEdge2D he = this.Edge; DCELHalfEdge2D prev = he.Previous(); DCELVertex2D first = he.Origin; do { Vector v1 = new Vector( prev.Origin.Coordinates.X - he.Origin.Coordinates.X, prev.Origin.Coordinates.Y - he.Origin.Coordinates.Y); Vector v2 = new Vector( he.Next.Origin.Coordinates.X - he.Origin.Coordinates.X, he.Next.Origin.Coordinates.Y - he.Origin.Coordinates.Y); double dotProduct = (v1.X * v2.X + v1.Y * v2.Y); double norm1 = Math.Sqrt(Math.Pow(v1.X, 2) + Math.Pow(v1.Y, 2)); double norm2 = Math.Sqrt(Math.Pow(v2.X, 2) + Math.Pow(v2.Y, 2)); double angle = (Math.Acos(dotProduct / (norm1 * norm2)) * 180) / Math.PI; if (angle > 180) { return(false); } prev = he; he = he.Next; }while (he.Origin != first); //returns true if every internal angle is less than or equal to 180 degrees return(true); }
public bool AddVertex(DCELVertex2D vertex) { vertexList.Add(vertex); vertexCount++; return(true); }
public bool RemoveVertex(DCELVertex2D vertex) { if (vertexList.Remove(vertex)) { vertexCount--; return(true); } return(false); }
/// <summary> /// Restituisce i lati della faccia. /// </summary> /// <returns>DCELHalfEdge collection.</returns> public IEnumerable <DCELHalfEdge2D> Sides() { DCELHalfEdge2D he = this.Edge; DCELVertex2D first = he.Origin; do { yield return(he); he = he.Next; }while (he.Origin != first); }
public static IEnumerable <DCELHalfEdge2D> LeavingEdges(DCELMesh2D mesh, DCELVertex2D vertex, QueryExecutionMode executionMode) { var query = mesh.HalfEdgeList.AsEnumerable(); switch (executionMode) { case QueryExecutionMode.Default: query = query.Where(x => x.Origin == vertex); break; case QueryExecutionMode.AsParallel: query = query.AsParallel().Where(x => x.Origin == vertex); break; case QueryExecutionMode.ForEachLoop: foreach (var leavingEdge in mesh.HalfEdgeList) { if (leavingEdge.Origin == vertex) { yield return(leavingEdge); } } yield break; case QueryExecutionMode.ForLoop: for (int i = 0; i < mesh.HalfEdgeCount; i++) { if (mesh.HalfEdgeList[i].Origin == vertex) { yield return(mesh.HalfEdgeList[i]); } } yield break; case QueryExecutionMode.ForWithAssignment: int n = mesh.HalfEdgeCount; for (int i = 0; i < n; i++) { if (mesh.HalfEdgeList[i].Origin == vertex) { yield return(mesh.HalfEdgeList[i]); } } yield break; } foreach (var leavingEdge in query) { yield return(leavingEdge); } }
public bool TriangulateFace(DCELFace2D face) { //lista di appoggio List <DCELHalfEdge2D> edges = face.Sides().ToList(); //sides è il numero di lati della faccia int sides = edges.Count; //first è il vertice a partire dal quale viene suddiviso il poligono DCELVertex2D first = edges[0].Origin; //se la faccia non esiste o se esiste ma ha meno di 4 lati o non è convessa restituisco false //if (sides <= 3 || !this.Contains(face) || !face.IsConvex()) // return false; for (int i = 0; i < sides; i++) { if (i == 0) { this.AddFace(new DCELFace2D(edges[i])); edges[i].Face = faceList[FaceCount - 1]; i++; edges[i].Face = faceList[FaceCount - 1]; this.AddHalfEdge(new DCELHalfEdge2D(edges[i].Next.Origin, faceList[FaceCount - 1], null, edges[0])); edges[i].Next = edgeList[HalfEdgeCount - 1]; } else if (i == sides - 2) { this.AddFace(new DCELFace2D(null)); this.AddHalfEdge(new DCELHalfEdge2D(first, faceList[FaceCount - 1], edgeList[HalfEdgeCount - 1], edges[i])); edges[i].Face = faceList[FaceCount - 1]; i++; edges[i].Face = faceList[FaceCount - 1]; edgeList[HalfEdgeCount - 2].Twin = edgeList[HalfEdgeCount - 1]; faceList[FaceCount - 1].Edge = edgeList[HalfEdgeCount - 1]; edges[i].Next = edgeList[HalfEdgeCount - 1]; } else { this.AddFace(new DCELFace2D(null)); this.AddHalfEdge(new DCELHalfEdge2D(first, faceList[FaceCount - 1], edgeList[HalfEdgeCount - 1], edges[i])); faceList[FaceCount - 1].Edge = edgeList[HalfEdgeCount - 1]; edges[i].Face = faceList[FaceCount - 1]; edgeList[HalfEdgeCount - 2].Twin = edgeList[HalfEdgeCount - 1]; this.AddHalfEdge(new DCELHalfEdge2D(edges[i].Next.Origin, faceList[faceCount - 1], null, edgeList[HalfEdgeCount - 1])); edges[i].Next = edgeList[HalfEdgeCount - 1]; } } //ora è possibile rimuovere la faccia dalla lista return(RemoveFace(face)); }
/// <summary> /// Restituisce tutte le facce confinanti. /// </summary> /// <returns>DCELFace collection.</returns> public IEnumerable <DCELFace2D> Neighbours() { DCELHalfEdge2D he = this.Edge; DCELVertex2D first = he.Origin; do { if (he.Twin != null) { if (!he.Twin.Face.IsInfinite()) { yield return(he.Twin.Face); } } he = he.Next; }while (he.Origin != first); }
public bool Contains(DCELVertex2D vertex) { return(vertexList.Contains(vertex)); }