Calculate angle for rotation in Pie Chart

纵饮孤独 提交于 2019-12-02 00:34:43

Glad I remember triginometry


-(void)degreesToRotateObjectWithPosition:(CGPoint)objPos andTouchPoint:(CGPoint)touchPoint{

   float dX = touchPoint.x-objPos.x;        // distance along X
   float dY = touchPoint.y-objPos.y;        // distance along Y
   float radians = atan2(dY, dX);          // tan = opp / adj

   //Now we have to convert radians to degrees:
   float degrees = radians*M_PI/360;

   return degrees;
}

Once you have your nice method, just do this in the touch event method. (I forgot what it's called...)

CGAffineTransform current = view.transform;

[view setTransform:CGAffineTransformRotate(current,
[self degreesTorotateObjectWithPosition:view.frame.origin
andTouchPoint:[touch locationInView:parentView]] //Note: parentView = The view that your object to rotate is sitting in.

This is pretty much all the code that you'll need.The math is right, but I'm not sure about the setTransform stuff. I'm at school writing this in a browser. You should be able to figure it out from here.

Good luck,

Aurum Aquila

Have to think at this. But I will prefer rotating the view with two touches. It will be much simpler.

I did struggle a bit with how to get a touch driven rotation, even more so because I want 100% understanding of the code I am using. So I ended up, after many failed attempts, with this:

- (CGFloat) pointToAngleFromCenter: (CGPoint) point {
    // transform point to a self.center'ed origin based coordinate system
    point.x = point.x - self.center.x ;
    // ditto for y, but compensate for y going downwards to y going upwards
    point.y = self.center.y - point.y ;
    return ::atan2(point.y, point.x) ;
}

If anyone has a better name for this method, I'm all ears.

What it does is that it takes a point in parent view coordinates, remaps it relative to the center of the view (which is in parent view coordinate), and computes the angle between this remapped point and the axis [0X]. To do so, it normalizes y to the normal mathematical coordinates (y goes up when its value increases, not down), hence self.center.y - point.y and not the opposite.

Finally, in touchesMoved:

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

    CGFloat currA = [self pointToAngleFromCenter:[touch locationInView:self.superview]] ;
    CGFloat prevA = [self pointToAngleFromCenter:[touch previousLocationInView:self.superview]] ;
    // the current value of the rotation angle
    CGFloat tranA = ::atan2(self.transform.b, self.transform.a) ;
    // the angle difference between last touch and the current touch
    CGFloat diffA = currA - prevA ;
    // the new angle resulting from applying the difference
    CGFloat angle = tranA - diffA ;

    CGAffineTransform t = ::CGAffineTransformMakeRotation(angle) ;

    self.transform = t ;
    [self setNeedsDisplay] ;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!