/// <summary> /// Sort the half edges. /// </summary> private int SortHalfEdges(HalfEdge a, HalfEdge b) { double r = b.Angle - a.Angle; if (r < 0) { return -1; } if (r > 0) { return 1; } return 0; }
/// <summary> /// Close cells. /// </summary> private void CloseCells() { // Prune and order the halfedges, then add missing halfedges in order to close the cells. for (int intCell = this.Cells.Count; intCell > 0; intCell--) { // Grab the cell object. Cell objCell = this.Cells[intCell]; // Prepare the cell by pruning and ordering the halfedges. objCell.PrepareHalfEdges(); // close open cells // step 1: find first 'unclosed' point, if any. // an 'unclosed' point will be the end point of a halfedge which // does not match the start point of the following halfedge int intHalfEdges = objCell.HalfEdges.Count; int intLeft = 0; while (intLeft < intHalfEdges) { int intRight = (intLeft + 1) % intHalfEdges; Point objEnd = objCell.HalfEdges[intLeft].GetEndPoint(); Point objStart = objCell.HalfEdges[intRight].GetStartPoint(); // if end point is not equal to start point, we need to add the missing halfedge(s) to close the cell if ((Math.Abs(objEnd.x - objStart.x) >= Polygons.Epsilon || Math.Abs(objEnd.y - objStart.y) >= Polygons.Epsilon)) { // if we reach this point, cell needs to be closed by walking counterclockwise along the bounding box until it connects to next halfedge in the list Point objVertexA = objEnd; double x; double y; Point objVertexB = null; // walk downward along left side if (this.EqualWithEpsilon(objEnd.x, this.Box.xl) && this.LessThanWithEpsilon(objEnd.y, this.Box.yb)) { x = this.Box.xl; y = this.EqualWithEpsilon(objStart.x, this.Box.xl) ? objStart.y : this.Box.yb; objVertexB = this.CreateEdgeVertex(x, y); } // walk rightward along bottom side else if (this.EqualWithEpsilon(objEnd.y, this.Box.yb) && this.LessThanWithEpsilon(objEnd.x, this.Box.xr)) { x = this.EqualWithEpsilon(objStart.y, this.Box.yb) ? objStart.x : this.Box.xr; y = this.Box.yb; objVertexB = this.CreateEdgeVertex(x, y); } // walk upward along right side else if (this.EqualWithEpsilon(objEnd.x, this.Box.xr) && this.GreaterThanWithEpsilon(objEnd.y, this.Box.yt)) { x = this.Box.xr; y = this.EqualWithEpsilon(objStart.x, this.Box.xr) ? objStart.y : this.Box.yt; objVertexB = this.CreateEdgeVertex(x, y); } // walk leftward along top side else if (this.EqualWithEpsilon(objEnd.y, this.Box.yt) && this.GreaterThanWithEpsilon(objEnd.x, this.Box.xl)) { x = this.EqualWithEpsilon(objStart.y, this.Box.yt) ? objStart.x : this.Box.xl; y = this.Box.yt; objVertexB = this.CreateEdgeVertex(x, y); } // Create a new half edge. HalfEdge objHalfEdge = new HalfEdge(this.CreateBorderEdge(objCell.Site, objVertexA, objVertexB), objCell.Site, null); objCell.HalfEdges.Insert(intLeft + 1, objHalfEdge); intHalfEdges = objCell.HalfEdges.Count; } if (intLeft > 100) { // Clearly something is going awfully wrong. What site is causing this problem? throw new Exception("CloseCells: Trouble with seed " + this.Seed + ". Site (" + objCell.Site.ID.ToString() + ") " + objCell.Site.ToString() + "."); } intLeft++; } } }