这是我的代码片段。我试图将我的对象绑定在一个圆圈而不是一个正方形,但我的代码有些问题我无法弄清楚。我有两个有效的矩形边界和不起作用的圆形边界。
// 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代表我试图约束的对象(操纵杆)。我想我可以尝试使用简单的触发器将操纵杆限制在一个圆圈,但我想我错了。
设置圆形约束的最佳方法是什么?
答案 0 :(得分:3)
代码似乎已计算出点(0,0)的角度,然后基于将x与该角度的某个函数进行比较来对其进行界定。例如,75 * Math.cos(angle)
在-75到+75之间变化,而您希望将该点与圆心比较。
设置圆心(cx
和cy
)的变量以及x和y坐标(dx
和dy
)的差异。
然后,您想测试距离中心的距离是否超出了您想要的半径(通常这是通过距离的平方来完成的,因为它避免了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 + cx
,dy + cy
)将位于cx
,cy
和r
定义的圈内。
答案 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);
}