2

用户可以使用一个非常简单的工具(按住 LMB 移动鼠标)在我的应用程序中绘制草图。这会导致一系列 mousemove 事件,并且我会在每个事件中记录光标位置。生成的折线曲线往往相当密集,几乎每隔一个像素都有记录点。我想平滑这条像素化的折线,但我不想平滑预期的扭结。那么我如何找出扭结在哪里呢?

该图像显示了记录的轨迹(红色像素)和人类可以理解的“暗示”形状。人们倾向于在拐角处放慢速度,因此这里的噪音通常比直道上还要多。

折线跟踪器 http://www.freeimagehosting.net/uploads/c83c6b462a.png

4

4 回答 4

1

您是否考虑过查看数据的时间,而不是尝试从结果数据中执行此操作?如果鼠标明显停止或减速,则使用自上次“扭结”(鼠标最后一次减速)以来的趋势来确定行进方向。如果用户朝着新的方向前进,你称之为扭结,否则,你忽略当前的放缓趋势并开始等待下一个趋势。

于 2010-04-27T20:48:18.723 回答
1

好吧,一种方法是使用真正的曲线拟合算法。生成贝塞尔曲线(具有精确端点,使用 Catmull-Rom 或类似的东西),然后优化和递归细分(使用与实际线点的距离作为成本指标)。不过,这对于您的用例来说可能太复杂了。

于 2010-04-27T20:52:31.297 回答
1

您所描述的可能与手势识别技术有关,因此您可以在它们上搜索想法。

显而易见的方法是应用曲线拟合,但这会产生平滑所有有趣细节和扭结的效果。建议的另一种方法是查看速度和加速度,但这可能会让人毛骨悚然(方向变化可能非常快或非常慢且经过深思熟虑)

一个相当基本但有效的方法是将样本直接简化为折线。

例如,从样本 1 到样本 4 遍历样本(例如),并检查所有 4 个样本是否都在 1 和 4 之间的直线的合理误差范围内。如果是,则将其扩展到点 1。 .5 并重复直到从起点到终点的直线不再为这些样本定义的曲线提供合理的近似值。创建一条直到前一个采样点的线段并开始累积一个新的线段。

当样本彼此太接近时,您必须小心阈值,因此当样本彼此相距少于 4-5 个像素时,您可能需要调整灵敏度。

这将为您提供一组相当准确地遵循原始路径的直线。

如果您需要额外的平滑,或者想要创建可缩放的矢量图形,那么您可以从折线进行曲线拟合。首先,确定扭结(折线中一条线与另一条线之间的角度锐利的位置 - 例如,超过 140 度的任何东西都被认为是平滑曲线,小于 140 度的任何东西都被认为是扭结)并在这些不连续处打破折线. 然后对原始手势的每个子部分进行曲线拟合以使其平滑。这将具有平滑光滑的东西和锐化扭结的效果。(您可以更进一步,插入小的光滑角圆角而不是这些锋利的接头,以降低接头的锋利度)

蛮力,但它可能只是实现你想要的。

于 2010-04-27T21:38:12.800 回答
0

记录像素的绘制顺序。然后,计算“接近”但不“接近”的像素之间的斜率。我猜测像素(i)和像素(i + 7)之间的斜率图可能会在曲线的扭结周围表现出容易识别的“跳跃”。

于 2010-09-29T18:18:14.820 回答