如果我有例如20分,我该怎么检查这些点是否能弥补一个圆圈?它不一定是一个完美的圆圈。
例如,如果我每隔200ms存储鼠标的坐标(当用户移动鼠标时),我想看看用户是否做了圆形手势。我不能指望用户做一个完美的圈子。
答案 0 :(得分:9)
我执行以下操作;
答案 1 :(得分:3)
更新:根据@LastCoder的建议,将连续点丢弃得太接近前一个(我将阈值设置为10;也许可以增加),公差等级设置为0.25(即差异为25)从平均距离到中心点的百分比是可以接受的),我做的应用程序在超过一半的情况下识别我的“圆圈”,并且不再被正方形欺骗。毕竟,这可能不是一个坏主意。
我会找到给定点集的centroid,并检查从质心到每个点的距离是否大致相同(假设您期望得到一个完整圆的近似值,而不仅仅是弧)。
在实践中,它对于检测用鼠标完成的圆形手势的问题是有用的;请参阅an example in C#(仅限主要表单VS2010,应用程序的其余部分是自动样板;忽略ideone处的错误)及其屏幕截图:
答案 2 :(得分:2)
这是一个简单的方法,我将工作实现放在一起。
这非常适合用户输入,例如鼠标或触摸传感器。该算法为O(n ^ 2)并使用delta最大距离,而不是查找质心和检查半径距离。
“似乎”似乎比最佳拟合圆方法更有效,它必须计算3个点的每个组合。
这个hack~algo充分利用了这样一个事实:圆上两点之间的最大距离就是圆的直径。
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;
}