public PointList Merge(PointList lhs, PointList rhs) { // the base case PointList p = null; if (lhs.Length == 1 && rhs.Length == 1) { p = new PointList(lhs, rhs); return(p); } // finding the top connecting nodes /* * O(n) because you will visit each node a maximum of one time within the while loop * (with the possible exception of the first node checked, which may get visited twice, at most) * where n is the number of nodes given before they are split in the Divide function */ // Finding the rightmost of the lhs and the leftmost of the rhs are a combined O(n) PointF lpt_top = lhs.Rightmost(), rpt_top = rhs.Leftmost(); PointF current; bool changed = true; bool growing = true; while (changed) { changed = false; growing = true; while (growing) { current = lhs.prev(); if (Slope(current, rpt_top) > Slope(lpt_top, rpt_top)) { lpt_top = current; changed = true; } else { growing = false; lhs.next(); } } growing = true; while (growing) { current = rhs.next(); if (Slope(lpt_top, current) < Slope(lpt_top, rpt_top)) { rpt_top = current; changed = true; } else { growing = false; rhs.prev(); } } } // finding the bottom connecting nodes /* * O(n) because you will visit each node a maximum of one time within the while loop * (with the possible exception of the first node checked, which may get visited twice, at most) * where n is the number of nodes given before they are split in the Divide function */ // Finding the rightmost of the lhs and the leftmost of the rhs are a combined O(n) PointF lpt_bot = lhs.Rightmost(), rpt_bot = rhs.Leftmost(); changed = true; growing = true; while (changed) { changed = false; growing = true; while (growing) { current = lhs.next(); if (Slope(current, rpt_bot) < Slope(lpt_bot, rpt_bot)) { lpt_bot = current; changed = true; } else { growing = false; lhs.prev(); } } growing = true; while (growing) { current = rhs.prev(); if (Slope(lpt_bot, current) > Slope(lpt_bot, rpt_bot)) { rpt_bot = current; changed = true; } else { growing = false; rhs.next(); } } } // forming the new list with only the convex hull nodes /* * O(n) because you might have to add all n nodes from the lhs and rhs * bounding lists to the new bounding list. * Usually this will only be a fraction of the actual number of nodes given to Divide() */ List <PointF> list = new List <PointF>(); growing = true; current = lpt_bot; lhs.SetIndex(lpt_bot); while (growing) { if (current == lpt_top) { growing = false; } list.Add(current); current = lhs.next(); } growing = true; current = rpt_top; rhs.SetIndex(rpt_top); while (growing) { if (current == rpt_bot) { growing = false; } list.Add(current); current = rhs.next(); } p = new PointList(list); return(p); // Total Time: O(5n) = O(n) // Total Space: O(n) for the new list allocated at the end }
public PointList Merge(PointList lhs, PointList rhs) { // the base case if (lhs.Length == 1 || rhs.Length == 1) { return(new PointList(lhs, rhs)); } // finding the top connecting nodes PointF lpt_top = lhs.Rightmost(), rpt_top = rhs.Leftmost(); PointF current; bool changed = true; bool growing = true; while (changed) { changed = false; growing = true; while (growing) { current = lhs.prev(); if (Slope(current, rpt_top) > Slope(lpt_top, rpt_top)) { lpt_top = current; changed = true; } else { growing = false; lhs.next(); } } growing = true; while (growing) { current = rhs.next(); if (Slope(lpt_top, current) < Slope(lpt_top, rpt_top)) { rpt_top = current; changed = true; } else { growing = false; rhs.prev(); } } } // finding the bottom connecting nodes PointF lpt_bot = lhs.Rightmost(), rpt_bot = rhs.Leftmost(); bool changed = true; bool growing = true; while (changed) { changed = false; growing = true; while (growing) { current = lhs.next(); if (Slope(current, rpt_bot) < Slope(lpt_bot, rpt_bot)) { lpt_bot = current; changed = true; } else { growing = false; lhs.prev(); } } growing = true; while (growing) { current = rhs.prev(); if (Slope(lpt_bot, current) > Slope(lpt_bot, rpt_bot)) { rpt_bot = current; changed = true; } else { growing = false; rhs.next(); } } } // forming the new list with only the convex hull nodes List <PointF> list = new List <>(); growing = true; current = lpt_bot; lhs.SetIndex(lpt_bot); while (growing) { if (current == lpt_top) { growing = false; } list.Add(current); current = lhs.next(); } growing = true; current = rpt_top; rhs.SetIndex(rpt_top); while (growing) { if (current == rpt_bot) { growing = false; } list.Add(current); current = rhs.next(); } return(new PointList(list)); }
public PointList(PointList pts1, PointList pts2) { points = new PointF[pts1.Length + pts2.Length]; Array.Copy(pts1.points, 0, points, 0, pts1.Length); Array.Copy(pts2.points, 0, points, pts1.Length, pts1.Length + pts2.Length); }