public void CloseMesh(List <Line> lines, Edge <T> firstCutEdge) { MeshCell <T> cell = firstCutEdge.Cell; //Divide this cell //================================================================ //NewVertices Vertex[] verticesOfNewRidgeBoundary = new Vertex[lines.Count + 2]; verticesOfNewRidgeBoundary[0] = firstCutEdge.End; verticesOfNewRidgeBoundary[verticesOfNewRidgeBoundary.Length - 1] = Vertices[cell.IntersectionVertex]; verticesOfNewRidgeBoundary[verticesOfNewRidgeBoundary.Length - 2] = lines[0].start; int ID = AddVertex(lines[0].start); //Add Vertices of lines for (int i = 2; i < verticesOfNewRidgeBoundary.Length - 1; ++i) { verticesOfNewRidgeBoundary[verticesOfNewRidgeBoundary.Length - 1 - i] = lines[i - 1].end; ID = AddVertex(verticesOfNewRidgeBoundary[verticesOfNewRidgeBoundary.Length - 1 - i]); } //New Ridges Edge <T>[] newRidges; Edge <T>[] newNeighborRidges; MeshCell <T> newCell = new MeshCell <T>(); AddCell(newCell); CreateEdge(verticesOfNewRidgeBoundary, cell, newCell, out newRidges, out newNeighborRidges); InsertEdgesAndVertices(newRidges, newNeighborRidges); }
static void MoveNodesTowardsCellCenter <T>(IReadOnlyList <MeshCell <T> > Cells, ref int FirstCellNode_indice) where T : IMesherNode, new() { //Mark inside nodes //Use Original Nodes List and update. Use LinkedList?! Only iterate and cut some nodes, or insert //Let's give it a try! for (int i = 0; i < Cells.Count; ++i) { MeshCell <T> cell = Cells[i]; double relaxValue = 0.1; Vector CenterOfGravity = new Vector(0, 0); foreach (Vertex vertex in cell.Vertices) { CenterOfGravity += vertex.Position; } CenterOfGravity.Scale(1.0 / cell.Vertices.Length); CenterOfGravity = CenterOfGravity * relaxValue + new Vector(cell.Node.Position) * (1 - relaxValue); cell.Node.Position = CenterOfGravity; if (cell.ID == FirstCellNode_indice) { FirstCellNode_indice = i; } } }
public (MeshCell <T>, IEnumerator <Edge <T> >) getNeighborFromEdgeNeighbor(Edge <T> edge) { MeshCell <T> newCell = getNeighbour(edge); AfterCutRidgeEnumerator ridgeEnum = new AfterCutRidgeEnumerator(newCell.Edges, edge); return(newCell, ridgeEnum); }
public void CreateEdge(Vertex[] vertices, MeshCell <T> cell, MeshCell <T> neighborCell, out Edge <T>[] ridges, out Edge <T>[] twinEdges) { int count = vertices.Length - 1; ridges = new Edge <T> [count]; twinEdges = new Edge <T> [count]; for (int i = 0; i < count; ++i) { Edge <T> ridge = new Edge <T> { Start = vertices[i], End = vertices[i + 1], Cell = cell }; Edge <T> twinRidge = new Edge <T> { Start = vertices[i + 1], End = vertices[i], Twin = ridge, Cell = neighborCell, IsBoundary = true }; ridge.Twin = twinRidge; ridges[i] = ridge; twinEdges[count - 1 - i] = twinRidge; } }
public void VertexCut(Edge <T> edge, double alphaCut) { MeshCell <T> cell = edge.Cell; Vertex newOldVertex = edge.End; cell.IntersectionVertex = newOldVertex.ID; cell = edge.Twin.Cell; cell.IntersectionVertex = newOldVertex.ID; }
public static MeshCell <T>[] Clone <T>(IList <MeshCell <T> > cells) where T : ILocatable, new() { MeshCell <T>[] clones = new MeshCell <T> [cells.Count]; for (int i = 0; i < cells.Count; ++i) { clones[i] = Clone(cells[i]); } return(clones); }
static Vector VertexMean <T>(MeshCell <T> cell) { Vector centerOfGravity = new Vector(0, 0); foreach (Vertex vertex in cell.Vertices) { centerOfGravity += vertex.Position; } centerOfGravity.Scale(1.0 / cell.Vertices.Length); return(centerOfGravity); }
protected List <MeshCell <T> > SetCellTypesOnSameSideOfBoundary(MeshCell <T> startingCell, MeshCellType type, ref List <MeshCell <T> > cells) { List <MeshCell <T> > sameSideCells = new List <MeshCell <T> >(); foreach (MeshCell <T> cell in CellsOnSameSideOfBoundary_Iterative(startingCell)) { cell.type = type; sameSideCells.Add(cell); } return(sameSideCells); }
static void MoveNodesTowardsCellCenter <T>(IReadOnlyList <MeshCell <T> > cells) where T : ILocatable { for (int i = 0; i < cells.Count; ++i) { MeshCell <T> cell = cells[i]; Vector centerOfGravity = CenterOf(cell); double relaxValue = 0.3; centerOfGravity = centerOfGravity * relaxValue + new Vector(cell.Node.Position) * (1 - relaxValue); cell.Node.Position = centerOfGravity; } }
public static MeshCell <T> Clone <T>(MeshCell <T> cell) where T : ILocatable, new() { MeshCell <T> clone = new MeshCell <T>() { Node = Clone(cell.Node), Type = cell.Type, ID = cell.ID, Vertices = Clone((IList <Vertex>)cell.Vertices), Edges = Clone <T>(cell.Edges) }; FuseEdgeVertices(clone.Edges, clone.Vertices); return(clone); }
/// <summary> /// Enumerates the cells inside the boundary of this mesh. /// Recursion produces Stack overflow, when to many cells in mesh. /// </summary> /// <param name="cell"> /// Enumeration starts with this cell and then return its neighbors and so on. /// </param> /// <returns></returns> static IEnumerable <MeshCell <T> > RecursiveYieldConnectedCells(MeshCell <T> cell, HashSet <int> visited) { visited.Add(cell.ID); yield return(cell); foreach (Edge <T> edge in cell.Edges) { Edge <T> newRidge = edge.Twin; if (!visited.Contains(newRidge.Cell.ID) && !newRidge.IsBoundary) { foreach (MeshCell <T> neighbor in RecursiveYieldConnectedCells(newRidge.Cell, visited)) { yield return(neighbor); } } } }
static Vector CenterOf <T>(MeshCell <T> cell) { Vector centerOfGravity = new Vector(0, 0); Vector root = cell.Vertices[0].Position; double cellArea = 0; for (int i = 1; i < cell.Vertices.Length - 1; ++i) { Vector a = cell.Vertices[i].Position; Vector b = cell.Vertices[i + 1].Position; double area = AreaOfTriangle(root, a, b); centerOfGravity += (root + a + b) / 3 * area; cellArea += area; } centerOfGravity.Scale(1.0 / cellArea); return(centerOfGravity); }
private IEnumerable <MeshCell <T> > YieldConnectedCells(MeshCell <T> cell, BitArray visited) { visited[cell.ID] = true; yield return(cell); foreach (Edge <T> edge in cell.Edges) { Edge <T> newRidge = edge.Twin; if (!visited[newRidge.Cell.ID] && !newRidge.IsBoundary) { foreach (MeshCell <T> neighbor in YieldConnectedCells(newRidge.Cell, visited)) { yield return(neighbor); } } } }
public Edge <T> SubdivideWithoutNewVertex(Edge <T> edge, List <Line> lines) { MeshCell <T> cell = edge.Cell; Vertex cutVertex = edge.End; IEnumerator <Edge <T> > neighEdges = getConnectedRidgeEnum(edge); while (neighEdges.MoveNext()) { MeshCell <T> neighbor = neighEdges.Current.Cell; if (neighbor.ID != cell.ID) { neighbor.IntersectionVertex = cutVertex.ID; } } //Divide this cell //================================================================ Vertex[] verticesOfNewEdgeBoundary = new Vertex[lines.Count + 2]; verticesOfNewEdgeBoundary[0] = cutVertex; verticesOfNewEdgeBoundary[verticesOfNewEdgeBoundary.Length - 1] = Vertices[cell.IntersectionVertex]; //Add Vertices of lines for (int i = 1; i < verticesOfNewEdgeBoundary.Length - 1; ++i) { verticesOfNewEdgeBoundary[verticesOfNewEdgeBoundary.Length - 1 - i] = lines[i - 1].end; AddVertex(verticesOfNewEdgeBoundary[verticesOfNewEdgeBoundary.Length - 1 - i]); } //New Ridges Edge <T>[] newEdges; Edge <T>[] newNeighborEdges; MeshCell <T> newCell = new MeshCell <T>(); AddCell(newCell); CreateEdge(verticesOfNewEdgeBoundary, cell, newCell, out newEdges, out newNeighborEdges); //Link Ridges to old neighbors InsertEdgesAndVertices(newEdges, newNeighborEdges); //dOnE, DoNe! return(edge); }
/// <summary> /// Enumerates the cells inside the boundary of this mesh. /// </summary> /// <param name="cell"> /// Enumeration starts with this cell and then return its neighbors and so on. /// </param> /// <returns></returns> static IEnumerable <MeshCell <T> > IterativeYieldConnectedCells(MeshCell <T> cell, HashSet <int> visited) { Queue <MeshCell <T> > cells = new Queue <MeshCell <T> >(); cells.Enqueue(cell); visited.Add(cell.ID); while (cells.Count > 0) { MeshCell <T> current = cells.Dequeue(); yield return(current); foreach (Edge <T> edge in current.Edges) { Edge <T> newEdge = edge.Twin; if (newEdge != null && !newEdge.IsBoundary && !visited.Contains(newEdge.Cell.ID)) { cells.Enqueue(newEdge.Cell); visited.Add(newEdge.Cell.ID); } } } }
public Edge <T> Subdivide(Edge <T> edge, List <Line> lines, double alpha) { MeshCell <T> cell = edge.Cell; //Divide Ridge and update Ridge Arrays //------------------------------------- Vertex newVertex = DivideEdge(edge, alpha, out Edge <T> newRidge); edge.Twin.Cell.IntersectionVertex = newVertex.ID; //cell.IntersectionVertex = newVertex.ID; //Divide this cell //================================================================ //NewVertices Vertex[] verticesOfNewRidgeBoundary = new Vertex[lines.Count + 2]; verticesOfNewRidgeBoundary[0] = newVertex; verticesOfNewRidgeBoundary[verticesOfNewRidgeBoundary.Length - 1] = Vertices[cell.IntersectionVertex]; //Add Vertices of lines for (int i = 1; i < verticesOfNewRidgeBoundary.Length - 1; ++i) { verticesOfNewRidgeBoundary[verticesOfNewRidgeBoundary.Length - 1 - i] = lines[i - 1].end; int ID = AddVertex(verticesOfNewRidgeBoundary[verticesOfNewRidgeBoundary.Length - 1 - i]); } //New Ridges Edge <T>[] newEdges; Edge <T>[] newNeighborEdges; MeshCell <T> newCell = new MeshCell <T> { Node = new T() }; newCell.Node.Position = cell.Node.Position; AddCell(newCell); CreateEdge(verticesOfNewRidgeBoundary, cell, newCell, out newEdges, out newNeighborEdges); //Link Ridges to old neighbors InsertEdgesAndVertices(newEdges, newNeighborEdges); //dOnE, DoNe! return(edge); }
public void InsertEdgesAndVertices(params Edge <T>[] additionalEdges) { MeshCell <T> cell = additionalEdges[0].Cell; int countAdditionalRidges = additionalEdges.Length; Edge <T>[] newRidges = new Edge <T> [cell.Edges.Length + countAdditionalRidges]; bool notInsertedYet = true; for (int i = 0; i < cell.Edges.Length; ++i) { if (notInsertedYet) { newRidges[i] = cell.Edges[i]; } else { newRidges[i + countAdditionalRidges] = cell.Edges[i]; } if (notInsertedYet && (additionalEdges[0].Start.ID == cell.Edges[i].End.ID)) { for (int k = 0; k < countAdditionalRidges; ++k) { newRidges[i + k + 1] = additionalEdges[k]; } notInsertedYet = false; } } cell.Edges = newRidges; Vertex[] newVertices = new Vertex[cell.Vertices.Length + countAdditionalRidges]; for (int i = 0; i < cell.Edges.Length; ++i) { newVertices[i] = newRidges[i].Start; } cell.Vertices = newVertices; }
/// <summary> /// Enumerates the cells inside the boundary of this mesh. /// </summary> /// <param name="cell"> /// Enumeration starts with this cell and then return its neighbors and so on. /// </param> /// <returns></returns> public IEnumerable <MeshCell <T> > CellsOnSameSideOfBoundary_Iterative(MeshCell <T> cell) { BitArray visited = new BitArray(Cells.Count); LinkedList <MeshCell <T> > cells = new LinkedList <MeshCell <T> >(); cells.AddFirst(cell); visited[cell.ID] = true; while (cells.Count > 0) { MeshCell <T> current = cells.First.Value; yield return(current); cells.RemoveFirst(); foreach (Edge <T> edge in current.Edges) { Edge <T> newEdge = edge.Twin; if (!visited[newEdge.Cell.ID] && !newEdge.IsBoundary) { cells.AddLast(newEdge.Cell); visited[newEdge.Cell.ID] = true; } } } }
protected int AddCell(MeshCell <T> cell) { return(mesh.AddCell(cell)); }
/// <summary> /// Enumerates the cells inside the boundary of this mesh. /// Recursion produces Stack overflow, when to many cells in mesh. /// </summary> /// <param name="cell"> /// Enumeration starts with this cell and then return its neighbors and so on. /// </param> /// <returns></returns> public IEnumerable <MeshCell <T> > CellsOnSameSideOfBoundary_Recursive(MeshCell <T> cell) { BitArray visited = new BitArray(Cells.Count); return(YieldConnectedCells(cell, visited)); }
public int AddCell(MeshCell <T> cell) { cell.ID = Cells.Count; Cells.Add(cell); return(cell.ID); }
public void InsertEdgesAndVertices(Edge <T>[] newEdge, Edge <T>[] newNeighborEdges) { MeshCell <T> cell = newEdge[0].Cell; MeshCell <T> emptyNeighCell = newNeighborEdges[0].Cell; Edge <T>[] oldRidges = cell.Edges; List <Edge <T> > cellRidges = null; List <Edge <T> > emptyNeighCellRidges = null; List <Edge <T> > workerA = new List <Edge <T> >(newEdge.Length); List <Edge <T> > workerB = new List <Edge <T> >(newEdge.Length); bool workerAIsActive = true; List <Edge <T> > tmp = workerA; //Add new Ridges for (int i = 0; i < oldRidges.Length; ++i) { Edge <T> activeR = oldRidges[i]; if (activeR.Start.ID == newEdge[0].Start.ID) { cellRidges = tmp; for (int j = 0; j < newEdge.Length; ++j) { cellRidges.Add(newEdge[j]); } tmp = workerAIsActive ? workerB : workerA; workerAIsActive = !workerAIsActive; } if (activeR.Start.ID == newNeighborEdges[0].Start.ID) { emptyNeighCellRidges = tmp; for (int j = 0; j < newNeighborEdges.Length; ++j) { emptyNeighCellRidges.Add(newNeighborEdges[j]); } tmp = workerAIsActive ? workerB : workerA; workerAIsActive = !workerAIsActive; } tmp.Add(activeR); } cell.Edges = cellRidges.ToArray(); emptyNeighCell.Edges = emptyNeighCellRidges.ToArray(); //Update AllRidges for (int i = 0; i < cell.Edges.Length; ++i) { cell.Edges[i].Cell = cell; } for (int i = 0; i < emptyNeighCell.Edges.Length; ++i) { emptyNeighCell.Edges[i].Cell = emptyNeighCell; } //Vertices Vertex[] newVertices = new Vertex[cell.Edges.Length]; for (int i = 0; i < cell.Edges.Length; ++i) { newVertices[i] = cell.Edges[i].Start; } cell.Vertices = newVertices; Vertex[] newNeighVertices = new Vertex[emptyNeighCell.Edges.Length]; for (int i = 0; i < emptyNeighCell.Edges.Length; ++i) { newNeighVertices[i] = emptyNeighCell.Edges[i].Start; } emptyNeighCell.Vertices = newNeighVertices; }
public static IEnumerable <MeshCell <T> > GetInsideCells(MeshCell <T> cell) { HashSet <int> visited = new HashSet <int>(); return(IterativeYieldConnectedCells(cell, visited)); }
Domain <T> CreateMeshFrom(IList <T> nodes, MeshCell <T> firstCorner) { return(CreateMeshFrom(nodes, firstCorner.ID)); }
public Domain <T> Generate(IList <T> nodes, MeshCell <T> firstCorner) { return(Generate(nodes, firstCorner.ID)); }