I'm having difficulties adding momentum to my spinning wheel.
I have this wheel (something like this) and I'm rotating it around it's center by using a single touch event.
No problems here, but when the touch (aka drag) ends; I want the wheel to keep it's momentum and ease out it's movement.
Anyone who can give me some pointers, it doesn't necessarily have to be in objective-c.
AS3, javascript or JAVA will also be sufficient.
* UPDATE (code for rotating the wheel) *
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
rotation = _startAngle = atan2(384 - touchPoint.y, 512 - touchPoint.x);
};
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint touchPoint = [[touches anyObject] locationInView:self.view];
rotation = atan2(384 - touchPoint.y, 512 - touchPoint.x);
rotation = fmod(rotation - _startAngle, M_PI * 2.0f);
[wheel setTransform:CGAffineTransformMakeRotation(_circleRotationOffset + rotation)];
};
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
_circleRotationOffset = fmod(_circleRotationOffset + rotation, M_PI * 2);
};
You want the momentum to reduce due to friction; friction is a force that's a function of velocity. So technically you've got a differential equation going on. That's not really worth investing too much thought into though, because the solution is probably more easily reached by hand waving.
So: store current angle and current angular velocity. n times a second (probably via an NSTimer
or a CADisplayLink
) add the angular velocity to the angle, then multiply the angular velocity by something to make it smaller — such as 0.995. Constants closer to 1.0 will make it take longer to slow down; if you go above 1.0 it'll obviously accelerate. This is effectively a form of Euler integration but, again, it's not worth worrying about.
It's possibly also worth putting a minimum cap on angular velocity so that if it drops below, say 0.01 radians/second then you snap it down to 0. That effectively modifies your model of friction slightly to jump from kinetic to static friction at an opportune moment, and acts as a floating point precision buffer zone.
To get initial velocity from a drag you can just work out the vector from the centre of the wheel to the start of the drag, rotate that vector by 90 degrees, do a dot product with that and the drag vector and scale according to distance from the centre.