//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Compare edges clockwise around this vertex. </summary> /// <remarks> Darrellp, 2/19/2011. </remarks> /// <param name="e1"> The first WeEdge. </param> /// <param name="e2"> The second WeEdge. </param> /// <returns> +1 if they are CW around the generator, -1 if they're CCW, 0 if neither. </returns> //////////////////////////////////////////////////////////////////////////////////////////////////// private int CompareEdges(WeEdge e1, WeEdge e2) { // Compare edges for clockwise order var fe1 = (FortuneEdge)e1; var fe2 = (FortuneEdge)e2; return(Geometry2D.ICompareCw(Pt, fe1.PolyOrderingTestPoint, fe2.PolyOrderingTestPoint)); }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Return the point at the other end of the given edge. If the opposite point is a point at /// infinity, a "real" point on that edge is created and returned. /// </summary> /// <remarks> Darrellp, 2/19/2011. </remarks> /// <param name="edge"> Edge to traverse. </param> /// <returns> The point at the opposite end of the edge. </returns> //////////////////////////////////////////////////////////////////////////////////////////////////// private Vector PtAtOtherEnd(WeEdge edge) { // Get the vertex at the other end var ptRet = VtxOtherEnd(edge).Pt; // If it's at infinity if (edge.VtxEnd.FAtInfinity) { // Produce a "real" point ptRet = new Vector(Pt.X + ptRet.X, Pt.Y + ptRet.Y); } // Return the result return(ptRet); }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Compare two edges based on their cw order around a common generator. </summary> /// <remarks> /// It is an error to compare edges which do not have a common generator so this is only a /// "partial" comparer which is probably strictly verboten according to C# rules, but we have to /// do it in order to use the framework Sort routine to sort edges around a generator. /// Darrellp, 2/19/2011. /// </remarks> /// <param name="edgeIn"> Edge to compare. </param> /// <returns> Comparison output. </returns> //////////////////////////////////////////////////////////////////////////////////////////////////// internal override int CompareToVirtual(WeEdge edgeIn) { // Get our fortune edge var edge = edgeIn as FortuneEdge; // If they're identical if (ReferenceEquals(edgeIn, this)) { return(0); } // Return the "clockwisedness" of the generator and points on the two edges. // ReSharper disable once PossibleNullReferenceException return(ICompareCw(PolyCommon(edge).VoronoiPoint, PolyOrderingTestPoint, edge.PolyOrderingTestPoint)); }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Ensure that all edges connect to each other. </summary> /// <remarks> Darrellp, 2/18/2011. </remarks> /// <returns> True if all edges connect in order, else false. </returns> //////////////////////////////////////////////////////////////////////////////////////////////////// internal bool FValidateEdgesInOrder() { // If it's a single infinite polygon if (!Edges.Any()) { // There are no edges so skip this check return(true); } // Declarations var fFirstTimeThroughLoop = true; var edgePrev = new WeEdge(); var edgeFirst = new WeEdge(); // For each edge in the polygon foreach (var edgeCur in Edges) { if (fFirstTimeThroughLoop) { // Initialize fFirstTimeThroughLoop = false; edgePrev = edgeFirst = edgeCur; } else { // If this edge doesn't connect to the previous one if (!edgeCur.FConnectsToEdge(edgePrev)) { // there is a problem return(Failure()); } edgePrev = edgeCur; } } // Make sure the last edge cycles back to the first one return(edgePrev.FConnectsToEdge(edgeFirst) || Failure()); }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Ensure that a given edge is adjacent to this polygon. </summary> /// <remarks> Darrellp, 2/18/2011. </remarks> /// <param name="edge"> Edge to be checked. </param> /// <returns> True if the edge is adjacent, else false. </returns> //////////////////////////////////////////////////////////////////////////////////////////////////// internal bool FValidateEdgeIsAdjacent(WeEdge edge) { return(edge.PolyLeft == this || edge.PolyRight == this); }
internal OrientedEdge(WeEdge edge, bool fForward) { Forward = fForward; Edge = edge; }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> /// Add an edge at infinity and step the polygon and edge along to the next infinite polygon and /// rayed edge. /// </summary> /// <remarks> Darrellp, 2/18/2011. </remarks> /// <param name="polyAtInfinity"> Polygon at infinity. </param> /// <param name="poly"> Infinite polygon we're adding the edge to. </param> /// <param name="iLeadingEdgeCw"> index to rayed edge we start with. </param> /// <param name="edgePreviousAtInfinity"> /// Edge at infinity we added in the previous infinite /// polygon. /// </param> /// <param name="polyNextCcw"> /// [out] Returns the next infinite polygon to be /// processed. /// </param> /// <param name="iLeadingEdgeNext"> [out] Returns the next infinite edge. </param> /// <returns> . </returns> //////////////////////////////////////////////////////////////////////////////////////////////////// private static FortuneEdge AddEdgeAtInfinity( FortunePoly polyAtInfinity, FortunePoly poly, int iLeadingEdgeCw, WeEdge edgePreviousAtInfinity, out FortunePoly polyNextCcw, out int iLeadingEdgeNext) { // Get the other infinite edge // // This is the edge to the right as we look outward var iTrailingEdgeCw = (iLeadingEdgeCw + 1) % poly.VertexCount; var edgeLeadingCw = poly.FortuneEdges[iLeadingEdgeCw]; var edgeTrailingCw = poly.FortuneEdges[iTrailingEdgeCw]; // Next polygon in order is to the left of our leading edge polyNextCcw = edgeLeadingCw.PolyLeft as FortunePoly; // Create the edge at infinity // // Create the edge at infinity separating the current infinite polygon from // the polygon at infinity. The vertices for this edge will both be vertices // at infinity. This, of course, doesn't really have any real impact on the // "position" of the edge at infinity, but allows us to maintain a properly // set up winged edge structure. var edgeAtInfinity = new FortuneEdge { PolyRight = poly, PolyLeft = polyAtInfinity, VtxStart = edgeLeadingCw.VtxEnd, VtxEnd = edgeTrailingCw.VtxEnd }; // The poly at infinity is to the left of the edge, the infinite poly is to its right // // Start and end vertices are the trailing and leading infinite edges // Add the edge at infinity to the poly at infinity and the current infinite poly polyAtInfinity.AddEdge(edgeAtInfinity); poly.FortuneEdges.Insert(iTrailingEdgeCw, edgeAtInfinity); // Set up the wings of the wingedEdge edgeAtInfinity.EdgeCWPredecessor = edgeLeadingCw; edgeAtInfinity.EdgeCCWSuccessor = edgeTrailingCw; edgeLeadingCw.EdgeCCWSuccessor = edgeAtInfinity; edgeTrailingCw.EdgeCWSuccessor = edgeAtInfinity; // If we've got a previous edge at infinity if (edgePreviousAtInfinity != null) { // Incorporate it properly edgePreviousAtInfinity.EdgeCCWPredecessor = edgeAtInfinity; edgeAtInfinity.EdgeCWSuccessor = edgePreviousAtInfinity; } // Hook up our edge at infinity to our vertices at infinity HookEdgeAtInfinityToVerticesAtInfinity( edgeAtInfinity, edgeAtInfinity.VtxStart as FortuneVertex, edgeAtInfinity.VtxEnd as FortuneVertex); // Locate the leading edge index in the next polygon // For each Edge of the infinite polygon to our left // ReSharper disable once PossibleNullReferenceException for (iLeadingEdgeNext = 0; iLeadingEdgeNext < polyNextCcw.VertexCount; iLeadingEdgeNext++) { // If it's the same as our leading CW infinite edge if (polyNextCcw.FortuneEdges[iLeadingEdgeNext] == edgeLeadingCw) { // then their leading edge is the one immediately preceding it in CW order iLeadingEdgeNext = (polyNextCcw.VertexCount + iLeadingEdgeNext - 1) % polyNextCcw.VertexCount; break; } } // Return the edge at infinity we've created return(edgeAtInfinity); }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Find the vertex on the other end of an edge. </summary> /// <remarks> Darrellp, 2/18/2011. </remarks> /// <param name="edge"> Edge to check. </param> /// <returns> Vertex at the other end of the edge. </returns> //////////////////////////////////////////////////////////////////////////////////////////////////// public WeVertex VtxOtherEnd(WeEdge edge) { // If we're the start vertex, then return the end and vice verse. return(ReferenceEquals(edge.VtxStart, this) ? edge.VtxEnd : edge.VtxStart); }
//////////////////////////////////////////////////////////////////////////////////////////////////// /// <summary> Ensure that the passed in edge is adjacent to this vertex. </summary> /// <remarks> Darrellp, 2/18/2011. </remarks> /// <param name="edge"> Edge to check. </param> /// <returns> True if the edge is adjacent, else false. </returns> //////////////////////////////////////////////////////////////////////////////////////////////////// internal bool FValidateEdgeIsAdjacent(WeEdge edge) { return(Edges.Any(edgeCur => ReferenceEquals(edgeCur, edge))); }