/// <summary>
/// Check if the specified set of points form a circle shape.
/// </summary>
///
/// <param name="edgePoints">Shape's points to check.</param>
/// <param name="center">Receives circle's center on successful return.</param>
/// <param name="radius">Receives circle's radius on successful return.</param>
///
/// <returns>Returns <see langword="true"/> if the specified set of points form a
/// circle shape or <see langword="false"/> otherwise.</returns>
///
/// <remarks><para><note>Circle shape must contain at least 8 points to be recognized.
/// The method returns <see langword="false"/> always, of number of points in the specified
/// shape is less than 8.</note></para></remarks>
///
public bool IsCircle(List <IntPoint> edgePoints, out Point center, out float radius)
{
// make sure we have at least 8 points for curcle shape
if (edgePoints.Count < 8)
{
center = new Point(0, 0);
radius = 0;
return(false);
}
// get bounding rectangle of the points list
IntPoint minXY, maxXY;
PointsCloud.GetBoundingRectangle(edgePoints, out minXY, out maxXY);
// get cloud's size
IntPoint cloudSize = maxXY - minXY;
// calculate center point
center = minXY + (Point)cloudSize / 2;
radius = ((float)cloudSize.X + cloudSize.Y) / 4;
// calculate mean distance between provided edge points and estimated circle’s edge
float meanDistance = 0;
for (int i = 0, n = edgePoints.Count; i < n; i++)
{
meanDistance += (float)Math.Abs(center.DistanceTo(edgePoints[i]) - radius);
}
meanDistance /= edgePoints.Count;
float maxDitance = Math.Max(minAcceptableDistortion,
((float)cloudSize.X + cloudSize.Y) / 2 * relativeDistortionLimit);
return(meanDistance <= maxDitance);
}