sankar siva
sankar siva

Reputation: 255

Arrow Rotation in speedometer

I have implemented a speedometer. I have one arrow image. I want to rotate it 0° to 180° very smoothly with finger touch and also I should give boundaries. How is it possible?

Here is my code (in UIImageView category):

- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
    UITouch *touch = [touches anyObject];

    CGPoint currentLocation = [touch locationInView:self.superview];
    CGPoint pastLocation = [touch previousLocationInView:self.superview];

    CGPoint d1 = CGPointMake(currentLocation.x-self.superview.center.x, currentLocation.y-self.superview.center.y);   
    CGPoint d2 = CGPointMake(pastLocation.x-self.superview.center.x, pastLocation.y-self.superview.center.y);

    CGFloat angle1 = atan2(d1.y, d1.x); 
    CGFloat angle2 = atan2(d2.y, d2.x); 

    self.transform = CGAffineTransformRotate(self.transform, angle1-angle2);
}

It's rotating 0 to 360 degrees, I need restrict between the angles like 20 to 160 degrees.

Upvotes: 3

Views: 593

Answers (1)

Lou Franco
Lou Franco

Reputation: 89192

Figure out the correct Affine Transform to apply based on touch (using trig) and apply it.

 view.transform = CGAffineTransformMakeRotation(angleInRadians);

Probably you need to translate the origin first, and then back again, to get it to rotate around the point that you want. Alternatively, you could make the view so that the pivot point is in the center of the view.

To calculate the angle, find the touch point's distance from the rotation point (dx, dy).

tan angle = dy / dx

Use

 atan2(dy, dx)

Because it deals with the signs by knowing which quadrant it's in (don't pass in 0 for dx).

https://developer.apple.com/library/IOs/#documentation/System/Conceptual/ManPages_iPhoneOS/man3/atan2.3.html

Deal with the dx being 0 case separately (it's PI/2 radians). There are probably other special cases you want to deal with to constrain it -- just pick min and max radians and check them before using in a transform.

EDIT based on question update: You have done the hard part -- just look at the angle and limit it

Use MIN and MAX to limit angle1 and angle2 (remember it's radians, so 20/180*pi and 160/180*pi). Do that right before you pass to CGAffineTransformRotate

Upvotes: 3

Related Questions