private void ComputeEdgeEndLabels() { // Compute edge label for each EdgeEnd for (IEnumerator it = Iterator(); it.MoveNext();) { EdgeEnd ee = (EdgeEnd)it.Current; ee.ComputeLabel(); } }
/// <summary> Insert an EdgeEnd into the map, and clear the edgeList cache, /// since the list of edges has now changed /// </summary> protected virtual void InsertEdgeEnd(EdgeEnd e, object obj) { // object tempObject; // tempObject = obj; // edgeMap[e] = tempObject; // object generatedAux = tempObject; edgeMap[e] = obj; edgeList = null; // edge list has changed - clear the cache }
/// <summary> /// Returns the EdgeEnd which has edge e as its base edge /// (MD 18 Feb 2002 - this should return a pair of edges) /// </summary> /// <returns> the edge, if found /// null if the edge was not found /// </returns> public EdgeEnd FindEdgeEnd(Edge e) { for (IEnumerator i = EdgeEnds.GetEnumerator(); i.MoveNext();) { EdgeEnd ee = (EdgeEnd)i.Current; if (ee.Edge == e) { return(ee); } } return(null); }
public int FindIndex(EdgeEnd eSearch) { Iterator(); // force edgelist to be computed for (int i = 0; i < edgeList.Count; i++) { EdgeEnd e = (EdgeEnd)edgeList[i]; if (e == eSearch) { return(i); } } return(-1); }
private bool CheckAreaLabelsConsistent(int geomIndex) { // Since edges are stored in CCW order around the node, // As we move around the ring we move from the right to the left side of the edge IList edges = this.Edges; // if no edges, trivially consistent if (edges.Count <= 0) { return(true); } // initialize startLoc to location of last L side (if any) int lastEdgeIndex = edges.Count - 1; Label startLabel = ((EdgeEnd)edges[lastEdgeIndex]).Label; int startLoc = startLabel.GetLocation(geomIndex, Position.Left); Debug.Assert(startLoc != LocationType.None, "Found unlabelled area edge"); int currLoc = startLoc; for (IEnumerator it = Iterator(); it.MoveNext();) { EdgeEnd e = (EdgeEnd)it.Current; Label label = e.Label; // we assume that we are only checking a area Debug.Assert(label.IsArea(geomIndex), "Found non-area edge"); int leftLoc = label.GetLocation(geomIndex, Position.Left); int rightLoc = label.GetLocation(geomIndex, Position.Right); // check that edge is really a boundary between inside and outside! if (leftLoc == rightLoc) { return(false); } // check side location conflict //Assert.isTrue(rightLoc == currLoc, "side location conflict " + locStr); if (rightLoc != currLoc) { return(false); } currLoc = leftLoc; } return(true); }
public EdgeEnd GetNextCW(EdgeEnd ee) { IList generatedAux = Edges; if (generatedAux == null) { return(null); } int i = edgeList.IndexOf(ee); int iNextCW = i - 1; if (i == 0) { iNextCW = edgeList.Count - 1; } return((EdgeEnd)edgeList[iNextCW]); }
/// <summary> /// Compares the directions of the specified <see cref="EdgeEnd"/> and the current /// EdgeEnd. /// </summary> /// <remarks> /// Implements the total order relation: /// <para> /// "a" has a greater angle with the positive x-axis than "b" /// </para> /// <para> /// Using the obvious algorithm of simply computing the angle is not robust, /// since the angle calculation is obviously susceptible to roundoff. /// </para> /// A robust algorithm is: /// <list type="number"> /// <item> /// <description> /// first Compare the quadrant. If the quadrants /// are different, it it trivial to determine which vector is "greater". /// </description> /// </item> /// <item> /// <description> /// if the vectors lie in the same quadrant, the computeOrientation function /// can be used to decide the relative orientation of the vectors. /// </description> /// </item> /// </list> /// </remarks> public int CompareDirection(EdgeEnd e) { if (dx == e.dx && dy == e.dy) { return(0); } // if the rays are in different quadrants, determining the ordering is trivial if (quadrant > e.quadrant) { return(1); } if (quadrant < e.quadrant) { return(-1); } // vectors are in the same quadrant - check relative // orientation of direction vectors // this is > e if it is CCW of e return((int)CGAlgorithms.ComputeOrientation(e.p0, e.p1, p1)); }
/// <summary> /// Compute the labelling for all dirEdges in this star, as well as the /// overall labelling. /// </summary> public override void ComputeLabelling(GeometryGraph[] geom) { base.ComputeLabelling(geom); // determine the overall labelling for this DirectedEdgeStar // (i.e. for the node it is based at) label = new Label(LocationType.None); for (IEnumerator it = Iterator(); it.MoveNext();) { EdgeEnd ee = (EdgeEnd)it.Current; Edge e = ee.Edge; Label eLabel = e.Label; for (int i = 0; i < 2; i++) { int eLoc = eLabel.GetLocation(i); if (eLoc == LocationType.Interior || eLoc == LocationType.Boundary) { label.SetLocation(i, LocationType.Interior); } } } }
public void Add(EdgeEnd e) { m_objNodes.Add(e); edgeEndList.Add(e); }
internal void PropagateSideLabels(int geomIndex) { // Since edges are stored in CCW order around the node, // As we move around the ring we move from the right to the left side of the edge int startLoc = LocationType.None; // initialize loc to location of last L side (if any) for (IEnumerator it = Iterator(); it.MoveNext();) { EdgeEnd e = (EdgeEnd)it.Current; Label label = e.Label; if (label.IsArea(geomIndex) && label.GetLocation(geomIndex, Position.Left) != LocationType.None) { startLoc = label.GetLocation(geomIndex, Position.Left); } } // no labelled sides found, so no labels to propagate if (startLoc == LocationType.None) { return; } int currLoc = startLoc; for (IEnumerator it = Iterator(); it.MoveNext();) { EdgeEnd e = (EdgeEnd)it.Current; Label label = e.Label; // set null ON values to be in current location if (label.GetLocation(geomIndex, Position.On) == LocationType.None) { label.SetLocation(geomIndex, Position.On, currLoc); } // set side labels (if any) // if (label.IsArea()) { //ORIGINAL if (label.IsArea(geomIndex)) { int leftLoc = label.GetLocation(geomIndex, Position.Left); int rightLoc = label.GetLocation(geomIndex, Position.Right); // if there is a right location, that is the next location to propagate if (rightLoc != LocationType.None) { //Debug.Print(rightLoc != currLoc, this); if (rightLoc != currLoc) { throw new GeometryException("side location conflict", e.Coordinate); } if (leftLoc == LocationType.None) { Debug.Assert(false, "Should never reach here: found single null side (at " + e.Coordinate + ")"); } currLoc = leftLoc; } else { /// <summary>RHS is null - LHS must be null too. /// This must be an edge from the other geometry, which has no location /// labelling for this geometry. This edge must lie wholly inside or outside /// the other geometry (which is determined by the current location). /// Assign both sides to be the current location. /// </summary> Debug.Assert(label.GetLocation(geomIndex, Position.Left) == LocationType.None, "found single null side"); label.SetLocation(geomIndex, Position.Right, currLoc); label.SetLocation(geomIndex, Position.Left, currLoc); } } } }
public virtual void ComputeLabelling(GeometryGraph[] geom) { ComputeEdgeEndLabels(); // Propagate side labels around the edges in the star // for each parent Geometry PropagateSideLabels(0); PropagateSideLabels(1); // If there are edges that still have null labels for a geometry // this must be because there are no area edges for that geometry incident on this node. // In this case, to label the edge for that geometry we must test whether the // edge is in the interior of the geometry. // To do this it suffices to determine whether the node for the edge is in the interior of an area. // If so, the edge has location INTERIOR for the geometry. // In all other cases (e.g. the node is on a line, on a point, or not on the geometry at all) the edge // has the location EXTERIOR for the geometry. // <p> // Note that the edge cannot be on the BOUNDARY of the geometry, since then // there would have been a parallel edge from the Geometry at this node also labelled BOUNDARY // and this edge would have been labelled in the previous step. // <p> // This code causes a problem when dimensional collapses are present, since it may try and // determine the location of a node where a dimensional collapse has occurred. // The point should be considered to be on the EXTERIOR // of the polygon, but Locate() will return INTERIOR, since it is passed // the original Geometry, not the collapsed version. // // If there are incident edges which are Line edges labelled BOUNDARY, // then they must be edges resulting from dimensional collapses. // In this case the other edges can be labelled EXTERIOR for this Geometry. // // MD 8/11/01 - NOT TRUE! The collapsed edges may in fact be in the interior of the Geometry, // which means the other edges should be labelled INTERIOR for this Geometry. // Not sure how solve this... Possibly labelling needs to be split into several phases: // area label propagation, symLabel merging, then finally null label resolution. bool[] hasDimensionalCollapseEdge = new bool[] { false, false }; for (IEnumerator it = Iterator(); it.MoveNext();) { EdgeEnd e = (EdgeEnd)it.Current; Label label = e.Label; for (int geomi = 0; geomi < 2; geomi++) { if (label.IsLine(geomi) && label.GetLocation(geomi) == LocationType.Boundary) { hasDimensionalCollapseEdge[geomi] = true; } } } for (IEnumerator it = Iterator(); it.MoveNext();) { EdgeEnd e = (EdgeEnd)it.Current; Label label = e.Label; for (int geomi = 0; geomi < 2; geomi++) { if (label.IsAnyNull(geomi)) { int loc = LocationType.None; if (hasDimensionalCollapseEdge[geomi]) { loc = LocationType.Exterior; } else { Coordinate p = e.Coordinate; loc = GetLocation(geomi, p, geom); } label.SetAllLocationsIfNull(geomi, loc); } } } }
/// <summary> Insert a EdgeEnd into this EdgeEndStar</summary> public abstract void Insert(EdgeEnd e);
/// <summary> Add the edge to the list of edges at this node</summary> public void Add(EdgeEnd e) { // Assert: start pt of e is equal to node point m_objEdges.Insert(e); e.Node = this; }
public int CompareTo(object obj) { EdgeEnd e = (EdgeEnd)obj; return(CompareDirection(e)); }
/// <summary> Insert a directed edge in the list</summary> public override void Insert(EdgeEnd ee) { DirectedEdge de = (DirectedEdge)ee; InsertEdgeEnd(de, de); }