在 Brick Breaker 游戏中使用 atan2() 查找对象的交点
Using atan2() to find the intersection point of objects in a Brick Breaker game
我正在查看由 r3ticuli(GitHub 的用户)创建的打砖块游戏的源代码。下面的方法检查两个对象是否相交,如果相交,该方法检查 returns 主对象的哪一部分被另一个接触。
该方法是 GameObject class 的一部分(桨、砖和球都是此 class 的子class) class 对象的 x 和y 坐标从对象的左上角开始。编写此代码的程序员仅使用 paddle 或 brick 调用此方法,并将 ball 作为参数传递给 main 方法。
我花了两天时间来理解这个逻辑是如何工作的。我知道变量 theta 计算两个对象中心之间的矢量角度。但是,我不明白变量 diagTheta 的用途是什么,以及该方法如何确定对象的哪一部分与另一部分互连。
感谢您的支持。
*如果我的问题有问题,我会解决。
/**
* Compute whether two GameObjects intersect.
*
* @param other
* The other game object to test for intersection with.
* @return NONE if the objects do not intersect. Otherwise, a direction
* (relative to <code>this</code>) which points towards the other
* object.
*/
public Intersection intersects(GameObject other) {
if ( other.x > x + width
|| other.y > y + height
|| other.x + other.width < x
|| other.y + other.height < y)
return Intersection.NONE;
// compute the vector from the center of this object to the center of
// the other
double dx = other.x + other.width /2 - (x + width /2);
double dy = other.y + other.height/2 - (y + height/2);
double theta = Math.atan2(dy, dx); // In here, theta means the angle between objects. from original to the other object (center to center).
double diagTheta = Math.atan2(height, width); // This is angle from (x,y) to its opposite tip side of the shape.
if ( -diagTheta <= theta && theta <= diagTheta )
return Intersection.RIGHT;
if ( diagTheta <= theta && theta <= Math.PI - diagTheta )
return Intersection.DOWN;
if ( Math.PI - diagTheta <= theta || theta <= diagTheta - Math.PI )
return Intersection.LEFT;
// if ( diagTheta - Math.PI <= theta && theta <= diagTheta)
return Intersection.UP;
}
在这幅图中,(dx dy)是红色箭头,它从this
指向other
。而(width, height)就是蓝色箭头,也就是this
的对角线。 atan2 函数将 return 箭头的角度,从 -pi 到 +pi,其中零指向右,正向上,负向下。
在图中你可以看到蓝色箭头比红色箭头更正,即更接近pi。因此 diagTheta 约为 2.9,theta 约为 2.5。那有意义吗?
当你运行通过逻辑,可以看到returns UP
,也就是说other
框在this
上面盒子.
当您将 other
框移动到不同位置时,红色箭头会发生变化,并且您会得到不同的 theta
值。尝试几种可能性并亲自确认逻辑 return 是正确的结果。
我正在查看由 r3ticuli(GitHub 的用户)创建的打砖块游戏的源代码。下面的方法检查两个对象是否相交,如果相交,该方法检查 returns 主对象的哪一部分被另一个接触。
该方法是 GameObject class 的一部分(桨、砖和球都是此 class 的子class) class 对象的 x 和y 坐标从对象的左上角开始。编写此代码的程序员仅使用 paddle 或 brick 调用此方法,并将 ball 作为参数传递给 main 方法。
我花了两天时间来理解这个逻辑是如何工作的。我知道变量 theta 计算两个对象中心之间的矢量角度。但是,我不明白变量 diagTheta 的用途是什么,以及该方法如何确定对象的哪一部分与另一部分互连。
感谢您的支持。 *如果我的问题有问题,我会解决。
/**
* Compute whether two GameObjects intersect.
*
* @param other
* The other game object to test for intersection with.
* @return NONE if the objects do not intersect. Otherwise, a direction
* (relative to <code>this</code>) which points towards the other
* object.
*/
public Intersection intersects(GameObject other) {
if ( other.x > x + width
|| other.y > y + height
|| other.x + other.width < x
|| other.y + other.height < y)
return Intersection.NONE;
// compute the vector from the center of this object to the center of
// the other
double dx = other.x + other.width /2 - (x + width /2);
double dy = other.y + other.height/2 - (y + height/2);
double theta = Math.atan2(dy, dx); // In here, theta means the angle between objects. from original to the other object (center to center).
double diagTheta = Math.atan2(height, width); // This is angle from (x,y) to its opposite tip side of the shape.
if ( -diagTheta <= theta && theta <= diagTheta )
return Intersection.RIGHT;
if ( diagTheta <= theta && theta <= Math.PI - diagTheta )
return Intersection.DOWN;
if ( Math.PI - diagTheta <= theta || theta <= diagTheta - Math.PI )
return Intersection.LEFT;
// if ( diagTheta - Math.PI <= theta && theta <= diagTheta)
return Intersection.UP;
}
在这幅图中,(dx dy)是红色箭头,它从this
指向other
。而(width, height)就是蓝色箭头,也就是this
的对角线。 atan2 函数将 return 箭头的角度,从 -pi 到 +pi,其中零指向右,正向上,负向下。
在图中你可以看到蓝色箭头比红色箭头更正,即更接近pi。因此 diagTheta 约为 2.9,theta 约为 2.5。那有意义吗?
当你运行通过逻辑,可以看到returns UP
,也就是说other
框在this
上面盒子.
当您将 other
框移动到不同位置时,红色箭头会发生变化,并且您会得到不同的 theta
值。尝试几种可能性并亲自确认逻辑 return 是正确的结果。