/// <summary> /// Create a new "split edge" with the section of points between /// (and including) the two intersections. /// The label for the new edge is the same as the label for the parent edge. /// </summary> /// <param name="ei0"></param> /// <param name="ei1"></param> /// <returns></returns> private SegmentString CreateSplitEdge(SegmentNode ei0, SegmentNode ei1) { int npts = ei1.SegmentIndex - ei0.SegmentIndex + 2; Coordinate lastSegStartPt = _edge.GetCoordinate(ei1.SegmentIndex); // if the last intersection point is not equal to the its segment start pt, add it to the points list as well. // (This check is needed because the distance metric is not totally reliable!) // The check for point equality is 2D only - Z values are ignored bool useIntPt1 = ei1.IsInterior || !ei1.Coordinate.Equals2D(lastSegStartPt); if (!useIntPt1) { npts--; } Coordinate[] pts = new Coordinate[npts]; int ipt = 0; pts[ipt++] = new Coordinate(ei0.Coordinate); for (int i = ei0.SegmentIndex + 1; i <= ei1.SegmentIndex; i++) { pts[ipt++] = _edge.GetCoordinate(i); } if (useIntPt1) { pts[ipt] = ei1.Coordinate; } return(new SegmentString(pts, _edge.Data)); }
/// <summary> /// Consente di spostare l'enumeratore all'elemento successivo dell'insieme. /// </summary> /// <returns> /// true se l'enumeratore è stato spostato correttamente in avanti in corrispondenza dell'elemento successivo; false se l'enumeratore ha raggiunto la fine dell'insieme. /// </returns> /// <exception cref="T:System.InvalidOperationException">L'insieme è stato modificato dopo la creazione dell'enumeratore. </exception> public bool MoveNext() { if (_currNode == null) { _currNode = _nextNode; _currSegIndex = _currNode.SegmentIndex; ReadNextNode(); return(true); } // check for trying to read too far if (_nextNode == null) { return(false); } if (_nextNode.SegmentIndex == _currNode.SegmentIndex) { _currNode = _nextNode; _currSegIndex = _currNode.SegmentIndex; ReadNextNode(); return(true); } if (_nextNode.SegmentIndex > _currNode.SegmentIndex) { } return(false); }
/// <summary> /// /// </summary> /// <param name="outstream"></param> public virtual void Write(StreamWriter outstream) { outstream.Write("Intersections:"); foreach (object obj in this) { SegmentNode ei = (SegmentNode)obj; ei.Write(outstream); } }
private void ReadNextNode() { if (_nodeIt.MoveNext()) { _nextNode = (SegmentNode)_nodeIt.Current; } else { _nextNode = null; } }
/// <summary> /// Adds an intersection into the list, if it isn't already there. /// The input segmentIndex and dist are expected to be normalized. /// </summary> /// <param name="intPt"></param> /// <param name="segmentIndex"></param> public void Add(Coordinate intPt, int segmentIndex) { SegmentNode eiNew = new SegmentNode(_edge, intPt, segmentIndex, _edge.GetSegmentOctant(segmentIndex)); SegmentNode ei = (SegmentNode)_nodeMap[eiNew]; if (ei != null) { // debugging sanity check Assert.IsTrue(ei.Coordinate.Equals2D(intPt), "Found equal nodes with different coordinates"); return; } // node does not exist, so create it _nodeMap.Add(eiNew, eiNew); return; }
/// <summary> /// </summary> /// <param name="obj"></param> /// <returns> /// -1 this SegmentNode is located before the argument location, or /// 0 this SegmentNode is at the argument location, or /// 1 this SegmentNode is located after the argument location. /// </returns> public int CompareTo(object obj) { SegmentNode other = (SegmentNode)obj; if (SegmentIndex < other.SegmentIndex) { return(-1); } if (SegmentIndex > other.SegmentIndex) { return(1); } if (Coordinate.Equals2D(other.Coordinate)) { return(0); } return(SegmentPointComparator.Compare(_segmentOctant, Coordinate, other.Coordinate)); }
/// <summary> /// /// </summary> /// <param name="ei0"></param> /// <param name="ei1"></param> /// <param name="collapsedVertexIndex"></param> /// <returns></returns> private static bool FindCollapseIndex(SegmentNode ei0, SegmentNode ei1, int[] collapsedVertexIndex) { // only looking for equal nodes if (!ei0.Coordinate.Equals2D(ei1.Coordinate)) { return(false); } int numVerticesBetween = ei1.SegmentIndex - ei0.SegmentIndex; if (!ei1.IsInterior) { numVerticesBetween--; } // if there is a single vertex between the two equal nodes, this is a collapse if (numVerticesBetween == 1) { collapsedVertexIndex[0] = ei0.SegmentIndex + 1; return(true); } return(false); }
/// <summary> /// Creates new edges for all the edges that the intersections in this /// list split the parent edge into. /// Adds the edges to the provided argument list /// (this is so a single list can be used to accumulate all split edges /// for a set of <see cref="SegmentString" />s). /// </summary> /// <param name="edgeList"></param> public void AddSplitEdges(IList edgeList) { // ensure that the list has entries for the first and last point of the edge AddEndPoints(); AddCollapsedNodes(); IEnumerator ie = GetEnumerator(); ie.MoveNext(); // there should always be at least two entries in the list, since the endpoints are nodes SegmentNode eiPrev = (SegmentNode)ie.Current; while (ie.MoveNext()) { SegmentNode ei = (SegmentNode)ie.Current; SegmentString newEdge = CreateSplitEdge(eiPrev, ei); edgeList.Add(newEdge); eiPrev = ei; } // CheckSplitEdgesCorrectness(testingSplitEdges); }
/// <summary> /// Adds nodes for any collapsed edge pairs caused by inserted nodes /// Collapsed edge pairs occur when the same coordinate is inserted as a node /// both before and after an existing edge vertex. /// To provide the correct fully noded semantics, /// the vertex must be added as a node as well. /// </summary> /// <param name="collapsedVertexIndexes"></param> private void FindCollapsesFromInsertedNodes(IList collapsedVertexIndexes) { int[] collapsedVertexIndex = new int[1]; IEnumerator ie = GetEnumerator(); ie.MoveNext(); // there should always be at least two entries in the list, since the endpoints are nodes SegmentNode eiPrev = (SegmentNode)ie.Current; while (ie.MoveNext()) { SegmentNode ei = (SegmentNode)ie.Current; bool isCollapsed = FindCollapseIndex(eiPrev, ei, collapsedVertexIndex); if (isCollapsed) { collapsedVertexIndexes.Add(collapsedVertexIndex[0]); } eiPrev = ei; } }
private void ReadNextNode() { if (_nodeIt.MoveNext()) _nextNode = (SegmentNode)_nodeIt.Current; else _nextNode = null; }
/// <summary> /// Consente di spostare l'enumeratore all'elemento successivo dell'insieme. /// </summary> /// <returns> /// true se l'enumeratore è stato spostato correttamente in avanti in corrispondenza dell'elemento successivo; false se l'enumeratore ha raggiunto la fine dell'insieme. /// </returns> /// <exception cref="T:System.InvalidOperationException">L'insieme è stato modificato dopo la creazione dell'enumeratore. </exception> public bool MoveNext() { if (_currNode == null) { _currNode = _nextNode; _currSegIndex = _currNode.SegmentIndex; ReadNextNode(); return true; } // check for trying to read too far if (_nextNode == null) return false; if (_nextNode.SegmentIndex == _currNode.SegmentIndex) { _currNode = _nextNode; _currSegIndex = _currNode.SegmentIndex; ReadNextNode(); return true; } if (_nextNode.SegmentIndex > _currNode.SegmentIndex) { } return false; }
/// <summary> /// Create a new "split edge" with the section of points between /// (and including) the two intersections. /// The label for the new edge is the same as the label for the parent edge. /// </summary> /// <param name="ei0"></param> /// <param name="ei1"></param> /// <returns></returns> private SegmentString CreateSplitEdge(SegmentNode ei0, SegmentNode ei1) { int npts = ei1.SegmentIndex - ei0.SegmentIndex + 2; Coordinate lastSegStartPt = _edge.GetCoordinate(ei1.SegmentIndex); // if the last intersection point is not equal to the its segment start pt, add it to the points list as well. // (This check is needed because the distance metric is not totally reliable!) // The check for point equality is 2D only - Z values are ignored bool useIntPt1 = ei1.IsInterior || !ei1.Coordinate.Equals2D(lastSegStartPt); if (!useIntPt1) npts--; Coordinate[] pts = new Coordinate[npts]; int ipt = 0; pts[ipt++] = new Coordinate(ei0.Coordinate); for (int i = ei0.SegmentIndex + 1; i <= ei1.SegmentIndex; i++) pts[ipt++] = _edge.GetCoordinate(i); if (useIntPt1) pts[ipt] = ei1.Coordinate; return new SegmentString(pts, _edge.Data); }
/// <summary> /// /// </summary> /// <param name="ei0"></param> /// <param name="ei1"></param> /// <param name="collapsedVertexIndex"></param> /// <returns></returns> private static bool FindCollapseIndex(SegmentNode ei0, SegmentNode ei1, int[] collapsedVertexIndex) { // only looking for equal nodes if (!ei0.Coordinate.Equals2D(ei1.Coordinate)) return false; int numVerticesBetween = ei1.SegmentIndex - ei0.SegmentIndex; if (!ei1.IsInterior) numVerticesBetween--; // if there is a single vertex between the two equal nodes, this is a collapse if (numVerticesBetween == 1) { collapsedVertexIndex[0] = ei0.SegmentIndex + 1; return true; } return false; }