我正在研究一种简单的程序化方法,用于检测用户是否绘制了圆形。我在C工作,但很高兴从伪代码工作。一些谷歌搜索带来了许多(希望)过于复杂的方法。
我将鼠标坐标跟踪为浮动,并创建了一个矢量数组来跟踪鼠标随时间的移动。基本上我想要检测何时绘制一个圆,然后忽略与该圆无关的所有运动数据。
我基本了解如何实现这一目标:
使用轮询功能跟踪所有动作。每次轮询该功能时,都会存储当前鼠标位置。在这里,我们遍历历史位置数据并做一个粗略的“对齐位置”来比较这两个位置。如果新位置距离旧位置足够近,我们会删除旧位置之前的所有历史数据。
虽然这在理论上有效,但在实践中却是一团糟。有没有人有什么建议?如果建议的方法可以检测它是顺时针还是逆时针绘制的加分点。
答案 0 :(得分:6)
基于您的跟踪/轮询功能,它将浮动对推送到堆栈上。这必须定期进行。
将步骤2的数量除以2,现在已经有了季度。
如果步骤1中的线是垂直的,并且线的第一个点位于顶部:如果第一个四分之一位于中心点的左侧,则逆时针绘制圆圈。如果第一个四分之一位于中心点右侧,则顺时针绘制圆圈。如果该行的第一个点位于底部,则反向(即ccw => cw和cw => ccw)
如果步骤1中的线是水平的并且列表的第一个点位于左侧:如果第一个四分之一位于中心点之上,则逆时针绘制圆圈。如果第一个季度低于中心点,则顺时针绘制圆圈。如果该行的第一个点位于右侧,则反转。
在步骤2和4中,如果定时间隔非常低(快速轮询),您可以通过取几个索引的平均值来进一步调整此算法。例如:数组中有30对,然后您在0,1和28,29处平均对以获得高点。对所有其他点也这样做。
我希望这很容易。
答案 1 :(得分:5)
你肯定是在正确的轨道恕我直言。基本上,您需要将每个鼠标点与之前的鼠标点进行比较,并计算它们之间的角度(如第一个点位于原点的单位圆所设想的那样)。为此,您可以使用以下公式:
double angle = atan2(y2 - y1, x2 - x1) * 180 / PI;
if (angle < 0)
angle += 360;
您最终得到的是,对于顺时针运动,角度将以正方向循环,而对于逆时针运动,角度将以负方向循环。您可以使用以下逻辑确定当前角度是大于还是小于前一个角度:
if (angle2 > 270 && angle1 < 90)
{
angle1 += 360
}
else if (angle1 > 270 && angle2 < 90)
{
angle2 += 360
}
bool isPositive = (angle2-angle1 > 0);
如果你得到一定数量的矢量,所有的矢量都有增加的角度(isPositive是真的,比方说,10倍),你可以假设正在绘制顺时针圆;如果趋势为负(isPositive为假10次),则为逆时针圈。 :)
答案 2 :(得分:1)
这是一种算法,用于查看点数组是否适合圆形:
计算点的质心(所有x和y坐标的平均值)
计算所有点到质心的距离
找到最大和最小距离
如果最大-最小<公差,检测到圆形截面
NB这还将检测圆的一部分,因此您需要确定已扫过足够的角度才能使其成为完整的圆。
为此:
如果所有线段均包含至少1个点,则该点为一个圆(即,您映射的线段数组包含0到11之间的所有值)
奖金:增加角度为逆时针;递减是顺时针
答案 3 :(得分:0)
没有试过这个,但想到阅读你的问题时想到了这个想法,所以不妨与你分享:
我假设必须在合理的时间内绘制圆圈,给定鼠标的稳定“采样率”,这将留下已知大小的2D矢量阵列(点)。将它们全部加起来并除以2D向量的数量,以估算出数组中的“中心”点。然后从该中心点到阵列中的点形成矢量并做点积(通过矢量长度归一化),确保点积的符号在一系列点上保持相同意味着这些点全部在同一点上移动方向,正号表示逆时针运动,负表示正好相反。如果累积角度超过2 PI,则绘制圆周运动。
祝你好运。答案 4 :(得分:0)
1-选择任意3点
2-如果这些点是共线的+/-“某个缓冲区”,则它不是一个圆。
3-使用Wikipedia上描述的方法找到三角形的外接圆,以找到候选圆的中点和半径
可以通过绘制任意两个来构造三角形的外接心 三个垂直平分线之一。对于三个非共线点, 这两条线不能平行,并且外接点是点 他们穿过的地方。等分线的任何一点与等分线等距 它一分为二的两点,从这一点出发, 两个等分线均与所有三个三角形顶点等距。的 圆周半径是从它到三个顶点中任意一个顶点的距离。
4-检查到其余点的距离。如果这些点在“候选圆半径” +/-“某些缓冲区余量”之内,则为圆。
5-要确定方向,只需从中点计算第一点和第二点之间的角度即可。负角是正确的。剩下一个正角。 (可以根据您使用的坐标系来反转)