I've implemented something similar, atan2 function as mentioned by Echelon helped me a lot.
I have a custom view that contains a layer which can be rotated around the middle of the view. I'm actually creating more layers as I have graphics which are overlapping the wheel. The view itself does not draw anything, it is used as a container for layers, and for the sake of reacting to touch events.
In the touchesEnded:withEvent:
I'm creating more complex animation that auto-rotates the wheel to aligned position.
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
touchedUnderAngle = [self angleForTouch:[touches anyObject]];
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
double angle = [self angleForTouch:[touches anyObject]];
wheelAngle = wheelAngle - angle + touchedUnderAngle;
touchedUnderAngle = angle;
[CATransaction begin];
[CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]];
[CATransaction setAnimationDuration:0.05];
self.wheelLayer.transform = CATransform3DMakeRotation(wheelAngle, 0.0f, 0.0f, 1.0f);
[CATransaction commit];
}
- (double)angleForTouch:(UITouch*)touch
{
CGPoint location = [touch locationInView:self];
double x = location.x - self.frame.size.width / 2;
double y = self.frame.size.height / 2 - location.y;
return atan2(y, x);
}