Here's a simple method, with a working implementation I threw together.
http://jsfiddle.net/kBsdW/29/
- Loop through the points
- Find a second point with the maximum distance from the first
- Record the distance
- Once you have all of the max distances average them and calculate the error tolerance
- Check all your recorded distances against your error tolerance
This works great for user input like from a mouse or touch sensor. This algorithm is O(n^2) and uses the delta max distance as opposed to finding the center of mass and checking radii distances.
It "seems" to be more efficient than the best-fit-circle method which has to calculate on every combination of 3 points.
This hack~algo takes advantage of the fact that the maximum distance between two points on a circle is the diameter of the circle.
function isCircle(points, error) {
if(points.length <= 2) return true;
var weights = [];
var maxDistance = 0;
var sumDistance = 0;
var avgDistance = 0;
var errorConstraint = 0;
for(var i=0; i<points.length; i++) {
var distance = 0;
for(var j=0; j<points.length; j++) {
var d = getDistance(points[i], points[j]);
if(d > distance) {
distance = d;
}
}
if(distance > 0) {
if(distance > maxDistance) maxDistance = distance;
sumDistance += distance;
weights.push(distance);
}
}
avgDistance = sumDistance / weights.length;
errorConstraint = error * avgDistance;
for(var i=0; i<weights.length; i++) {
if(Math.abs(avgDistance - weights[i]) > errorConstraint) {
return false;
}
}
return true;
}