It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened,
visit the help center.
Closed 8 years ago.
If I have e.g. 20 points, how can i check to see if those points make up for a circle? It doesnt have to be a perfect circle.
For example if I store the coordinates of my mouse every 200ms (as the user moves the mouse), I want to see if the user makes a circle gesture. And I cant expect the user to make a perfect circle.
Update: with the suggestion from @LastCoder to drop consecutive points too close to the previous one (I set the threshold at the distance of 10; perhaps it can be increased) and the tolerance level set to 0.25 (i.e. discrepancy of 25% from the average distance to the centre point is acceptable), the app I made recognizes my "circles" in more than half cases, and is not deceived by squares anymore. So might be not a bad idea, after all.
I would find the centroid for the given set of points, and check if the distance from the centroid to each point is more or less the same (assuming that you expect an approximation of full circle, not just an arc).
It works for me in practice for the problem of detecting a circle gesture done with mouse; see an example in C# (VS2010, the main form only, the rest of app is automatic boilerplate; ignore the errors at ideone) and a screenshot for it here:
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;
}