iOS - 沿曲线路径拖动对象
Posted
技术标签:
【中文标题】iOS - 沿曲线路径拖动对象【英文标题】:iOS - Dragging objects along curved paths 【发布时间】:2011-05-24 17:49:29 【问题描述】:我正在竭力想弄清楚什么似乎是一个非常简单的问题。我知道很多这样的东西已经被切题地讨论过,所以如果这涉及到覆盖良好的地面,我深表歉意,但我找不到任何特定于我的解决方案的东西(相信我,我已经看过了)。
基本上我想沿着预定义的弯曲路径拖动对象/精灵(不仅仅是移动它,而是拖动它)。想想 iPhone 的“滑动解锁”,但不要只是从左到右拖动滑块,而是将路径设为弧线或波浪线。
我的基本想法是:
定义贝塞尔路径,将对象设置在起点。 如果对象被触摸,请在 touchesMoved(或一些类似函数)中检查贝塞尔路径上的命中检测。如果触摸停留在路径上,则沿着路径前进精灵直到路径结束(在这种情况下,任务完成)或用户的手指离开路径(在这种情况下,对象应该回到起点)。这一切都不是微不足道的(至少看起来是这样)。例如:
在 Bezier 路径上进行命中检测非常痛苦,因为您实际上需要在描边部分而不是填充部分上进行检测。即便如此,我似乎也找不到在任何宽度的路径上执行此操作的方法 - 只能在 Bezier 的 1 点宽路径上。 沿路径部分移动对象似乎是不可能的:所有动画方法都沿整个路径移动精灵。此外,这样做需要您找到最接近用户触摸的路径上的点,如果您曾经查找过这个点,那么这涉及到极其复杂的数学运算。 我曾想过使用刚体来占据除了路径之外的所有空间,因此对象只能在路径中移动。然而,这需要定义弯曲刚体,其中一些必须是凹的。死胡同。我是不是太难了?好像没那么复杂。我不需要一个完整的解决方案,只需要一种新的方式来思考这个问题并朝着正确的方向前进。任何帮助将不胜感激。
【问题讨论】:
我知道很久以前有人问过这个问题,但我现在遇到了非常相似的问题,想知道您是否已经解决了这个问题,并且可以帮助我走上正确的道路。 【参考方案1】:这个怎么样?
考虑贝塞尔曲线的 X 轴 路径。 用户每次点击或与屏幕交互时,只需查看触摸的 x 部分 将该 X 坐标映射到您的路径并将对象移动到正确的位置。【讨论】:
如果曲线多次穿过 X 轴上的同一点,此解决方案是否有效?例如,如果曲线只是字母“S”怎么办。对于曲线上的不同 Y 点,同一个 X 点可以出现多次... 不,不会。你可以做的是使用 Y 轴来决定你应该调整到曲线中的哪个点【参考方案2】:是的,你太难了。
如果适用于上面建议的简化(或沿圆、线等),或者如果您真的想针对贝塞尔曲线进行简化,请考虑以下事项:
-
看看贝塞尔曲线的定义
您正在寻找的是从当前位置 P 和触摸位置 D 的变化定义一个新的对象位置 P'。
如果您将原始 P(x,y) 重新表述为 t(贝塞尔曲线是参数化的),那么问题就变成了根据 D 确定要添加多少 t 偏移量。
在 P 处涉及贝塞尔 fn 微分的方法可能是一个很好的方法。即,如果曲线只是一条从 P 点沿曲线出来的直线,那么会增加多少 t。
编辑: 段之间的过渡: 如果每个段的 t 在 [0,1) 中,那么您可以检测到 t >= 1 并移动到下一段,将 P 设置为前一段的末尾,并再次评估与该点相关的移动。如果您有很多小点等,可能必须涉及一些启发式方法。
【讨论】:
安德鲁,感谢您的回复。请耐心等待,因为我真的很想理解这一点,但它仍然在逃避我。我认为您和 arclight 的解决方案可能不适用于更复杂的路径。我相信(如果我错了,请纠正我)如果我的曲线是单个贝塞尔曲线,您的解决方案将起作用。但是,如果我构建的路径由多段、一些直线、一些四边形曲线、一些弧(SDK 允许)组成,我需要弄清楚我在哪个段上,然后计算新位置。你明白我在说什么吗? 请参阅上文了解处理此问题的可能方法。 我知道这是很久以前问的,但我现在正在尝试做类似的事情,想知道也许你可以回答这个问题。我想沿着我使用 beizerpath 绘制的椭圆拖动。有没有办法得到椭圆中的所有点,这样我就可以按照您上面的建议进行操作? @gikygik 根据定义,椭圆上有无数个点,所以你的问题对我来说没有意义。不过,椭圆的情况比贝塞尔曲线的情况要容易得多,因此您可以只采用椭圆的参数定义并找到它的导数(查看此处的任何向量微积分教科书)。不管你怎么画椭圆——它仍然是一个椭圆。以上是关于iOS - 沿曲线路径拖动对象的主要内容,如果未能解决你的问题,请参考以下文章