Reputation: 8348
I have a Ring(width 25px) as UIView
. When User selects any where on the ring, I want to Calculate the Angle between the the Points Selected on a fixed point on the circle considering the Center of Circle.
I have found few examples but they are not taking center into consideration.
What is the Optimum way to do this ?
Upvotes: 1
Views: 2493
Reputation: 919
You'll have to handle the code yourself (I'm a Java developer), but the simplest way to get the angle between two points on a circle (measured against its center) is to recall the geometry of the situation. The triangle formed by any two points on the circumference of a circle and the circle's center is necessarily isosceles.
An isosceles triangle, recall, has (at least) two sides of the same length -- the radial segments to your two points. Bisecting the angle results in a radial segment which is perpendicular to and bisects the line connecting the two points. This forms a pair of right triangles, with the radius as the hypotenuse, and half the distance between the two points as the 'opposite' side.
Moving the factor of two to the denominator and recognizing what twice the radius is, simply calculate the distance between the two points (on the circumference), and divide it by the diameter. The value you get is the sine of the half-angle (you desire the whole angle). Take the arcsine, and you'll have half your angle:
θ/2 = sin-1(d/D)
With d
as the distance between the two points, and D
as the diameter of the circle. Since the diameter is given, and the distance between the two points is simple to calculate, getting to this point should be easy, and then you just need to double the value calculated to get the whole angle between the two points.
Upvotes: 1
Reputation: 830
As we know ((center.x + radius*cos(theta)) ,(center.y + radius*sin(theta))) ~ (X,Y)
where (X,Y) belongs to the any circumference point
so you can calculate the Angle i.e. theta for any Circumference point as:
X= center.x + radius*cos(theta)
cos(theta) = (X - center.x)/radius .......... eqn-1
similarly
Y= center.y + radius*sin(theta)
sin(theta) = (Y - center.y)/radius .......... eqn-2
By dividing eqn-2 by eqn-1 we have
tan(theta) = (Y - center.y)/(X - center.x) -----------------Final Equation
Upvotes: 0
Reputation: 443
This might help you, I have used same thing in one of my projects.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
beginPoint = [[[event allTouches] anyObject] locationInView:self];
currentAngle = 0.0f;
centerPoint = self.center;
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
endPoint = [[[event allTouches] anyObject] locationInView:self];
float fromAngle = atan2(beginPoint.y - self.center.y, beginPoint.x - self.center.x);
float toAngle = atan2(endPoint.y - self.center.y, endPoint.x - self.center.x);
float newAngle = [self wrapd:currentAngle + (toAngle - fromAngle) min:0 max:2 * 3.14];
currentAngle = newAngle;
CGAffineTransform cgaRotate = CGAffineTransformMakeRotation(newAngle);
[self setTransform:cgaRotate];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
endPoint = [[[event allTouches] anyObject] locationInView:self];
float fromAngle = atan2(beginPoint.y - self.center.y, beginPoint.x - self.center.x);
float toAngle = atan2(endPoint.y - self.center.y, endPoint.x - self.center.x);
float newAngle = [self wrapd:currentAngle + (toAngle - fromAngle) min:0 max:2 * 3.14];
currentAngle = newAngle;
}
- (double) wrapd:(double)_val min:(double)_min max:(double)_max {
if(_val < _min) return _max - (_min - _val);
if(_val > _max) return _val - _max; /*_min - (_max - _val)*/;
return _val;
}
Upvotes: 0