public void FindMinTest() { CreateTree(); int val; Assert.IsTrue(m_tree.FindMin(out val)); Assert.AreEqual(-999, val); }
// Test program; should print min and max and nothing else public static void Main(string[] args) { AATree <int> t = new AATree <int>(-9999); const int NUMS = 40000; const int GAP = 307; Console.WriteLine("Checking... (no bad output means success)"); t.Insert(NUMS * 2); t.Insert(NUMS * 3); for (int i = GAP; i != 0; i = (i + GAP) % NUMS) { t.Insert(i); } Console.WriteLine("Inserts complete"); t.Remove(t.FindMax( )); for (int i = 1; i < NUMS; i += 2) { t.Remove(i); } t.Remove(t.FindMax( )); Console.WriteLine("Removes complete"); if (t.FindMin( ) != 2 || t.FindMax( ) != NUMS - 2) { Console.WriteLine("FindMin or FindMax error!"); } for (int i = 2; i < NUMS; i += 2) { if (t.Find(i) != i) { Console.WriteLine("Error: find fails for " + i); } } for (int i = 1; i < NUMS; i += 2) { if (t.Contains(i)) { Console.WriteLine("Error: Found deleted item " + i); } } }
public static Polygon2D Vision(Polygon2DWithHoles polygon, Vector2 x) { if (!(polygon.ContainsInside(x) || polygon.OnBoundary(x))) { throw new ArgumentException(x + " is not inside polygon: " + polygon); } float initAngle; var events = Preprocess(polygon, x, out initAngle); var status = new AATree <StatusItem>(); var visibility = new List <Vector2>(); // create ray in positive x direction var ray = new Ray2D(Vector2.zero, new Vector2(1f, 0f)); VisibilityEvent xEvent = null; // initialize the status foreach (var v in events) { if (MathUtil.EqualsEps(v.vertex, Vector2.zero)) { xEvent = v; continue; } var seg = v.item1.seg; if (!seg.IsEndpoint(x)) { var intersect = seg.Intersect(ray); if (intersect.HasValue && intersect.Value.x > 0 && (seg.Point1.y >= 0 != seg.Point2.y >= 0) && !MathUtil.EqualsEps(intersect.Value, Vector2.zero)) { status.Insert(v.item1); } } } if (xEvent != null) { if (!xEvent.isHole) { status.Insert(xEvent.item1); } else { status.Delete(xEvent.item1); } if (!xEvent.isHole) { status.Delete(xEvent.item2); } else { status.Insert(xEvent.item2); } if (!xEvent.isHole) { visibility.Add(xEvent.item2.seg.Point2); visibility.Add(Vector2.zero); visibility.Add(xEvent.item1.seg.Point1); } else { visibility.Add(xEvent.item2.seg.Point1); visibility.Add(Vector2.zero); visibility.Add(xEvent.item1.seg.Point2); } } // handle events StatusItem top = null; var insertions = new HashSet <StatusItem>(); if (status.Count > 0) { status.FindMin(out top); } for (var i = 0; i < events.Count; i++) { var v = events[i]; if (MathUtil.EqualsEps(v.vertex, Vector2.zero)) { continue; } ray = new Ray2D(Vector2.zero, v.vertex); // first handle deletions // handle first segment if (status.Contains(v.item1)) { status.Delete(v.item1); } else if (insertions.Contains(v.item1)) { insertions.Remove(v.item1); } else { insertions.Add(v.item1); } // handle second segment if (status.Contains(v.item2)) { status.Delete(v.item2); } else if (insertions.Contains(v.item2)) { insertions.Remove(v.item2); } else { insertions.Add(v.item2); } // skip if next event colinear with current if (i < events.Count - 1 && Line.Colinear(Vector2.zero, v.vertex, events[i + 1].vertex)) { // skip until all colinear events are handled continue; } // handle insertions (after potential skip for colinear events foreach (var item in insertions) { status.Insert(item); } insertions.Clear(); StatusItem newTop; status.FindMin(out newTop); // do stuff if current top different from previous if (top != newTop) { // add intersections with previous top segment if (top != null) { HandleTopSegment(ref visibility, top.seg, ray); } // add intersections with new top segment if (newTop != null) { HandleTopSegment(ref visibility, newTop.seg, ray); } top = newTop; } } return(Postprocess(visibility, x, initAngle)); }