private void TraceContiguousJunctions(Component component) { Dictionary <Discrete2D, BranchNode> junctionPoints = component.junctions; foreach (KeyValuePair <Discrete2D, BranchNode> starting in junctionPoints) { Debug.Assert(notVisitedMap[starting.Key.I, starting.Key.J]); MarkVisited(starting.Key); // n.b. not unmarked later, to prevent marking contiguous segments twice // Determine the 8-connected neighbours int neighbourhood = BitImage.Analysis.Neighbourhood(notVisitedMap, starting.Key.I, starting.Key.J); // TODO: Is it possible to have diagonally connected junctions? List <Discrete2D> relativeNeighbours = new List <Discrete2D>(BitImage.Analysis.ConnectedRelativeCoordinates(neighbourhood)); foreach (Discrete2D relativeNeighbour in relativeNeighbours) { Discrete2D neighbour = starting.Key + relativeNeighbour; // Check that the starting point hasn't already been consumed by the other branchpoint if (IsJunction(neighbour)) { SegmentNode segment = new SegmentNode(); segment.PreviousBranch = starting.Value; segment.NextBranch = junctionPoints[neighbour]; } } } }
public SegmentNode CreateSegmentNode() { SegmentNode node = new SegmentNode(); segmentNodes.Add(node); return(node); }
private void TraceEightConnectedFromJunctions(Component component) { // TODO: This case only occurs if there are segments which are 8-connected // at BOTH ends to branch points. NOT YET TESTED. Dictionary <Discrete2D, BranchNode> junctionPoints = component.junctions; // Trace line segments from each junction point's 8-connected neighbours foreach (KeyValuePair <Discrete2D, BranchNode> starting in junctionPoints) { Debug.Assert(notVisitedMap[starting.Key.I, starting.Key.J]); MarkVisited(starting.Key); // Prevent tracings immediately returning to their origin // Determine the 8-connected neighbours int neighbourhood = BitImage.Analysis.Neighbourhood(notVisitedMap, starting.Key.I, starting.Key.J); int fourNeighbourhood = BitImage.Analysis.ToFourDiagonal(neighbourhood); // One line different int filteredNeighbourhood = RemoveJunctions(starting.Key, fourNeighbourhood); // NOT NEEDED?? List <Discrete2D> fourNeighbours = new List <Discrete2D>(BitImage.Analysis.ConnectedRelativeCoordinates(filteredNeighbourhood)); foreach (Discrete2D relativeNeighbour in fourNeighbours) { Discrete2D neighbour = starting.Key + relativeNeighbour; // Check that the starting point hasn't already been consumed, for example, // by a single line looping back so the same branch point it originated from if (notVisitedMap[neighbour.I, neighbour.J]) { SegmentNode segment = TraceSegment(component, neighbour); segment.PreviousBranch = starting.Value; } else { Console.WriteLine("Model contains single segment loops!"); // TODO: Test this } } UnmarkVisited(starting.Key); // Unmark, so that this junction point can be found for other segment ends } }
/// <summary> /// Insert a FaultEdge edge into the mesh between the two specified positions /// </summary> /// <param name="segment">The equivalent segment in the FaultNetwork</param> /// <param name="m">The mesh to which the edge is to be added</param> /// <param name="p1">A position at the start of the edge</param> /// <param name="p2">A position at the end of the edge</param> private static void AddFaultEdge(SegmentNode segment, Mesh <PositionedVertexBase, EdgeBase, FaceBase> m, IPositionable2D p1, IPositionable2D p2) { var v1 = m.Find(new FaultVertex(p1)); Debug.Assert(v1 != null); var v2 = m.Find(new FaultVertex(p2)); Debug.Assert(v2 != null); m.AddEdge(v1, v2, new FaultEdge(segment)); }
private Discrete2D?AppendToSegment(Discrete2D?current, SegmentNode segment, Discrete2D neighbour) { // Add a point to the segment, and move on Debug.Assert(current.HasValue); Debug.Assert(IsStem(neighbour)); Point2D currentGeographic = GridToGeographic(current.Value.I, current.Value.J); segment.Add(currentGeographic); MarkVisited(current.Value); return(neighbour); }
private Discrete2D?Follow(Component component, Discrete2D?current, SegmentNode segment) { Debug.Assert(current.HasValue); int neighbourhood = BitImage.Analysis.Neighbourhood(notVisitedMap, current.Value.I, current.Value.J); neighbourhood = AccountForJunctions(current, neighbourhood); int eightConnectivity = BitImage.Analysis.EightConnectivity(neighbourhood); Debug.Assert(eightConnectivity > 0); if (eightConnectivity == 1) { List <Discrete2D> neighbours = new List <Discrete2D>(BitImage.Analysis.ConnectedRelativeCoordinates(neighbourhood)); Debug.Assert(eightConnectivity == neighbours.Count); Discrete2D neighbour = current.Value + neighbours[0]; if (IsJunction(neighbour)) { current = EndSegmentAtJunction(component, current, segment, neighbour); } else if (IsFreeEnd(neighbour)) { current = EndSegmentAtFreeEnd(current, segment, neighbour); } else // neighbour is segment stem { current = AppendToSegment(current, segment, neighbour); } } else // eightConnectivity > 1 { // Determine numFour - the number of 4-connected neighbours int fourConnectivity = BitImage.Analysis.FourConnectivity(neighbourhood); Debug.Assert(fourConnectivity == 1); int fourNeighbourhood = BitImage.Analysis.ToFourCross(neighbourhood); List <Discrete2D> fourNeighbours = new List <Discrete2D>(BitImage.Analysis.ConnectedRelativeCoordinates(fourNeighbourhood)); Debug.Assert(fourConnectivity == fourNeighbours.Count); Discrete2D neighbour = current.Value + fourNeighbours[0]; if (IsJunction(neighbour)) { current = EndSegmentAtJunction(component, current, segment, neighbour); } else // Extend to neighbour { Debug.Assert(IsStem(neighbour)); current = AppendToSegment(current, segment, neighbour); } } return(current); }
private SegmentNode TraceSegment(Component component, Discrete2D start) { Discrete2D?current = start; Debug.Assert(connectivityMap[current.Value.I, current.Value.J] != 0); SegmentNode segment = network.CreateSegmentNode(); while (current.HasValue) { current = Follow(component, current, segment); } return(segment); }
private Discrete2D?EndSegmentAtFreeEnd(Discrete2D?current, SegmentNode segment, Discrete2D neighbour) { // End segment here by adding last node Debug.Assert(current.HasValue); Point2D currentGeographic = GridToGeographic(current.Value.I, current.Value.J); segment.Add(currentGeographic); Point2D neighbourGeographic = GridToGeographic(neighbour.I, neighbour.J); segment.Add(neighbourGeographic); segment.NextBranch = null; MarkVisited(current.Value); MarkVisited(neighbour); return(null); }
/// <summary> /// Create a mesh representing the fault centerlines /// </summary> private Mesh <PositionedVertexBase, EdgeBase, FaceBase> CreateMesh() { // 1a. Add the vertices IEnumerable <PositionedVertexBase> vs = network.Points.Select(fp => (PositionedVertexBase) new FaultVertex(fp)); var mesh = new Mesh <PositionedVertexBase, EdgeBase, FaceBase>(vs); // 1b. Connect vertices foreach (SegmentNode segment in network.Segments) { SegmentNode s = segment; // Prevents access to modified closure segment.InclusivePoints.ForEachPair((p1, p2) => AddFaultEdge(s, mesh, p1, p2)); } return(mesh); }
internal void RemoveInSegment(SegmentNode segment) { Debug.Assert(segment.NextBranch != this); Debug.Assert(inSegments.Contains(segment)); inSegments.Remove(segment); }
internal void RemoveOutSegment(SegmentNode segment) { Debug.Assert(segment.PreviousBranch != this); Debug.Assert(outSegments.Contains(segment)); outSegments.Remove(segment); }
internal void AddInSegment(SegmentNode segment) { Debug.Assert(segment.NextBranch == this); inSegments.Add(segment); }
internal void AddOutSegment(SegmentNode segment) { Debug.Assert(segment.PreviousBranch == this); outSegments.Add(segment); }
private Discrete2D?EndSegmentAtJunction(Component component, Discrete2D?current, SegmentNode segment, Discrete2D junction) { // End segment here with edge to junction Debug.Assert(current.HasValue); BranchNode branchPoint = component.junctions[junction]; Point2D geographic = GridToGeographic(current.Value.I, current.Value.J); segment.Add(geographic); segment.NextBranch = branchPoint; MarkVisited(current.Value); return(null); }
internal bool ContainsInSegment(SegmentNode segment) { return(inSegments.Contains(segment)); }
internal bool ContainsOutSegment(SegmentNode segment) { return(outSegments.Contains(segment)); }
public FaultPoint(Point2D position, SegmentNode parentNode) { this.position = position; }