iOS - Dragging objects along curved paths
I am tearing my hair out trying to figure out what seems to be a very easy problem. I know a lot of this stuff has been talked about tangentially, so apologies if this treads on well-covered ground, but I can't find anything specific to my solution (believe me, I've looked).
Basically I want to drag an object/sprite along a pre-defined, curved path (not just move it, but DRAG IT). Think of the iPhone's "Slide to unlock" thing, but instead of just dragging the slider left-to-right, make the path an arc or a wavy line.
My basic thinking was:
- define a bezier path, set the object at the start point.
- if the object is touched, check for hit detection on the bezier path in touchesMoved (or some similar function). if touches stay on the path, advance the sprite along the path until the path ends (in which case, task is finished) or the user's finger goes off the path (in which case, the obj开发者_Python百科ect should go back to the beginning).
None of this is trivial (at least, that's how it seems). For example:
- Doing hit detection on a Bezier path is a royal pain since you actually need to do it on the stroked portion, not the fill portion. And even then, I can't seem to find a way to do it on a path of any width -- only on the 1-point-wide path of the Bezier.
- Moving an object partially along a path doesn't even seem possible: all of the animation methods move the sprite along the ENTIRE path. Also, doing this requires you to find the point on the path closest to the user's touch, which, if you've ever looked this up involves astoundingly complicated math.
- I've thought of using rigid bodies to occupy all of the space EXCEPT the path, so the object can only move in the path. However, this requires the definition of curved rigid bodies some of which must be concave. Dead end.
Am I making this too hard? It doesn't seem that complicated. I don't need a whole solution, just a new way to think about this and kick in the right direction. Any help would be really appreciated.
How about this?
- Consider the X Axis of your bezier path.
- Each time the user taps or interacts with the screen just look at the x portion of the touch
- Map that X Coordinate with your path and move the object to the right position.
Yes, you are making this too hard.
Take the simplification suggested above (or along a circle, line, etc) if it works for, or if you really want to do it against a bézier curve, consider the following:
- Look at the definition of the bézier curve
- What you're looking for is to define a new object position P' from a current position P and a change in touch position D.
- If you rephrase the original P(x,y) in terms of t (bézier curves are parametric), then the problem becomes finding how much t offset to add based on D.
- Something involving the differential of the bezier fn at P might be a good way to do that. Ie, how much t would have been added had the curve just been a straight line coming from point P along the curve.
EDIT: Transition between segments: If each segment has t in [0,1), then you can detect t >= 1 and move on to the next segment, setting P to the end of the previous segment, and evaluating the movement again in relation to that point. There might have to be some heuristics involved if you have a lot of small points, etc.
精彩评论