math - 如何从鼠标手势生成的点列表中确定所有线段?

标签 math drawing gesture-recognition gesture

目前我在一家软件公司实习,我的任务之一是实现鼠标手势的识别。一位高级开发人员帮助我入门并提供了使用 $1 Unistroke Recognizer 的代码/项目 http://depts.washington.edu/aimgroup/proj/dollar/ .我得到,在 广泛 方式,1 美元的 Unistroke 识别器正在做什么以及它是如何工作的,但我有点不知所措,试图了解它的所有内部/更精细的细节。

我的问题是我试图识别向下移动鼠标然后向上移动的手势。 $1 Unistroke Recognizer 确定我创建的手势是向下的手势,这实际上是它应该做的。我真正希望它做的是说“我识别出向下的手势,然后是向上的手势。”

我不知道对 1 美元的 Unistroke Recognizer 缺乏了解是否完全让我摸不着头脑,但是有没有人知道如何通过向下和向上移动鼠标来识别两种不同的手势?

这是我的想法,我认为可能会对我有所帮助,但会喜欢专家甚至比我知道的更多的人让我知道您的想法。您知道的任何帮助或资源都是 大大赞赏。

我的应用程序目前如何工作:

我当前应用程序的工作方式是在用户按住鼠标左键时从鼠标光标所在的位置捕获点。然后将一个点列表提供给手势识别器,然后它会吐出它认为与捕获的点对应的最佳形状/手势。

我的想法:

我想做的是在将点输入手势识别器之前以某种方式遍历所有点并将它们分解为单独的线或曲线。通过这种方式,我可以一次输入每条线/曲线,从下、上、左、右、对角线和曲线的基本运动中,我可以确定最终的形状/手势。

我认为确定点列表中是否有单独线的一种方法是对点组进行采样并查看它们的斜率。如果采样点组的斜率与其他采样点组的斜率相差 X%,则可以安全地假设确实存在单独的线。

我认为是我思考中可能存在的问题:

  • 我在哪里确定一行的结束和一个单独的行的开始?如果我使用检查一组点的斜率的想法,然后确定存在一条单独的线,这并不意味着我必须找到一条单独的线的斜率。例如,如果您要绘制一个直边“L”并带有直角,并对“L”拐角周围的点的斜率进行采样,您会看到斜率会给出合理的指示,表明存在单独的线,但是这些点不对应于单独行的开始。
  • 如何处理不断变化的曲线斜率?我使用的手势识别器也以我想要的方式处理曲线。但是我不希望我用来确定单独线的方法继续在曲线中寻找这些所谓的单独线,因为当我对点组进行采样时,它的斜率一直在变化。一旦斜率连续变化超过 X%,我会停止采样点吗?
  • 我没有使用正确的数学“类型”来确定单独的行。数学不是我最擅长的科目,但我确实做了一些研究。我试图研究 Dot Products,看看这是否会给我指明方向,但我不知道是否会。有没有人使用 Dot Prodcuts 做这样的事情或其他方法?

  • 最后的想法、评论和感谢:

    我觉得我的部分问题是我不知道如何完全提出我的问题。如果这个问题已经被问过(以一种或另一种方式)并且存在可以通过谷歌搜索的解决方案,我不会感到惊讶。但是我在 Google 上的搜索结果没有提供任何解决方案,因为我还不知道如何确切地问我的问题。如果你觉得它很困惑,请告诉我在哪里以及为什么,我会帮助澄清它。这样做也许我在谷歌上的搜索会变得更加精确,我将能够找到解决方案。

    我只想再次感谢您阅读我的帖子。我知道它很长,但真的不知道在哪里可以问它。 Imma 与办公室周围的其他人交谈,但我在整个学校使用的所有最佳解决方案都来自 StackOverflow 社区,因此我非常感谢您。

    对这篇文章的编辑:

    (7/6 4:00 PM) 我想到的另一个想法是比较最小/最大点之前的所有点。例如,如果我将鼠标向下然后向上移动,我的起点将是当前的最大点,而我开始向上移动鼠标的点将是我的最小点。然后我可以继续查看在最小点之后是否有任何点,如果有,就说可能有一条新的潜在线。我不知道这对星星等其他形状的效果如何,但这是我要研究的另一件事。有没有人做过类似的事情?

    最佳答案

    如果您的问题可以缩小为将一般曲线分解为直线或平滑弯曲的部分线,那么您可以尝试这样做。

    在非常简化的情况下,比较段的斜率并识别大于某个阈值的断点。想象一个完美的 L 形,其中两条直线之间有一个直角。显然,只要阈值在 0 到 90 度之间,角点将是唯一一个斜率差异高于阈值的点,因此是一个可识别的断点。

    但是,垂直线和水平线可能会略微弯曲,因此阈值需要足够大,以便将斜率中的这些小差异作为断点忽略。您还必须决定算法在休息时应该选择多尖的角落。是否需要 90 度或更高,或者甚至 30 度就足够了?这是一个重要的问题。

    最后,为了使这个强大,我不会满足比较两个相邻段的斜率。手可能会颤抖,角落可能会变得平滑,找到直线和尖角的理想条件可能永远不会出现。对于为休息而调查的每个点,我将取前 N 个段的平均斜率,并将其与 N 个后续段的平均斜率进行比较。这可以使用运行平均值有效地实现。通过选择一个好的样本数 N(取决于输入的准确性、总点数等),算法可以避免噪声并进行更好的检测。

    基本上算法是:

  • 对于每个调查点(从 N 个点开始进入序列并在结束前结束 N 个点。)
  • 计算前 N 个线段的平均斜率。
  • 计算下 N 个线段的平均斜率。
  • 如果平均值的差异大于阈值,则将当前点标记为突破点。

  • 这完全不是我的想法。您必须在您的应用程序中尝试它。

    关于math - 如何从鼠标手势生成的点列表中确定所有线段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3190720/

    相关文章:

    java - 循环 i 和 j,其中 i != j

    c++ - 在归一化 vector 中查找缺失的坐标

    html - 使用鼠标在 HTML5 Canvas 上绘图

    android - 手势检测器不适用于可滚动列表 Activity

    c++ - 如何从 cvPoint 中分别获取 x 和 y 坐标到 int?

    algorithm - 找到最大的连续段算术级数

    javascript - jQuery - 如何在动画中进行数学运算

    android - 在 Canvas 上绘制虚线

    将多条抗锯齿线连接在一起

    c++ - glDrawElements 不绘制