是否可以检查用户在画布上绘制的笔划是否为圆形?
我有两个数组x[]
和y[]
,它们具有笔划的所有坐标。如何使用此信息检查笔划是否为圆形?
答案 0 :(得分:1)
我想这取决于您对" circle"的定义。用户不太可能画一个实际的圆圈,尽管他们可能会接近。首先,您需要为" circle"。
定义规范这是一个可行的方法:
请注意,该规范仍然相当含糊。我使用短语"相对接近"而不是精确的术语,因为我不知道你的标准是什么" circle"是。但我希望上述内容是一个很好的起点。
修改强>
正如评论中所指出的,上面的内容仍然允许一些相当草率的图纸作为一个圆圈,例如" D"形状提到。如果希望将图纸限制在合理的圆形范围内,但仍然允许公平地压扁图形"形状(例如更椭圆形,蛋形等),可以通过添加基于由三元组点构成的角度的启发式来改进上述内容。
正确地做到这一点有点牵扯。您可以使用点积来轻松确定两个矢量之间的角度。但不幸的是,这种计算对于哪个向量是第一个"无动于衷。也就是说,如果您关心凹曲线与凸曲线,则点积不会区分。另一种方法是使用Math.Atan2()
函数。例如,让我们看看前三个点之间的角度:
// Note: normally one would make both vectors have the same start
// point, i.e. using pointList[1], for the subtraction of the
// Atan2 value to give the correct result. But here, what we really
// want to know is how different in direction the second vector is
// from the first, so calculating both line segment angles in the
// same direction of drawing gives a more useful result.
double vx1 = pointList[1].X - pointList[0].X, vy1 = pointList[1].Y - pointList[0].Y,
vx2 = pointList[2].X - pointList[1].X, vy2 = pointList[2].Y - pointList[1].Y;
double angleDifference = Math.Atan2(vx2, vy2) - Math.Atan2(vx1, vy1);
(你当然会在一个循环中进行这些计算,以获得每个三重点的差异;以上仅用于说明目的)。
假设用户沿逆时针方向画了一个圆圈,那么上面应该返回接近0的正角度差异。如果它们太接近0,那么你会想要拒绝绘图,因为这表明用户正在绘制直线(例如" D"的垂直条)。但是如果某些差异与0相差太远,你也会想要拒绝绘图,因为这表明用户可能正在绘制尖角(例如&#34的左上角或左下角; D&# 34。)
注意:较小的圆圈需要更锐利的角度。您可能希望根据圆的公称直径(即每个点距中心的距离的平均值)动态调整用于此的限制,对于较大的圆设置较小和最大角度差,对于较小的圆设置较大圆。
注意:此处的角度值以弧度为单位。因此,在设置角度差的下限和上限时,您需要确保使用正确的单位进行比较。
注意:用户当然可以顺时针方向画圆圈。如果你总结所有差异,你最终会得到正数或负数;该标志将告诉您是否应该将差异与期望的限制进行比较,或者将这些差异与这些限制的负数进行比较。要解决此问题,您可以执行以下任何操作:
true
)。在单次通过数据之后,您将知道是否应该使用正限制或负限制,然后只要在结尾处仅设置一个标记,圆就有效(假设没有角度超过绝对限制) ,当然)。