public void FindCutLinesThreePointSetsTest()
        {
            var ret = HamSandwich.FindCutLines(m_points1, m_points2, m_points3);

            var expX = new FloatInterval(-1, 1);
            var expY = new FloatInterval(-2, 2);

            Assert.AreEqual(1, ret.Count);
            Assert.IsTrue(expX.ContainsEpsilon(ret[0].Slope));
            Assert.IsTrue(expY.ContainsEpsilon(ret[0].HeightAtYAxis));
        }
        public void FindCutlinesInDualThreeRegionsTest()
        {
            var faces1 = HamSandwich.MiddleFaces(m_dcel1, m_lines1);
            var faces2 = HamSandwich.MiddleFaces(m_dcel2, m_lines2);
            var faces3 = HamSandwich.MiddleFaces(m_dcel3, m_lines3);

            var ret = HamSandwich.FindCutlinesInDual(faces1, faces2, faces3);

            var expX = new FloatInterval(-1, 1);
            var expY = new FloatInterval(-2, 2);

            Assert.AreEqual(1, ret.Count);
            Assert.IsTrue(expX.ContainsEpsilon(ret[0].Slope));
            Assert.IsTrue(expY.ContainsEpsilon(ret[0].HeightAtYAxis));
        }
Beispiel #3
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);
        }