//worst case O(n) public Hull combine(Hull left, Hull right) { //extract lists from hulls List <PointF> l = left.getList(); List <PointF> r = right.getList(); //set booleans, they come in handy bool bothDone = false; bool rightDone = false; bool leftDone = false; //those 4 ints abreviate topleftindex,toprightindex,bottomleftindex,and bottomrightindex int tli = left.getRightIndex(); int tri = 0; int bli = left.getRightIndex(); int bri = 0; //find top edge, repeat this loop until no change in left or right index while (!bothDone) { bothDone = true; rightDone = false; leftDone = false; //move right index "up" until no advantage in slope change while (!rightDone) { int newIndex; if (tri == 0) { newIndex = r.Count() - 1; } else { newIndex = tri - 1; } if (slope(l[tli], r[tri]) > slope(l[tli], r[newIndex])) { tri = newIndex; bothDone = false; } else { rightDone = true; } } //move left index "up" until no advantage in slope change while (!leftDone) { int newIndex; if (tli == (l.Count() - 1)) { newIndex = 0; } else { newIndex = tli + 1; } if (slope(l[tli], r[tri]) < slope(l[newIndex], r[tri])) { tli = newIndex; bothDone = false; } else { leftDone = true; } } } bothDone = false; //find bottom edge, repeat this loop until no change in left or right index while (!bothDone) { bothDone = true; rightDone = false; leftDone = false; //move right index "down" until no advantage in slope change while (!rightDone) { if (bri == (r.Count() - 1)) { rightDone = true; } else { if (slope(l[bli], r[bri]) < slope(l[bli], r[bri + 1])) { bri++; bothDone = false; } else { rightDone = true; } } } //move left index "down" until no advantage in slope change while (!leftDone) { if (bli == 0) { leftDone = true; } else { if (slope(l[bli], r[bri]) > slope(l[bli - 1], r[bri])) { bli--; bothDone = false; } else { leftDone = true; } } } } //pass in the indeces we found return(getNewHull(bli, bri, tri, tli, right.getRightIndex(), l, r)); }
public Hull merge(Hull left, Hull right) { int rightMost = left.getRightMostIndex(); int leftMost = right.getLeftMostIndex(); int currentLeftIndex = rightMost; int currentRightIndex = leftMost; int upperLeft = -1; int upperRight = -1; int lowerLeft = -1; int lowerRight = -1; bool leftIndexChanged = false; bool rightIndexChanged = false; //iterate through at least once bool firstRight = true; bool firstLeft = true; //get upper common tangent while (leftIndexChanged || rightIndexChanged || firstLeft || firstRight) { if (firstRight || leftIndexChanged) { firstRight = false; upperRight = getRightUpper(left, right, currentLeftIndex, currentRightIndex); if (upperRight == currentRightIndex) { leftIndexChanged = false; rightIndexChanged = false; } else { rightIndexChanged = true; currentRightIndex = upperRight; } } if (firstLeft || rightIndexChanged) { firstLeft = false; upperLeft = getLeftUpper(left, right, currentLeftIndex, currentRightIndex); if (upperLeft == currentLeftIndex) { leftIndexChanged = false; rightIndexChanged = false; } else { leftIndexChanged = true; currentLeftIndex = upperLeft; } } } //get lower common tangentt currentLeftIndex = rightMost; currentRightIndex = leftMost; leftIndexChanged = false; rightIndexChanged = false; //iterate through at least once firstRight = true; firstLeft = true; while (leftIndexChanged || rightIndexChanged || firstLeft || firstRight) { if (firstLeft || rightIndexChanged) { firstLeft = false; lowerLeft = getLeftLower(left, right, currentLeftIndex, currentRightIndex); if (lowerLeft == currentLeftIndex) { leftIndexChanged = false; rightIndexChanged = false; } else { leftIndexChanged = true; currentLeftIndex = lowerLeft; } } if (firstRight || leftIndexChanged) { firstRight = false; lowerRight = getRightLower(left, right, currentLeftIndex, currentRightIndex); if (lowerRight == currentRightIndex) { leftIndexChanged = false; rightIndexChanged = false; } else { rightIndexChanged = true; currentRightIndex = lowerRight; } } } //join points List <PointF> resultPoints = new List <PointF>(); //add up to (and including) upperLeft for (int i = 0; i <= upperLeft; i++) { resultPoints.Add(left.getPoints()[i]); } //add up to lowerRight for (int i = upperRight; i != lowerRight; i = right.getNextIndex(i)) { resultPoints.Add(right.getPoints()[i]); } //add lowerRight resultPoints.Add(right.getPoints()[lowerRight]); //add from lowerLeft to beginning for (int i = lowerLeft; i != 0; i = left.getNextIndex(i)) { resultPoints.Add(left.getPoints()[i]); } return(new Hull(resultPoints)); }