Beispiel #1
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <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));
        }
Beispiel #2
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <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);
        }
Beispiel #3
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <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));
        }
Beispiel #4
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <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());
        }
Beispiel #5
0
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 /// <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);
 }
Beispiel #6
0
 internal OrientedEdge(WeEdge edge, bool fForward)
 {
     Forward = fForward;
     Edge    = edge;
 }
Beispiel #7
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <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);
        }
Beispiel #8
0
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 /// <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);
 }
Beispiel #9
0
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 /// <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)));
 }