public void ClockwiseTangentMove(ref ConvexHull hull, ref TangentLine TLine, ref double slope, ref int slopeChangedCount, string TangentType) { bool slopeChanged = false; string LOWER_TANGENT = "LOWER_TANGENT"; do { int index; PointF pendingTanPoint; double pendingSlope; if (TangentType == LOWER_TANGENT) { //TangentLeftPoint will move to the next point in a CLOCKWISE direction float leftPointX = TLine.GetLeftPoint().X; index = hull.GetConvexHullPoints().FindIndex(p => p.X == leftPointX); //Start at the index, so to go CLOCKWISE we need to move next through the list int i = Next(hull.GetConvexHullPoints(), index); pendingTanPoint = hull.GetConvexHullPoints()[i]; pendingSlope = CalculateSlope(pendingTanPoint, TLine.GetRightPoint()); } else { //TangentRightPoint will move to the next point in a CLOCKWISE direction float rightPointX = TLine.GetRightPoint().X; index = hull.GetConvexHullPoints().FindIndex(p => p.X == rightPointX); //Start at the index, so to go CLOCKWISE we need to move next through the list int i = Next(hull.GetConvexHullPoints(), index); pendingTanPoint = hull.GetConvexHullPoints()[i]; pendingSlope = CalculateSlope(TLine.GetLeftPoint(), pendingTanPoint); } if (pendingSlope > slope) { //That's good, so now we can change the tangent line if (TangentType == LOWER_TANGENT) { TLine.SetLeftPoint(pendingTanPoint); } else { TLine.SetRightPoint(pendingTanPoint); } //And also update the slope slope = pendingSlope; //And the slope changed slopeChanged = true; slopeChangedCount++; } else { slopeChanged = false; } } while (slopeChanged); }
public ConvexHull FindConvexHull(List <PointF> points) { //Base Case int n = points.Count; if (n == 1) { return(new ConvexHull(points)); } //Recursion ConvexHull chLeft = null; ConvexHull chRight = null; if (n > 1) { int mid = (int)Math.Ceiling((double)points.Count / 2); List <PointF> lowerHalf = GetPointsWithinRange(0, mid, points); List <PointF> upperHalf = GetPointsWithinRange(mid, n, points); chLeft = FindConvexHull(lowerHalf); chRight = FindConvexHull(upperHalf); } //Make Tangent Lines //Rightmost X value of the Left Hull PointF tanPointLeft = GetPointFromHull("RIGHTMOST", chLeft); //Leftmost X value of the Right Hull PointF tanPointRight = GetPointFromHull("LEFTMOST", chRight); TangentLine upperTangent = new TangentLine(tanPointLeft, tanPointRight); TangentLine lowerTangent = new TangentLine(tanPointLeft, tanPointRight); //Record the slope of the tangent lines double slope = CalculateSlope(upperTangent.GetLeftPoint(), upperTangent.GetRightPoint()); bool thereCouldBeMoreChanges = false; //bool slopeChanged = false; //Major Loop (CONDITION) for UPPER TANGENT LINE do { int slopeChangedCount = 0; //UpperTanLeft Loop CounterClockwiseTangentMove(ref chLeft, ref upperTangent, ref slope, ref slopeChangedCount, "UPPER_TANGENT"); //UpperTanRight Loop ClockwiseTangentMove(ref chRight, ref upperTangent, ref slope, ref slopeChangedCount, "UPPER_TANGENT"); thereCouldBeMoreChanges = (slopeChangedCount > 0) ? true : false; } while (thereCouldBeMoreChanges); //Major Loop (CONDITION) for LOWER TANGENT LINE slope = CalculateSlope(lowerTangent.GetLeftPoint(), lowerTangent.GetRightPoint()); do { int slopeChangedCount = 0; //LowerTanLeft Loop ClockwiseTangentMove(ref chLeft, ref lowerTangent, ref slope, ref slopeChangedCount, "LOWER_TANGENT"); //LowerTanRight Loop CounterClockwiseTangentMove(ref chRight, ref lowerTangent, ref slope, ref slopeChangedCount, "LOWER_TANGENT"); thereCouldBeMoreChanges = (slopeChangedCount > 0) ? true : false; } while (thereCouldBeMoreChanges); return(MergeConvexHulls(chLeft, chRight, upperTangent, lowerTangent)); }
public ConvexHull MergeConvexHulls(ConvexHull hullLeft, ConvexHull hullRight, TangentLine upTan, TangentLine lowTan) { //Start at the upTan right point using the hullRight first because the upTan Right Point will be in the hullRight float upTanRightPointX = upTan.GetRightPoint().X; int index = hullRight.GetConvexHullPoints().FindIndex(p => p.X == upTanRightPointX); //Make a new convexHull that will contain the merged hulls ConvexHull mergedHull = new ConvexHull(upTan.GetRightPoint()); //Move clockwise until we get to lowTan right point PointF nextPoint; bool sameIndexWasReturned = false; //If the starting point isn't already the lowertangent right point, then do the loop if (upTan.GetRightPoint().X != lowTan.GetRightPoint().X) { do { int i = Next(hullRight.GetConvexHullPoints(), index, ref sameIndexWasReturned); nextPoint = hullRight.GetConvexHullPoints()[i]; //Add the nextPoint into the mergedHull if (!sameIndexWasReturned) { mergedHull.AddPoint(nextPoint); } //Update index index = i; } while (nextPoint.X != lowTan.GetRightPoint().X); } //If we are right here, that means that the last point just added, was the Lower Tangent Right Point. //Now we want to add the Lower Tangent Left Point, and start iterating up CLOCKWISE the leftHull until we reach the point that is equal to the Upper Tangent Left Point. nextPoint = lowTan.GetLeftPoint(); mergedHull.AddPoint(nextPoint); float lowTanLeftPointX = lowTan.GetLeftPoint().X; index = hullLeft.GetConvexHullPoints().FindIndex(p => p.X == lowTanLeftPointX); //If the lowertanget left point isn't already the upper tangent left point, then do the loop. if (lowTan.GetLeftPoint().X != upTan.GetLeftPoint().X) { sameIndexWasReturned = false; do { int i = Next(hullLeft.GetConvexHullPoints(), index, ref sameIndexWasReturned); nextPoint = hullLeft.GetConvexHullPoints()[i]; //Add the nextPoint into the mergedHull if (!sameIndexWasReturned) { mergedHull.AddPoint(nextPoint); } //Update index index = i; } while (nextPoint.X != upTan.GetLeftPoint().X); } //Once we reach here that means that last point added was the Upper Left Tangent Point, which is the last one we need to add for a complete hull. return(mergedHull); }