2

设置

我想创建一个网页,当用户的光标位于屏幕的某个区域时,他在该区域“绘制”了一个假想的圆圈,javascript 检测到该手势并执行一个功能。对于正方形,将执行不同的功能。

我从未见过这样做,但我相信使用 javascript 和 HTML5 画布,它应该是完全可能的。

问题:

如何以一种允许我检测用户不完美的手势形状输入并让我的脚本区分不同手势/形状的方式来做到这一点?

例子

在此处输入图像描述

笔记:

这不仅仅是一个触摸屏功能。它也必须与普通光标以及用户的鼠标一起使用。

伟大的用途:

网站可以使用它来允许其用户使用鼠标和手的手势快捷方式来访问特定页面,或触发用户在站点内经常使用的功能。例如,用户可以在任何堆栈溢出页面的中心绘制一个问号,以直接发送到新的问题页面。甚至可以允许用户做出自己的手势来查看最喜欢的问题、转到主页或为当前问题页面提交答案。

4

1 回答 1

7

我一直想自己实现这样的东西,但用于不同的用例。我希望我的用户能够手动绘制“圆形”、“矩形”和“菱形”,而我的软件将用完美的圆形、矩形和菱形代替原来的曲折线。这是我想到的一个简单的图形/图表绘图 web 应用程序。

无论如何,需要的是从用户不完美的手绘中检测形状。我想我有一个粗略的想法。

几年前,我在 Tcl wiki 上发现了一个简单的玩具手写识别应用程序。它没有使用花哨的人工智能或任何东西来检测字母,而是使用了一种巧妙的图片“散列”技术。

这个想法基本上是这样的:

  1. 将您的书写区域划分为多个区域 - 最简单的是网格,但它可以是形状奇特的区域以提高准确性。

  2. 当用户绘制一些东西时,遍历区域列表并检测其中是否有任何“墨水”。

  3. 如果有“ink”,则将该区域的值设置为 1。如果不设置为 0。这将为您提供一个包含 1 和 0 的数组(或字符串)。如果您累积了一个数组,请将其转换为字符串。该字符串是您的绘图“哈希”。

  4. 将此“哈希”与形状哈希数据库进行比较。完全匹配的可能性很小,因此使用像 Levenshtein 距离这样的模糊匹配函数来找到最接近的匹配。

  5. 如果找到匹配项(在合理的阈值内),那么您就找到了您的形状(在原始算法中它是一个字母或数字,但这个想法可以推广到形状)。

以下是检测三角形的一个示例:

Sample triangle:
. . . . . . . . . . . . . . . .
0     1     2  #  3     4     .
.     .     . # # .     .     .
. . . . . . .#. .#. . . . . . .
5     .     #     #     .     .
.     .    #.     .#    .     .
. . . . . # . . . . # . . . . .
10    .  #  .     .  #  .     .
.     . #   .     .   # .     .
. . . .#. . . . . . . .#. . . .
15    #     .     .     #     .
.    #.     .     .     .#    .
. . # . . . . . . . . . . # . .
20 #  .     .     .     24 #  .
. ########################### .
. . . . . . . . . . . . . . . .

从上面的 ASCII 艺术。数据库中的示例三角形生成“哈希”:

00100
01110
01010
11011
11111

重新排列为字符串:0010001110010101101111111

现在让我们比较一个非常糟糕的用户绘制的三角形:

User drawing:
. . . . . . . . . . . . . . . .
0     1     2 #   3     4     .
.     .     . # # .     .     .
. . . . . . .#. .#. . . . . . .
5     .      #     #    .     .
.     .     #     . #   .     .
. . . . . # . . . . # . . . . .
10    . #   .     . #   .     .
.     .#    .     .  #  .     .
. . . .#. . . . . . . .#. . . .
15    #     .     .      #    .
.   # .     .     .     . #   .
. .#  . . . . . . ### . .  #. .
20### .     .#### .  ## 24  # .
.    #######.     .    ###### .
. . . . . . . . . . . . . . . .

其哈希值为:0010001110010101111111111。将其与数据库中的原始三角形进行比较:

  triangle: 0010001110010101101111111
   drawing: 0010001110010101111111111
difference: -----------------1-------

现在将绘图与其他形状的散列进行比较:

    circle: 0111011011100011101101110
   drawing: 0010001110010101111111111
difference: -1-1-1-1-111-11--1--1---1

    square: 1111110001100011000111111
   drawing: 0010001110010101111111111
difference: 11-111111111-11-111------

   diamond: 0111001010100010101001110
   drawing: 0010001110010101111111111
difference: -1-1---1--11-111-1-11---1

由于三角形是最佳匹配,我们假设用户正在尝试绘制三角形。

我一直在考虑一些策略来提高算法的可靠性。

  1. 而不是只存储 1 和 0 存储 0,1,2。这使得数据库中的散列成为“灰度”散列,这可能使我们能够捕捉到画得非常糟糕的形状。
  2. 而不是只存储 1 和 0 存储 0,1 和“不关心”,这可以让我们过滤掉绘图中的噪声并可以改善匹配。
  3. 不是使用固定网格,而是获取图形的边界矩形,然后将图形划分为多个区域。这使我们能够检测具有相同哈希值的圆形和椭圆形以及具有相同哈希值的正方形和矩形。它还适用于比预期更小或更大的图纸。

至于如何记录绘图 - 这取决于你。您可以使用画布、SVG 甚至只是使用 onmousemove 轮询鼠标坐标。

于 2013-10-29T01:57:59.500 回答