3
votes

I have got a UIImageView displaying a circle divided in six equal triangles corresponding to:

  • area1 between 0-60 degrees
  • area2 between>60-120 degrees
  • area3 between>120-180 degrees
  • area4 between>180-240 degrees
  • area5 between>240-300 degrees
  • area6 between>300-360 degrees

The circle is similar to the following (pardon me for the bad drawing):

enter image description here

I would like to derive from the touch point in which area the tap is. For example if the user taps at the top right corner of the circle then the area should be area 2: ">60-120".

The input data I got is:

  • width and height of the frame containing the circle (e.g. 200 pixel wide, 200 pixels height)
  • tap point coordinates

Any suggestion on how to infer in which area the tap point falls given the input data described above?

2
I'd recommend modifying this solution -- stackoverflow.com/a/17039105/2274694 -- to get the angle between the tap point and the frame's center. - Lyndsey Scott
Could it possibly involve using (gasp) math? - matt
@mm24 you achieved the above effect for anti-clockwise and it works as i tried it but i am not able to achieve it for the clockwise effect.can you help me out? - Pratik Shah

2 Answers

8
votes

I just noticed some errors in this solution I'd mentioned in the comments, but it's generally what you need...

I recommend getting the angle between your tap point and your circle's frame's center then implementing a getArea function to get the particular area tapped within your circle, ex:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{
    UITouch *touch = [touches anyObject];
    CGPoint tapPoint = [touch locationInView:self.view];
    CGFloat angle = [self angleToPoint:tapPoint];

    int area = [self sectionForAngle:angle];
}

- (float)angleToPoint:(CGPoint)tapPoint
{
    int x = self.circle.center.x;
    int y = self.circle.center.y;
    float dx = tapPoint.x - x;
    float dy = tapPoint.y - y;
    CGFloat radians = atan2(dy,dx); // in radians
    CGFloat degrees = radians * 180 / M_PI; // in degrees

    if (degrees < 0) return fabsf(degrees);
    else return 360 - degrees;
}

- (int)sectionForAngle:(float)angle
{
    if (angle >= 0 && angle < 60) {
        return 1;
    } else if (angle >= 60 && angle < 120) {
        return 2;
    } else if (angle >= 120 && angle < 180) {
        return 3;
    } else if (angle >= 180 && angle < 240) {
        return 4;
    } else if (angle >= 240 && angle < 300) {
        return 5;
    } else {
        return 6;
    }
}
0
votes
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
         let touch = touches.first
         let tapPoint = touch?.location(in: self)
         let distance = distanceWithCenter(center: circleCenter,SCCenter: tapPoint!)
                if distance <= radius {
                 let angle  = angleToPoint(tapPoint: tapPoint!)
                 print(angle)
        }


func angleToPoint(tapPoint:CGPoint) -> CGFloat{
            let dx =  circleCenter.x - tapPoint.x
            let dy =  circleCenter.y - tapPoint.y
            let radians = atan2(dy, dx) + π // Angel in radian

            let degree = radians * (180 / π)  // Angel in degree
            print("angle is off = \(degree)")
            return degree
        }

You got the angle now check in which section it belong.You can figure it out by comparision.If you face any problem please let me know .