iOS:在给定圆内,推导出点击点的角度

3
我有一个显示分为六个等边三角形的圆的UIImageView,对应如下内容:
  • 0-60度之间的区域1
  • >60-120度之间的区域2
  • >120-180度之间的区域3
  • >180-240度之间的区域4
  • >240-300度之间的区域5
  • >300-360度之间的区域6
圆类似于以下图示(请原谅我糟糕的绘画技能):

enter image description here

我想从触摸点中推断出所在的区域。例如,如果用户在圆的右上角轻触,则该区域应为区域2:“> 60-120”。
我得到的输入数据是:
  • 包含圆的框架的宽度和高度(例如,200像素宽,200像素高)
  • 轻触点坐标
您有关于如何通过上述输入数据推断轻触点所处的区域的任何建议吗?

1
我建议修改这个解决方案 - http://stackoverflow.com/a/17039105/2274694 - 以获取触摸点和框架中心之间的角度。 - Lyndsey Scott
2
可能会涉及使用(吸气)数学吗? - matt
@mm24,你已经成功实现了逆时针的效果,并且我已经尝试过它,它确实有效。但是我无法实现顺时针的效果,你能帮我吗? - Pratik Shah
2个回答

8
我刚注意到在我之前评论中提到的 这个解决方案 中存在一些错误,但这通常是您所需要的...
我建议获取您的触控点与您圆形帧的中心之间的角度,然后实现一个 getArea 函数来获取您圆形中特定的被点击区域,例如:
-(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;
    }
}

非常感谢。它完美地运行了。感谢您抽出时间编辑评论和解决方案。 - mm24
@mm24 没问题。 :) 是的,实际上这个问题比我链接中所暗示的答案更加复杂,因为通过测试我了解到 atan2 可以返回正或负弧度,所以我必须在我的 angleToPoint: 返回值中考虑到这一点。 - Lyndsey Scott
@LyndseyScott,你已经成功实现了逆时针的效果,并且我已经尝试过它,它确实有效。但是我无法实现顺时针的效果,你能帮我吗? - Pratik Shah

0
    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
        }

你已经得到了角度,现在检查它属于哪个部分。你可以通过比较来找出答案。如果遇到任何问题,请告诉我。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接