将操纵杆绑定到圆圈

时间:2014-06-24 17:16:08

标签: java math

这是我的代码片段。我试图将我的对象绑定在一个圆圈而不是一个正方形,但我的代码有些问题我无法弄清楚。我有两个有效的矩形边界和不起作用的圆形边界。

        // get the pos
        _touchingPoint.x = (int)event.getX();
        _touchingPoint.y = (int)event.getY();

        angle = Math.atan2(_touchingPoint.y , _touchingPoint.x);

        // bound to a box
        if( _touchingPoint.x < 75){
            _touchingPoint.x = 75;
        }
        if ( _touchingPoint.x > 225){
            _touchingPoint.x = 225;
        }
        if (_touchingPoint.y < 300){
            _touchingPoint.y = 300;
        }
        if ( _touchingPoint.y > 450 ){
            _touchingPoint.y = 450;
        }
        //bound to a circle
        if( _touchingPoint.x < 75 * Math.cos(angle))
        {
            _touchingPoint.x = (int) (75 * Math.cos(angle));
        }
        if ( _touchingPoint.x > 225 * Math.cos(angle))
        {
            _touchingPoint.x = (int) (225 * Math.cos(angle));
        }
        if ( _touchingPoint.y < 300 * Math.sin(angle))
        {
            _touchingPoint.y = (int) (300 * Math.sin(angle));
        }
        if ( _touchingPoint.y > 450 * Math.sin(angle))
        {
            _touchingPoint.y = (int) (450 * Math.sin(angle));
        }

_touchingPoint.x和_touchingPoint.y代表我试图约束的对象(操纵杆)。我想我可以尝试使用简单的触发器将操纵杆限制在一个圆圈,但我想我错了。

设置圆形约束的最佳方法是什么?

3 个答案:

答案 0 :(得分:3)

代码似乎已计算出点(0,0)的角度,然后基于将x与该角度的某个函数进行比较来对其进行界定。例如,75 * Math.cos(angle)在-75到+75之间变化,而您希望将该点与圆心比较。

设置圆心(cxcy)的变量以及x和y坐标(dxdy)的差异。

然后,您想测试距离中心的距离是否超出了您想要的半径(通常这是通过距离的平方来完成的,因为它避免了sqrt操作 - dx*dx+dy*dy>r*r)。

如果距离大于半径,则使用trig或缩放差异投射回圆圈:

double dx = event.getX() - cx;
double dy = event.getY() - cy;
double d2 = dx*dx+dy*dy;

if(d2>r*r) {
   double scale = r / Math.sqrt(d2);
   dx*=scale;
   dy*=scale;
}

然后(dx + cxdy + cy)将位于cxcyr定义的圈内。

答案 1 :(得分:3)

您似乎试图将位置限制为圆形磁盘,而不是将其作为边界的圆。我通过从中心重新调整偏移矢量来实现这一目标:

    double dx = event.getX() - 150;
    double dy = event.getY() - 375;
    double len = Math.hypot(dx, dy);
    if (len > 75) {
      dx = dx*75/len;
      dy = dy*75/len;
    }
    _touchingPoint.x = (int)dx + 150;
    _touchingPoint.y = (int)dy + 375;

答案 2 :(得分:2)

除非我遗漏了某些内容,否则就会出现这样的问题:

===编辑===正如Pete所指出的那样,我遗失的一件事就是如何计算angle

angle = atan2(y - 375, x - 150);

===编辑结束===

a = _touchingPoint.x;
b = _touchingPoint.y;

if((a-150)*(a-150) + (b-375)*(b-375) > 75*75){
  _touchingPoint.x = 150 + 75*cos(angle);
  _touchingPoint.y = 375 + 75*sin(angle);

}