/// <summary> /// Gets the points that are furthest apart. /// </summary> /// <param name="nIndx1">Ouput. The first index.</param> /// <param name="nIndx2">Ouput. The second index.</param> /// <param name="dDist">Ouput. The distance.</param> public void GetExtremePoints(ref int nIndx1, ref int nIndx2, ref double dDist) { // First take a guess at them. GetExtremePointsEst(ref nIndx1, ref nIndx2, ref dDist, 0); // Set up a circle to bound the 2 guesses. C2DVector Vec = new C2DVector(this[nIndx1], this[nIndx2]); Vec.Multiply(0.5); C2DCircle Circle = new C2DCircle(this[nIndx1] + new C2DPoint(Vec), dDist / 2); // Now, if the guess was wrong, there must be a point outside the circle which is part of // the right solution. Go through all these, check and reset the result each time. for (int i = 0; i < Count; i++) { if (i != nIndx1 && i != nIndx2) { if (!Circle.Contains(this[i])) { double dDistCheck = 0; int nCheck1 = GetFurthestPoint(i, ref dDistCheck); if (dDistCheck > dDist) { nIndx1 = i; nIndx2 = nCheck1; dDist = dDistCheck; } } } } }
/// <summary> /// Gets the minimum bounding circle. /// </summary> /// <param name="Circle">Ouput. The Circle.</param> public void GetBoundingCircle(C2DCircle Circle) { if (this.Count < 3) { if (this.Count == 2) { Circle.SetMinimum(this[0], this[1]); } else if (this.Count == 1) { Circle.Set(this[0], 0); } else { Debug.Assert(false, "Point set with no points. Cannot calculate bounding circle."); } return; } int nIndx1 = 0; int nIndx2 = 0;; int nIndx3 = 0;; double dDist = 0;; // First get the points that are furthest away from each other. GetExtremePoints(ref nIndx1, ref nIndx2, ref dDist); // Set the circle to bound these. Circle.SetMinimum(this[nIndx1], this[nIndx2]); // Set up a flag to show if we are circumscibed. (Once we are, we always will be). bool bCircum = false; // Cycle through and if any points aren't in the circle, then set the circle to be circumscribed. for (int i = 0; i < Count; i++) { if (i != nIndx1 && i != nIndx2) { if (!Circle.Contains(this[i])) { nIndx3 = i; Circle.SetCircumscribed(this[nIndx1], this[nIndx2], this[nIndx3]); bCircum = true; // Break out and try again. break; } } } // If we didn't succeed first time then go through again setting it to be circumscribed every time. if (bCircum) { for (int i = 0; i < Count; i++) { if (i != nIndx1 && i != nIndx2 && i != nIndx3) { if (!Circle.Contains(this[i])) { double Dist1 = this[i].Distance(this[nIndx1]); double Dist2 = this[i].Distance(this[nIndx2]); double Dist3 = this[i].Distance(this[nIndx3]); if (Dist1 < Dist2 && Dist1 < Dist3) { // Closest to point 1 so elimitate this nIndx1 = i; } else if (Dist2 < Dist3) { // Closest to point 2 so elimitate this nIndx2 = i; } else { // Closest to point 3 so elimitate this nIndx3 = i; } Circle.SetCircumscribed(this[nIndx1], this[nIndx2], this[nIndx3]); } } } } }