public void TestRemoveLeaf() { var beachLine = new BeachLine(0); var site1 = new Point { X = 40, Y = 60 }; var site2 = new Point { X = 20, Y = 40 }; var site3 = new Point { X = 60, Y = 40 }; beachLine.InsertSite(site1); beachLine.InsertSite(site2); var insert = beachLine.InsertSite(site3); var circleEvents = beachLine.GenerateCircleEvent(insert.Leaves, site3.Y); var circleEvent = circleEvents.Single(); beachLine.RemoveLeaf(circleEvent.Arc); var rightSubtree = ((Node)beachLine.Root).Right as Node; var leafLeft = rightSubtree.Left as Leaf; var leafRight = rightSubtree.Right as Leaf; Assert.IsNotNull(leafLeft); Assert.IsNotNull(leafRight); Assert.AreEqual(rightSubtree.Breakpoint.Left, site3); Assert.AreEqual(rightSubtree.Breakpoint.Right, site1); Assert.AreEqual(leafLeft.Site, site3); Assert.AreEqual(leafRight.Site, site1); }
public void TestFindCircleEventAbove() { var beachLine = new BeachLine(0); var site1 = new Point { X = 130, Y = 160 }; var site2 = new Point { X = 110, Y = 150 }; var site3 = new Point { X = 170, Y = 140 }; var site4 = new Point { X = 140, Y = 120 }; beachLine.InsertSite(site1); //beachLine.GenerateCircleEvent(site1); beachLine.InsertSite(site2); //beachLine.GenerateCircleEvent(site2); var insert = beachLine.InsertSite(site3); var circleEvents = beachLine.GenerateCircleEvent(insert.Leaves, site3.Y); var result = beachLine.FindCircleEventAbove(site4); Assert.IsNotNull(result); Assert.AreEqual(circleEvents.Single().Point, result.Point); }
public void TestGenerateCircleEvent() { var beachLine = new BeachLine(0); var site1 = new Point { X = 130, Y = 160 }; var site2 = new Point { X = 110, Y = 150 }; var site3 = new Point { X = 170, Y = 140 }; beachLine.InsertSite(site1); beachLine.InsertSite(site2); var insert = beachLine.InsertSite(site3); var expectedCricleEvent = new Point { X = 136, Y = 84 }; var result = beachLine.GenerateCircleEvent(insert.Leaves, site3.Y); Assert.IsNotNull(result); Assert.AreEqual(1, result.Count); Assert.AreEqual(expectedCricleEvent.XInt, result.Single().Point.XInt); Assert.AreEqual(expectedCricleEvent.YInt, result.Single().Point.YInt); //Assert.AreEqual(site2, result.Single().LeftArc.Site); Assert.AreEqual(site1, result.Single().Arc.Site); //Assert.AreEqual(site3, result.Single().RightArc.Site); }
public void TestGenerateCircleEventZeroLengthArc() { var beachLine = new BeachLine(2000); var site1 = new Point { X = 40, Y = 60 }; var site2 = new Point { X = 20, Y = 40 }; var site3 = new Point { X = 60, Y = 40 }; beachLine.InsertSite(site1); beachLine.InsertSite(site2); var insert = beachLine.InsertSite(site3); var expectedCricleEvent = new Point { X = 40, Y = 20 }; var result = beachLine.GenerateCircleEvent(insert.Leaves, site3.Y); Assert.IsNotNull(result); Assert.AreEqual(1, result.Count); Assert.AreEqual(expectedCricleEvent, result.Single().Point); //Assert.AreEqual(site2, result.Single().LeftArc.Site); Assert.AreEqual(site1, result.Single().Arc.Site); //Assert.AreEqual(site3, result.Single().RightArc.Site); }
public ICollection <IGeometry> HandleEvent(SiteEvent sweepEvent, EventQueue eventQueue, BeachLine beachLine) { var circleEvent = beachLine.FindCircleEventAbove(sweepEvent.Point); if (circleEvent != null) { Logger.Instance.Log($"SiteEvent: {sweepEvent.Point.ToString()}: Remove CircleEvent {circleEvent.Point} from queue."); eventQueue.Remove(circleEvent); } Logger.Instance.Log($"SiteEvent: {sweepEvent.Point.ToString()}: Insert site into beach line"); var result = beachLine.InsertSite(sweepEvent.Point); var circleEvents = beachLine.GenerateCircleEvent(result?.Leaves, sweepEvent.Point.Y); eventQueue.Insert(circleEvents); if (result != null) { return new List <IGeometry> { result.HalfEdge } } ; return(new List <IGeometry>()); } }
public ICollection <IGeometry> HandleEvent(CircleEvent sweepEvent, EventQueue eventQueue, BeachLine beachLine) { if (sweepEvent.Arc.Parent == null) { throw new InvalidOperationException($"CircleEvent: Arc {sweepEvent.Arc.Site}: Parent of node {0} is null"); } var leftParent = sweepEvent.Arc.GetParent(TraverseDirection.CounterClockwise); var rightParent = sweepEvent.Arc.GetParent(TraverseDirection.Clockwise); var left = leftParent?.GetLeaf(TraverseDirection.CounterClockwise); var right = rightParent?.GetLeaf(TraverseDirection.Clockwise); if (left == null || right == null) { throw new InvalidOperationException($"Neighbor of node {sweepEvent.Arc.Site} is null."); } if (left.CircleEvent != null) { eventQueue.Remove(left.CircleEvent); left.CircleEvent = null; } if (right.CircleEvent != null) { eventQueue.Remove(right.CircleEvent); right.CircleEvent = null; } var p = new Point(sweepEvent.Point.X, _calculationService.GetY(sweepEvent.Arc.Site, sweepEvent.Point)); leftParent.HalfEdge.EndPoint = p; rightParent.HalfEdge.EndPoint = p; var vertex = new Vertex { Point = p }; ConnectHalfEdgeWithVertex(leftParent.HalfEdge, vertex, (e, v) => e.End = v); ConnectHalfEdgeWithVertex(rightParent.HalfEdge, vertex, (e, v) => e.End = v); // Add third half edge var halfEdge = new HalfEdge(p, left.Site, right.Site); ConnectHalfEdgeWithVertex(halfEdge, vertex, (e, v) => e.Start = v); Logger.Instance.Log($"Left parent: {leftParent.HalfEdge}"); Logger.Instance.Log($"Right parent: {rightParent.HalfEdge}"); var higher = sweepEvent.Arc.GetFirstParent(leftParent, rightParent); Logger.Instance.Log($"Higher node: {higher}"); Logger.Instance.Log($"Higher edge old: {higher.HalfEdge}"); higher.HalfEdge = halfEdge; if (vertex.HalfEdges.Count != 3) { var message = $"Halfedge {halfEdge} is already connected to Vertex {vertex}"; Logger.Instance.Log(message); Logger.Instance.ToFile(); throw new InvalidOperationException(message); } Logger.Instance.Log($"CircleEvent: Remove Arc {sweepEvent.Arc.Site}"); beachLine.RemoveLeaf(sweepEvent.Arc); var circleEvents = beachLine.GenerateCircleEvent(new[] { left, right }, sweepEvent.Point.Y); eventQueue.Insert(circleEvents); return(new List <IGeometry> { vertex, halfEdge }); }