public void CycleTest()
        {
            var dcel = new DCEL();
            var v1   = dcel.AddVertex(new DCELVertex(0, 0));
            var v2   = dcel.AddVertex(new DCELVertex(10, 10));
            var v3   = dcel.AddVertex(new DCELVertex(20, 0));
            var e1   = dcel.AddEdge(v1, v2);
            var e2   = dcel.AddEdge(v2, v3);
            var e3   = dcel.AddEdge(v3, v1);

            Assert.Contains(e1, DCEL.Cycle(e1));
            Assert.Contains(e2, DCEL.Cycle(e1));
            Assert.Contains(e3, DCEL.Cycle(e1));
            Assert.Contains(e1, DCEL.Cycle(e2));
            Assert.Contains(e2, DCEL.Cycle(e2));
            Assert.Contains(e3, DCEL.Cycle(e2));
            Assert.Contains(e1, DCEL.Cycle(e3));
            Assert.Contains(e2, DCEL.Cycle(e3));
            Assert.Contains(e3, DCEL.Cycle(e3));
        }
示例#2
0
        /// <summary>
        /// Returns a halfedge of the leftmost middle face.
        /// </summary>
        /// <param name="m_dcel"></param>
        /// <param name="m_dualLines"></param>
        /// <returns></returns>
        private static HalfEdge LeftMostMiddleHalfEdge(DCEL m_dcel, IEnumerable <Line> m_dualLines)
        {
            var bbox = m_dcel.InitBoundingBox.Value;

            // get all intersections with left line of bounding box
            var leftLine      = new Line(new Vector2(bbox.xMin, bbox.yMin), new Vector2(bbox.xMin, bbox.yMax));
            var intersections = m_dualLines
                                .Where(l => !l.IsVertical)
                                .Select(l => leftLine.Intersect(l).Value)
                                .ToList();

            // sort on y value
            intersections.Sort((v1, v2) => v1.y.CompareTo(v2.y));

            // find edge between middle intersections
            var middleIntersectBot = intersections[intersections.Count / 2 - 1];
            var middleIntersectTop = intersections[intersections.Count / 2];
            var edgeInterval       = new FloatInterval(middleIntersectBot.y, middleIntersectTop.y);

            // get corresponding halfedge in dcel
            HalfEdge workingEdge;

            if (bbox.yMin < edgeInterval.Min && bbox.yMax > edgeInterval.Max)
            {
                // both intersections contained on left segment of bounding box

                workingEdge = DCEL.Cycle(m_dcel.OuterFace.InnerComponents[0])
                              .FirstOrDefault(e => e.From.Pos.x == bbox.xMin &&
                                              edgeInterval.ContainsEpsilon(e.From.Pos.y) &&
                                              edgeInterval.ContainsEpsilon(e.To.Pos.y));
            }
            else if (bbox.yMin >= edgeInterval.Min)
            {
                // bottom intersection lies below left segment

                // find halfedge pointing to bottom left corner
                workingEdge = DCEL.Cycle(m_dcel.OuterFace.InnerComponents[0])
                              .FirstOrDefault(e => MathUtil.Equals(e.From.Pos, new Vector2(bbox.xMin, bbox.yMin)));

                // traverse outer cycle until we find line with the corresponding bottom intersection
                while (workingEdge.Twin.Prev.Segment.Line.IsVertical ||
                       !MathUtil.EqualsEps(workingEdge.Twin.Prev.Segment.Line.Intersect(leftLine).Value, middleIntersectBot))
                {
                    workingEdge = workingEdge.Next;
                }
            }
            else
            {
                // top intersection lies above left segment

                // find halfedge pointing away from top left corner
                workingEdge = DCEL.Cycle(m_dcel.OuterFace.InnerComponents[0])
                              .FirstOrDefault(e => MathUtil.Equals(e.To.Pos, new Vector2(bbox.xMin, bbox.yMax)));

                // traverse outer cycle until we find line with the corresponding top intersection
                while (workingEdge.Twin.Next.Segment.Line.IsVertical ||
                       !MathUtil.EqualsEps(workingEdge.Twin.Next.Segment.Line.Intersect(leftLine).Value, middleIntersectTop))
                {
                    workingEdge = workingEdge.Prev;
                }
            }

            // middle edge should always exist
            if (workingEdge == null)
            {
                throw new GeomException("working edge not found");
            }

            // return twin (edge of middle face, not outer face)
            return(workingEdge.Twin);
        }