/// <summary> /// Remove edge set (decreasing reference counts). /// </summary> public void RemoveEdgeSet(EdgeSet edgeSet) { foreach (var edge in edgeSet.Edges) { RemoveEdge(edge); } }
//逐点插入法2 public Edge[] PointByPointInsertion() { EdgeSet sEdgeSet = new EdgeSet(); TriangleSet sTriangleSet = new TriangleSet(); MinBoundRect sMBR = this.mPointSet.MBR; double width = sMBR.MaxX - sMBR.MinX; double height = sMBR.MaxY - sMBR.MinY; double middlePointX = (sMBR.MaxX + sMBR.MinX) / 2; double middlePointY = sMBR.MinY; DataPoint P0 = new DataPoint(-1, "P0", middlePointX - width, middlePointY, 0); DataPoint P1 = new DataPoint(-2, "P1", middlePointX + width, middlePointY, 0); DataPoint P2 = new DataPoint(-3, "P2", middlePointX, middlePointY + 2 * height, 0); Triangle T0 = new Triangle(P0, P1, P2, -1); sTriangleSet.AddTriangle(T0); sEdgeSet.AddEdge(new Edge(P0, P1)); sEdgeSet.AddEdge(new Edge(P1, P2)); sEdgeSet.AddEdge(new Edge(P1, P0)); foreach (var point in mPointSet.PointList) { Triangle CurTri = sTriangleSet.GetPointInsidesTri(point); if (CurTri != null) { } } return(sEdgeSet.EdgeList.ToArray()); }
private void 逐点插入法ToolStripMenuItem_Click(object sender, EventArgs e) { //交互-格网与TIN if (逐点插入法ToolStripMenuItem.Checked == true) { //修改显示 this.UserOperation = UserOperationType.DisplayInTIN; this.ShowTin = true; this.显示隐藏TINToolStripMenuItem.Checked = true; CreateTIN createTin = new CreateTIN(this.mPointSet); Edge[] tinEdges = createTin.PointByPointInsertion2(); Edge[] tinEdges2 = createTin.GeneTIN().ToArray(); TinEdges = tinEdges; TriangleSet triSet = EdgeSet.TopologyGenerateTriangleSet(tinEdges, mPointSet); Triangle[] triList = triSet.TriangleList.ToArray(); TinContourLinePen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash; agisControl.Refresh(); } else { //修改显示 this.UserOperation = UserOperationType.None; this.ShowTin = false; this.显示隐藏TINToolStripMenuItem.Checked = false; } }
private static PolySet Inset(ICollection <Polygon> polygons, IList <Vector3> vertices, PolySet polys, float insetDistance) { PolySet stitchedPolys = StitchPolys(polygons, vertices, polys, out EdgeSet stitchedEdge); Dictionary <int, Vector3> inwardDirections = EdgeSet.GetInwardDirections(stitchedEdge, vertices); // Push each vertex inwards, then correct // it's height so that it's as far from the center of // the planet as it was before. foreach (KeyValuePair <int, Vector3> kvp in inwardDirections) { int vertIndex = kvp.Key; Vector3 inwardDirection = kvp.Value; Vector3 vertex = vertices[vertIndex]; float originalHeight = vertex.magnitude; vertex += inwardDirection * insetDistance; vertex = vertex.normalized * originalHeight; vertices[vertIndex] = vertex; } return(stitchedPolys); }
protected override int ExecuteTest() { if (NodeStates.FixedTargetNodeCount <= 1 || NodeStates.VariableTargetNodeCount > 0) { return(0); } var removedNodes = 0; var mst = new MinimalSpanningTree(NodeStates.FixedTargetNodeIndices.ToList(), DistanceLookup); mst.Span(StartNodeIndex); var maxEdgeDistance = mst.SpanningEdges.Max(e => e.Priority); for (var i = 0; i < SearchSpaceSize; i++) { if (NodeStates.IsTarget(i) || NodeStates.IsRemoved(i)) { continue; } // Theoretically, this can be sped up by using Voronoi partitions. The Voronoi base of i is the // terminal with the smallest distance to i by definition, so only the distance to that terminal // has to be checked. if (NodeStates.FixedTargetNodeIndices.All(t => DistanceLookup[i, t] >= maxEdgeDistance)) { EdgeSet.EdgesOf(i).ForEach(EdgeSet.Remove); NodeStates.MarkNodeAsRemoved(i); removedNodes++; } } return(removedNodes); }
public override bool AddEdge(T v1, T v2, K weight) { if (v1 is null) { throw new ArgumentNullException(nameof(v1)); } if (v2 is null) { throw new ArgumentNullException(nameof(v2)); } if (weight is null) { throw new ArgumentNullException(nameof(weight)); } if (!VertexSet.Contains(v1) || !VertexSet.Contains(v2)) { return(false); } IPairValue <T> pair = new PairValueI <T>(v1, v2); if (EdgeSet.Contains(pair)) { return(false); } EdgeSet.Add(pair); Weights[pair] = weight; return(true); }
public HitObject[] GenerateHitObjects(EventProxy events, Table.Table table) { var hitObjects = new List <HitObject>(); var addedEdges = new EdgeSet(); var mesh = _meshGenerator.GetMesh(table, 6, true); //!! adapt hacky code in the function if changing the "6" here // add collision triangles and edges for (var i = 0; i < mesh.Indices.Length; i += 3) { var rgv3D = new Vertex3D[3]; // NB: HitTriangle wants CCW vertices, but for rendering we have them in CW order var v = mesh.Vertices[mesh.Indices[i]]; rgv3D[0] = new Vertex3D(v.X, v.Y, v.Z); v = mesh.Vertices[mesh.Indices[i + 2]]; rgv3D[1] = new Vertex3D(v.X, v.Y, v.Z); v = mesh.Vertices[mesh.Indices[i + 1]]; rgv3D[2] = new Vertex3D(v.X, v.Y, v.Z); hitObjects.Add(new HitTriangle(rgv3D, ItemType.Rubber)); hitObjects.AddRange(GenerateHitEdge(mesh, addedEdges, mesh.Indices[i], mesh.Indices[i + 2])); hitObjects.AddRange(GenerateHitEdge(mesh, addedEdges, mesh.Indices[i + 2], mesh.Indices[i + 1])); hitObjects.AddRange(GenerateHitEdge(mesh, addedEdges, mesh.Indices[i + 1], mesh.Indices[i])); } // add collision vertices foreach (var mv in mesh.Vertices) { var v = new Vertex3D(mv.X, mv.Y, mv.Z); hitObjects.Add(new HitPoint(v, ItemType.Rubber)); } return(hitObjects.Select(obj => SetupHitObject(obj, events, table)).ToArray()); }
private static IEnumerable <HitObject> GenerateHitEdge(Mesh mesh, EdgeSet addedEdges, int i, int j) { var v1 = new Vertex3D(mesh.Vertices[i].X, mesh.Vertices[i].Y, mesh.Vertices[i].Z); var v2 = new Vertex3D(mesh.Vertices[j].X, mesh.Vertices[j].Y, mesh.Vertices[j].Z); return(addedEdges.AddHitEdge(i, j, v1, v2, ItemType.Rubber)); }
private HitObject[] GenerateDropTargetHits(Table.Table table, IItem item) { var addedEdges = new EdgeSet(); var hitMesh = _meshGenerator.GetRenderObjects(table, Origin.Original, false).RenderObjects[0].Mesh; return(GenerateCollidables(hitMesh, addedEdges, true, table, item)); }
public override bool DeleteEdge(T v1, T v2) { if (v1 is null) { throw new ArgumentNullException(nameof(v1)); } if (v2 is null) { throw new ArgumentNullException(nameof(v2)); } IPairValue <T> pair_1 = new PairValueI <T>(v1, v2); IPairValue <T> pair_2 = new PairValueI <T>(v2, v1); if (EdgeSet.Contains(pair_1) || EdgeSet.Contains(pair_2)) { EdgeSet.Remove(pair_1); Weights.Remove(pair_1); EdgeSet.Remove(pair_2); Weights.Remove(pair_2); return(true); } return(false); }
private HitObject[] GenerateCollidables(Mesh hitMesh, EdgeSet addedEdges, bool setHitObject, Table.Table table, IItem item) { var hitObjects = new List <HitObject>(); // add the normal drop target as collidable but without hit event for (var i = 0; i < hitMesh.Indices.Length; i += 3) { var i0 = hitMesh.Indices[i]; var i1 = hitMesh.Indices[i + 1]; var i2 = hitMesh.Indices[i + 2]; // NB: HitTriangle wants CCW vertices, but for rendering we have them in CW order var rgv3D = new [] { new Vertex3D(hitMesh.Vertices[i0].X, hitMesh.Vertices[i0].Y, hitMesh.Vertices[i0].Z), new Vertex3D(hitMesh.Vertices[i2].X, hitMesh.Vertices[i2].Y, hitMesh.Vertices[i2].Z), new Vertex3D(hitMesh.Vertices[i1].X, hitMesh.Vertices[i1].Y, hitMesh.Vertices[i1].Z) }; hitObjects.Add(SetupHitObject(new HitTriangle(rgv3D, ItemType.HitTarget, item), setHitObject, table)); hitObjects.AddRange(addedEdges.AddHitEdge(i0, i1, rgv3D[0], rgv3D[2], ItemType.HitTarget, item).Select(obj => SetupHitObject(obj, setHitObject, table))); hitObjects.AddRange(addedEdges.AddHitEdge(i1, i2, rgv3D[2], rgv3D[1], ItemType.HitTarget, item).Select(obj => SetupHitObject(obj, setHitObject, table))); hitObjects.AddRange(addedEdges.AddHitEdge(i2, i0, rgv3D[1], rgv3D[0], ItemType.HitTarget, item).Select(obj => SetupHitObject(obj, setHitObject, table))); } // add collision vertices foreach (var vertex in hitMesh.Vertices) { hitObjects.Add(SetupHitObject(new HitPoint(vertex.GetVertex(), ItemType.HitTarget, item), setHitObject, table)); } return(hitObjects.ToArray()); }
/// <summary> /// Merges the node x into the fixed target node into. /// /// Edges between these nodes, edges to x and related distance information is updated. /// /// x is marked as to be removed from the search space. If x was the start node, into /// will now be the start node. /// </summary> /// <returns>All neighbors of x before merging. These are the nodes that had their adjacency /// information changed.</returns> protected IEnumerable <int> MergeInto(int x, int into) { if (!NodeStates.IsFixedTarget(into)) { throw new ArgumentException("Nodes can only be merged into fixed target nodes", "into"); } _data.DistanceLookup.IndexToNode(into).MergeWith(_data.DistanceLookup.IndexToNode(x), _data.DistanceLookup.GetShortestPath(x, into)); _data.DistanceLookup.MergeInto(x, into); EdgeSet.Remove(x, into); var intoNeighbors = EdgeSet.NeighborsOf(into); var xNeighbors = EdgeSet.NeighborsOf(x); var neighbors = intoNeighbors.Union(xNeighbors); foreach (var neighbor in xNeighbors) { EdgeSet.Remove(x, neighbor); } foreach (var neighbor in neighbors) { EdgeSet.Add(into, neighbor, _data.DistanceLookup[into, neighbor]); } if (StartNodeIndex == x) { _data.StartNodeIndex = into; } NodeStates.MarkNodeAsRemoved(x); return(xNeighbors); }
public static IEnumerable <HitObject> MeshToHitObjects(Mesh mesh, ItemType itemType, IItem item) { var hitObjects = new List <HitObject>(); var addedEdges = new EdgeSet(); // add collision triangles and edges for (var i = 0; i < mesh.Indices.Length; i += 3) { var i0 = mesh.Indices[i]; var i1 = mesh.Indices[i + 1]; var i2 = mesh.Indices[i + 2]; // NB: HitTriangle wants CCW vertices, but for rendering we have them in CW order var rgv3D = new[] { mesh.Vertices[i0].GetVertex(), mesh.Vertices[i2].GetVertex(), mesh.Vertices[i1].GetVertex(), }; hitObjects.Add(new HitTriangle(rgv3D, itemType, item)); hitObjects.AddRange(addedEdges.AddHitEdge(i0, i1, rgv3D[0], rgv3D[2], itemType, item)); hitObjects.AddRange(addedEdges.AddHitEdge(i1, i2, rgv3D[2], rgv3D[1], itemType, item)); hitObjects.AddRange(addedEdges.AddHitEdge(i2, i0, rgv3D[1], rgv3D[0], itemType, item)); } // add collision vertices foreach (var vertex in mesh.Vertices) { hitObjects.Add(new HitPoint(vertex.GetVertex(), itemType, item)); } return(hitObjects); }
/// <summary> /// Tries to obtain first pending edge set, and advances state under big lock. /// </summary> private bool TryRemoveFirstPendingEdgeSet(out EdgeSet edgeSet, out bool add) { lock (m_pendingEdgeSets) { if (m_pendingEdgeSets.Count > 0) { edgeSet = m_pendingEdgeSets.First.Value; switch (edgeSet.State) { case EdgeSetState.PendingAdd: edgeSet.State = EdgeSetState.Adding; add = true; edgeSet.PendingEdgeSetNode = null; break; case EdgeSetState.PendingRemove: edgeSet.State = EdgeSetState.Invalid; add = false; break; default: throw Contract.AssertFailure("unexpected edge set state"); } m_pendingEdgeSets.RemoveFirst(); return(true); } } edgeSet = null; add = false; return(false); }
public EdgeDrawer(EdgeSet edgeSet) { _arcToEdges = edgeSet.VertexLists(); _edgeListObjects = new Dictionary <IArc, GameObject>(); _parentObject = new GameObject("Edges"); }
public void Add(params int[] vertices) { foreach (var vertex in vertices) { _vertices.Add(vertex); _graph[vertex] = new EdgeSet(); } }
public void ShapeCell(Mesh m) { vertices = new VertexSet(); edges = new EdgeSet(); faces = new FaceSet(); copy(m); }
private static PolySet StitchPolys(ICollection <Polygon> polygons, IList <Vector3> vertices, PolySet polys, out EdgeSet stitchedEdge) { var stichedPolys = new PolySet { StitchedVertexThreshold = vertices.Count }; stitchedEdge = PolySet.CreateEdgeSet(polys); IList <int> originalVerts = EdgeSet.GetUniqueVertices(stitchedEdge); IList <int> newVerts = CloneVertices(vertices, originalVerts); stitchedEdge.Split(originalVerts, newVerts); foreach (Edge edge in stitchedEdge) { // Create new polys along the stitched edge. These // will connect the original poly to its former // neighbor. var stitchPoly1 = new Polygon(edge.OuterVerts[0], edge.OuterVerts[1], edge.InnerVerts[0]); var stitchPoly2 = new Polygon(edge.OuterVerts[1], edge.InnerVerts[1], edge.InnerVerts[0]); // Add the new stitched faces as neighbors to // the original Polys. Polygon.ReplacePolygon(edge.InnerPoly.Neighbors, edge.OuterPoly, stitchPoly2); Polygon.ReplacePolygon(edge.OuterPoly.Neighbors, edge.InnerPoly, stitchPoly1); polygons.Add(stitchPoly1); polygons.Add(stitchPoly2); stichedPolys.Add(stitchPoly1); stichedPolys.Add(stitchPoly2); } //Swap to the new vertices on the inner polys. foreach (Polygon poly in polys) { for (int i = 0; i < 3; i++) { int vertID = poly.Vertices[i]; if (!originalVerts.Contains(vertID)) { continue; } int vertIndex = originalVerts.IndexOf(vertID); poly.Vertices[i] = newVerts[vertIndex]; } } return(stichedPolys); }
/// <summary> /// Default ctor /// </summary> public Module() { blocks = new BlockSet(this); blockGroups = new BlockGroupSet(this); junctions = new JunctionSet(this); routes = new RouteSet(this); edges = new EdgeSet(this); sensors = new SensorSet(this); signals = new SignalSet(this); outputs = new OutputSet(this); }
public override bool AreAdjacent(TV v1, TV v2) { if (v1 == null || v2 == null) { throw new ArgumentNullException(); } if (!VertexSet.Contains(v1) || !VertexSet.Contains(v2)) { throw new ArgumentException(); } return(EdgeSet.Contains(new PairValue <TV>(v1, v2))); }
public PolySet StitchPolys(PolySet polys, out EdgeSet stitchedEdge) { PolySet stichedPolys = new PolySet(); stichedPolys.m_StitchedVertexThreshold = m_Vertices.Count; stitchedEdge = polys.CreateEdgeSet(); var originalVerts = stitchedEdge.GetUniqueVertices(); var newVerts = CloneVertices(originalVerts); stitchedEdge.Split(originalVerts, newVerts); foreach (Edge edge in stitchedEdge) { // Create new polys along the stitched edge. These // will connect the original poly to its former // neighbor. var stitch_poly1 = new Polygon(edge.m_OuterVerts[0], edge.m_OuterVerts[1], edge.m_InnerVerts[0]); var stitch_poly2 = new Polygon(edge.m_OuterVerts[1], edge.m_InnerVerts[1], edge.m_InnerVerts[0]); // Add the new stitched faces as neighbors to // the original Polys. edge.m_InnerPoly.ReplaceNeighbor(edge.m_OuterPoly, stitch_poly2); edge.m_OuterPoly.ReplaceNeighbor(edge.m_InnerPoly, stitch_poly1); m_Polygons.Add(stitch_poly1); m_Polygons.Add(stitch_poly2); stichedPolys.Add(stitch_poly1); stichedPolys.Add(stitch_poly2); } //Swap to the new vertices on the inner polys. foreach (Polygon poly in polys) { for (int i = 0; i < 3; i++) { int vert_id = poly.m_Vertices[i]; if (!originalVerts.Contains(vert_id)) { continue; } int vert_index = originalVerts.IndexOf(vert_id); poly.m_Vertices[i] = newVerts[vert_index]; } } return(stichedPolys); }
public IDisposable AddValuePromiseChain(Func <IValuePromise[]> valuePromiseChainGetter, Action cycleAnnouncer) { var edgeSet = new EdgeSet(this, valuePromiseChainGetter, cycleAnnouncer); lock (m_pendingEdgeSets) { Contract.Assume(edgeSet.State == EdgeSetState.PendingAdd); edgeSet.PendingEdgeSetNode = m_pendingEdgeSets.AddLast(edgeSet); } Interlocked.Increment(ref m_statistics.CycleDetectionChainsAdded); return(edgeSet); }
protected override int ExecuteTest() { // The test only makes sense with at least 2 terminals. if (NodeStates.FixedTargetNodeCount <= 1) { return(0); } var removedNodes = 0; var untested = new HashSet <int>(NodeStates.FixedTargetNodeIndices); // For each terminal z with degree of at least 2 while (untested.Any()) { var z = untested.First(); untested.Remove(z); var neighbors = EdgeSet.NeighborsOf(z); if (neighbors.Count < 2) { continue; } // Determine the shortest and second shortest edge incident to z. // For the second shortest, only the weight is of interest. var tuple = ShortestTwoEdgesOf(EdgeSet.EdgesOf(z)); var shortest = tuple.Item1; var secondShortestWeight = tuple.Item2; // v is the node which is connected to z via the shortest edge. var v = shortest.N1 == z ? shortest.N2 : shortest.N1; // The shortest edge belongs to at least one Steiner minimal tree, if // secondShortestWeight >= shortest.Weight + distance(v, y) for any terminal y, y != z var canBeContracted = NodeStates.FixedTargetNodeIndices .Where(y => z != y) .Any(y => secondShortestWeight >= shortest.Weight + DistanceLookup[v, y]); // If such a y exists, we can merge v into z. if (canBeContracted) { // z was changed and can be tested again. untested.Add(z); // v no longer exists and as such must not be tested. untested.Remove(v); MergeInto(v, z); removedNodes++; } } return(removedNodes); }
private void GenerateFaces(EdgeSet surfaceEdges, List <Vector3> vertices, List <Vector3> normals, Dictionary <Vector3Int, int> blockVertexMap, List <int> indices) { foreach (Edge edge in surfaceEdges.AllEdges) { // At this point, an edge in the list should reference the 4 blocks that share that edge // If it doesn't, something went wrong. if (edge.blocks.Count != 4) { continue; } int i1 = blockVertexMap[edge.blocks[0]]; int i2 = blockVertexMap[edge.blocks[1]]; int i3 = blockVertexMap[edge.blocks[2]]; int i4 = blockVertexMap[edge.blocks[3]]; // Determine winding order based on our estimated normals Vector3 p1 = vertices[i1]; Vector3 p2 = vertices[i2]; Vector3 p3 = vertices[i3]; Vector3 p4 = vertices[i4]; Vector3 p1p2 = p2 - p1; Vector3 p1p3 = p3 - p1; Vector3 cross = Vector3.Cross(p1p2, p1p3); float dotNormal = Vector3.Dot(cross, normals[i1]); if (dotNormal >= 0f) { indices.Add(i1); indices.Add(i2); indices.Add(i3); indices.Add(i2); indices.Add(i4); indices.Add(i3); } else { indices.Add(i2); indices.Add(i1); indices.Add(i3); indices.Add(i2); indices.Add(i3); indices.Add(i4); } } }
public override bool DeleteEdge(TV v1, TV v2) { if (v1 == null || v2 == null) { throw new ArgumentNullException(); } IPairValue <TV> pair = new PairValue <TV>(v1, v2); if (EdgeSet.Contains(pair)) { EdgeSet.Remove(pair); Weigths.Remove(pair); return(true); } return(false); }
public Graph(IEnumerable <Edge> edges) { _edges = new List <Edge>(edges); _vertices = new List <int>(edges.Select(i => i.In).Union(edges.Select(i => i.Out))); _graph = new Dictionary <int, EdgeSet>(); foreach (var vertex in _vertices) { _graph[vertex] = new EdgeSet(); } foreach (var edge in _edges) { _graph[edge.In].Ins.Add(edge); _graph[edge.Out].Outs.Add(edge); } }
public MGCell(int i, int tissueId, Mesh m) { cellId = i; nuclei = new Vertex[2]; nuclei[0] = new Vertex(); centre = new Vector(0, 0, 0); ShapeCell(m); nbOfParticles = vertexCount(); innerRadius = m.innerRadius; neighbours = new List <int>(); sigma = new int[nbOfParticles]; spins = new float[nbOfParticles]; targetVertices = new Vector[nbOfParticles]; externalEdges = new EdgeSet(); nucleusEdges = new EdgeSet(); subset = new List <int>(); nuclei[0].id = nbOfParticles; nuclei[0].cellId = cellId; axis = new Vector[3]; for (int j = 0; j < nbOfParticles; j++) { vertices[j].id = j; vertices[j].cellId = i; vertices[j].tissueId = tissueId; Edge edge = new Edge(vertices[j], nuclei[0]); nucleusEdges.add(edge); targetVertices[j] = vertices[j].Clone().v; int k = new Random().Next(2); spins[j] = (k == 0) ? MGModel.delta : -MGModel.delta; sigma[j] = j; vertices[j].externalNeighbours = new List <int[]>(); vertices[j].globalForces = new Vector(); subset.Add(j); } nuclei[0].v = ComputeCentreFromMesh(); SetEdgeELengths(); ResetCell(); }
public override bool DeleteEdge(T v1Key, T v2Key) { if (v1Key == null || v2Key == null) { throw new ArgumentNullException(); } IPairValue <T> pair = new PairValue <T>(v1Key, v2Key); if (EdgeSet.Contains(pair)) { EdgeSet.Remove(pair); Weights.Remove(pair); return(true); } return(false); }
public EdgeSet CreateEdgeSet() { EdgeSet edgeSet = new EdgeSet(); foreach (Polygon poly in this) { foreach (Polygon neighbor in poly.m_Neighbors) { if (this.Contains(neighbor)) { continue; } Edge edge = new Edge(poly, neighbor); edgeSet.Add(edge); } } return(edgeSet); }
/// <summary> /// Adds an edge set (increasing reference counts), /// and if resulting graph has a cycle, invoke the edge set's cycle announcer. /// </summary> public void AddEdgeSetAndFindCycle(EdgeSet edgeSet) { foreach (var edge in edgeSet.Edges) { AddEdge(edge); } Contract.Assume(m_markers.Count == 0); foreach (var valuePromiseWithOutgoingEdges in m_graph.Keys) { if (!IsCycleFreeFrom(valuePromiseWithOutgoingEdges)) { edgeSet.CycleAnnouncer(); break; } } m_markers.Clear(); }