Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 笔划是圆吗?_C#_Silverlight_Windows Phone 8.1 - Fatal编程技术网

C# 笔划是圆吗?

C# 笔划是圆吗?,c#,silverlight,windows-phone-8.1,C#,Silverlight,Windows Phone 8.1,是否可以检查用户在画布上绘制的笔划是否为圆形 我有两个数组x[]和y[],它们具有笔划的所有坐标。如何使用此信息检查笔划是否为圆形?我想这取决于您对“圆”的定义。用户不太可能画出一个实际的圆圈,尽管他们可能很接近。因此,首先,您需要定义“圆”的规范 下面是一个可能有效的方法: 绘制的形状是一条闭合曲线。也就是说,终点与起点相对较近 从每个点到“中心”的距离(其中“中心”定义为所有点的平均值)相对接近所有点的平均距离 请注意,该规范仍然相当模糊。我用“相对接近”这个短语来代替精确的术语,因为我真的

是否可以检查用户在画布上绘制的笔划是否为圆形


我有两个数组
x[]
y[]
,它们具有笔划的所有坐标。如何使用此信息检查笔划是否为圆形?

我想这取决于您对“圆”的定义。用户不太可能画出一个实际的圆圈,尽管他们可能很接近。因此,首先,您需要定义“圆”的规范

下面是一个可能有效的方法:

  • 绘制的形状是一条闭合曲线。也就是说,终点与起点相对较近
  • 从每个点到“中心”的距离(其中“中心”定义为所有点的平均值)相对接近所有点的平均距离
  • 请注意,该规范仍然相当模糊。我用“相对接近”这个短语来代替精确的术语,因为我真的不知道你对“圈”的标准是什么。但我希望以上是一个很好的起点


    编辑:

    如注释中所述,上面的说明仍然允许一些相当粗糙的图形限定为圆形,如所提到的“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太远,您也会希望拒绝该图形,因为这表明用户可能正在绘制锐角(例如“D”的左上角或左下角)

    注意:较小的圆需要更锐利的角度。您可能希望根据圆的标称直径(即每个点到中心距离的平均值)动态调整用于此操作的限制,对于较大的圆,将最小和最大角度差设置为较小,对于较小的圆,将其设置为较大

    注意:此处的角度值以弧度为单位。因此,在设置角度差的下限和上限时,需要确保使用正确的单位进行比较

    注意:用户当然可以按顺时针方向画一个圆。如果你把所有的差异加起来,你会得到一个正数或负数;这个标志会告诉你是应该将你的差异与你想要的极限进行比较,还是与那些极限的负值进行比较。要解决此问题,您可以执行以下任一操作:

    • 对数据进行两次遍历,第一次是为了找出限制值的正值还是负值,第二次是为了将实际值与限制值进行比较
    • 在第一个过程中保存角度计算,然后在第二个过程中使用这些保存的值
    • 只需跟踪您的比较是否始终在正限值、负限值或两者之间(即两个标志,根据正限值和负限值的比较,将相应的标志设置为
      true
      )。单次通过数据后,您将知道应该使用正极限还是负极限,然后只要在末尾只设置一个标志,圆就有效(当然,假设没有角度超过绝对极限)

    可以,但需要非常精确的图纸。嗯,谢谢:)嗯,这里没有解决办法,我只是要求这个想法,它是有效的。如果你有更好的解决方案,请分享@伊万:“乔托”是谁?他对这个解决方案的具体反对意见是什么?以能够画出完美的曲线而闻名circle@Ewan:嗯……那么呢?他跟什么都有关系。