如何从鼠标手势生成的点列表中确定所有线段?
目前我在一家软件公司实习,我的任务之一就是实现鼠标手势的识别。一位高级开发人员帮助我入门,并提供了使用 1 美元 Unilines 识别器的代码/项目 http: //depts.washington.edu/aimgroup/proj/dollar/。我以一种广泛的方式了解了 1 美元的单笔画识别器正在做什么以及它是如何工作的,但对于试图理解它的所有内部结构/更精细的细节有点不知所措。
我的问题是我试图识别向下然后向上移动鼠标的手势。 $1 Unilines 识别器确定我创建的手势是向下的手势,这实际上是它应该做的。我真正希望它做的是说“我识别出向下的手势,然后识别出向上的手势。”
我不知道是否完全缺乏对 1 美元的单笔画识别器的理解让我抓耳挠腮,但是有人知道如何识别向下和向上移动鼠标的两种不同手势吗?
这是我的想法,我认为可能对我有帮助,但希望有一个专家或者比我懂得更多一点的人来让我知道你的想法。我们将非常感谢您所知道的任何帮助或资源。
我的应用程序当前的工作方式:
我当前的应用程序的工作方式是在用户按住鼠标左键时从鼠标光标所在的位置捕获点。然后,点列表被输入到手势识别器,然后它会输出它认为与捕获的点相对应的最佳形状/手势。
我的想法:
我想做的是在将点提供给手势识别器之前以某种方式遍历所有点并将它们分解为单独的直线或曲线。这样我就可以一次输入一条直线/曲线,并且根据下、上、左、右、对角线和曲线的基本运动,我可以确定最终的形状/手势。
我认为确定点列表中是否有单独的线的一种方法是对点组进行采样并查看它们的斜率。如果采样点组的斜率与其他采样点组的斜率相差 X%,则可以安全地假设确实存在一条单独的线。
我认为我的思维中可能存在的问题:
在哪里确定一行的结尾和另一行的开头?如果我要使用检查一组点的斜率的想法,然后确定存在一条单独的线,这并不意味着我一定要找到一条单独线的斜率。例如,如果您要绘制一个直角的直边“L”,并对“L”拐角周围的点的斜率进行采样,您会发现该斜率会给出合理的指示,表明存在一条单独的线,但是这些点不对应于单独行的开头。
如何处理不断变化的曲线斜率?我使用的手势识别器也已经按照我想要的方式处理曲线。但我不希望我用来确定单独线的方法继续在曲线中寻找这些所谓的单独线,因为当我对点组进行采样时,它的斜率一直在变化。一旦斜率连续多次变化超过 X%,我是否就停止采样点?
我没有使用正确的数学“类型”来确定单独的行。数学不是我最擅长的科目,但我确实做了一些研究。我尝试研究点积,看看这是否能为我指明某个方向,但我不知道是否会。有没有人使用点积来执行类似的操作或其他方法?
最后的想法、评论和感谢:
我觉得我的部分问题是我不知道如何完整地提出我的问题。如果这个问题已经被问过(以某种方式)并且存在可以通过谷歌搜索的解决方案,我不会感到惊讶。但我在谷歌上的搜索结果没有提供任何解决方案,因为我还不知道如何提出我的问题。如果您觉得令人困惑,请告诉我在哪里以及为什么,我会帮助澄清。这样做也许我在谷歌上的搜索会变得更加精确,我将能够找到解决方案。
我只想再次感谢您阅读我的帖子。我知道它很长,但真的不知道还能在哪里问。我正在与办公室里的其他人交谈,但我在整个学校使用过的所有最佳解决方案都来自 StackOverflow 社区,所以我非常感谢你们。
对这篇文章的编辑:
(7/6 4:00 PM)我想到的另一个想法是比较最小/最大点之前的所有点。例如,如果我向下然后向上移动鼠标,我的起点将是当前的最大点,而我开始向上移动鼠标的点将是我的最小点。然后我可以继续查看最小点之后是否有任何点,如果有,则说明可能存在新的潜在线。我不知道这对于星星等其他形状效果如何,但这是我要研究的另一件事。以前有人做过类似的事情吗?
Currently I am interning at a software company and one of my tasks has been to implement the recognition of mouse gestures. One of the senior developers helped me get started and provided code/projects that uses the $1 Unistroke Recognizer http://depts.washington.edu/aimgroup/proj/dollar/. I get, in a broad way, what the $1 Unistroke Recognizer is doing and how it works but am a bit overwhelmed with trying to understand all of the internals/finer details of it.
My problem is that I am trying to recognize the gesture of moving the mouse downards, then upwards. The $1 Unistroke Recognizer determines that the gesture I created was a downwards gesture, which is infact what it ought to do. What I really would like it to do is say "I recognize a downards gesture AND THEN an upwards gesture."
I do not know if the lack of understanding of the $1 Unistroke Recognizer completely is causing me to scratch my head, but does anyone have any ideas as to how to recognize two different gestures from moving the mouse downwards then upwards?
Here is my idea that I thought might help me but would love for someone who is an expert or even knows just a bit more than me to let me know what you think. Any help or resources that you know of would be greatly appreciated.
How My Application Currently Works:
The way that my current application works is that I capture points from where the mouse cursor is while the user holds down the left mouse button. A list of points then gets feed to a the gesture recognizer and it then spits out what it thinks to be the best shape/gesture that cooresponds to the captured points.
My Idea:
What I wanted to do is before I feed the points to the gesture recognizer is to somehow go through all the points and break them down into separate lines or curves. This way I could feed each line/curve in one at a time and from the basic movements of down, up, left, right, diagonals, and curves I could determine the final shape/gesture.
One way I thought would be good in determining if there are separate lines in my list of points is sampling groups of points and looking at their slope. If the slope of a sampled group of points differed X% from some other group of sampled points then it would be safe to assume that there is indeed a separate line present.
What I Think Are Possible Problems In My Thinking:
Where do I determine the end of a line and the start of a separate line? If I was to use the idea of checking the slope of a group of points and then determined that there was a separate line present that doesn't mean I nessecarily found the slope of a separate line. For example if you were to draw a straight edged "L" with a right angle and sample the slope of the points around the corner of the "L" you would see that the slope would give resonable indication that there is a separate line present but those points don't correspond to the start of a separate line.
How to deal with the ever changing slope of a curved line? The gesture recognizer that I use handles curves already in the way I want it too. But I don't want my method that I use to determine separate lines keep on looking for these so called separate lines in a curve because its slope is changing all the time when I sample groups of points. Would I just stop sampling points once the slope changed more than X% so many times in a row?
I'm not using the correct "type" of math for determining separate lines. Math isn't my strongest subject but I did do some research. I tried to look into Dot Products and see if that would point me in some direction, but I don't know if it will. Has anyone used Dot Prodcuts for doing something like this or some other method?
Final Thoughts, Remarks, And Thanks:
Part of my problem I feel like is that I don't know how to compeletly ask my question. I wouldn't be surprised if this problem has already been asked (in one way or another) and a solution exist that can be Googled. But my search results on Google didn't provide any solutions as I just don't know exactly how to ask my question yet. If you feel like it is confusing please let me know where and why and I will help clarify it. In doing so maybe my searches on Google will become more precise and I will be able to find a solution.
I just want to say thanks again for reading my post. I know its long but didn't really know where else to ask it. Imma talk with some other people around the office but all of my best solutions I have used throughout school have come from the StackOverflow community so I owe much thanks to you.
Edits To This Post:
(7/6 4:00 PM) Another idea I thought about was comparing all the points before a Min/Max point. For example, if I moved the mouse downards then upwards, my starting point would be the current Max point while the point where I start moving the mouse back upwards would be my min point. I could then go ahead and look to see if there are any points after the min point and if so say that there could be a new potential line. I dunno how well this will work on other shapes like stars but thats another thing Im going to look into. Has anyone done something similar to this before?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您的问题可以缩小到将一般曲线分解为直线或平滑弯曲的部分线,那么您可以尝试这个。
在非常简单的情况下,比较各段的斜率并识别大于某个阈值的断点。想象一个完美的 L 形,两条直线之间有一个直角。显然,只要阈值在 0 到 90 度之间,角点就是唯一一个斜率差高于阈值的点,因此是一个可识别的断点。
然而,垂直线和水平线可能会稍微弯曲,因此阈值需要足够大,才能将这些微小的斜率差异作为断点而忽略。您还必须决定算法应该选取多尖的角作为中断点。是否需要 90 度或更高,或者甚至 30 度就足够了?这是一个重要的问题。
最后,为了使其稳健,我不会满足于比较两个相邻线段的斜率。手可能会颤抖,拐角可能会被磨平,而找到直线和尖角的理想条件可能永远不会出现。对于针对中断进行调查的每个点,我将获取 N 个先前段的平均斜率,并将其与 N 个后续段的平均斜率进行比较。这可以使用运行平均值有效地实现。通过选择一个好的样本数N(取决于输入的准确性、总点数等),算法可以避免噪声并做出更好的检测。
基本上,算法是:
这完全超出了我的想象。您必须在您的应用程序中尝试它。
If your problem can be narrowed down to breaking apart a general curve into straight or smoothly curved partial lines then you could try this.
Comparing the slope of the segments and identifying breaking points where it is greater then some threshold would work in a very simplified case. Imagine a perfectly formed L-shape where you have a right angle between two straight lines. Obviously the corner point would be the only one where the slope difference is above the threshold as long as the threshold is between 0 and 90 degrees, and thus a identifiable breaking point.
However, the vertical and horizontal lines may be slightly curved so the threshold would need to be large enough for these small differences in slope to be ignored as breaking points. You'd also have to decide how sharp a corner the algorithm should pick up as a break. is 90 deg or higher required, or is even 30 deg enough? This is an important question.
Finally, to make this robust I would not be satisfied comparing the slopes of two adjacent segments. Hands may shake, corners may be smoothed out and the ideal conditions to find straight lines and sharp corners will probably never occur. For each point investigated for a break I would take the average slope of the N previous segments and compare it to the average slope of the N following segments. This can be efficiently implemented using a running mean. By choosing a good sample number N (depending on the accuracy of the input, the total number of points, etc) the algorithm can avoid the noise and make better detections.
Basically the algorithm would be:
This is quite off the top of my head. You'd have to try it in your application.
如果你使用绝对角度,比如向上和向下,你可以简单地取两点(不一定是相邻的)之间的绝对斜率来确定它是右、左、上、下(如果这足以区分的话)
。找到点之间的距离,使角度不是随机的(1px,角度将是 45° 的倍数)
有一个使用鼠标手势进行导航的 Firefox 插件,效果非常好。我认为是 FireGestures,但我不确定。我想你可以从这个
附加想法中得到一些启发:如果你通过连接连续的点,然后连接回第一个点来绘制形状,那么面积与最终线段长度之间的比率也是手势“的指标”急躁”
if you work with absolute angles, like upwards and downwards, you can simply take the absolute slope between two points (not necessarily adjacent) to determine if it's RIGHT, LEFT, UP, DOWN (if that is enough of a distinction)
the art is to find a distance between points so that the angle is not random (with 1px, the angle will be a multiple of 45°)
There is a firefox plugin for Navigation using mouse gestures that works very well. I think it's FireGestures, but I'm not sure. I guess you can get some inspiration from that one
Additional thought: If you draw a shape by connectiong successive points, then connecting back to the first point, the ratio between the area and the final line segment's length is also an indicator for the gesture's "edginess"
如果您只对上/下/左/右感兴趣,第一个近似方法是检查圆的 45 度线段。通过检查(连续)点之间的水平差异与点之间的垂直差异可以轻松完成此操作。
假设您的正水平差异大于垂直差异,那么这就是“正确”。
唯一的困难是例如区分“上/下”和“上/右/下”。但这可以通过点之间的距离来完成。如果您确定鼠标向右移动了少于 20 像素,那么您可以忽略该移动。
If you are just interested in up/down/left/right, a first approximation is to check 45 degree segments of a circle. This is easily done by checking the the horizontal difference between (successive) points against the vertical difference between points.
Say you have a greater positive horizontal difference than vertical difference, then that would be 'RIGHT'.
The only difficulty then comes for example, in distinguishing UP/DOWN from UP/RIGHT/DOWN. But this could be done by distances between points. If you determine that the mouse has moved RIGHT for less than 20 pixels say, then you can ignore that movement.