问题描述
我将开发一个二维球类游戏,其中两个球(圆圈)发生碰撞.现在我在确定碰撞点时遇到了问题(实际上,确定它们是否在 x 轴/y 轴上碰撞).我有一个想法,当 2 个球的 y 坐标之间的差异大于 x 坐标差异时,它们会在 y 轴上发生碰撞,否则,它们会在 x 轴上发生碰撞.我的想法正确吗?我在我的游戏中实现了这个东西.通常它运行良好,但有时会失败.谁能告诉我我的想法是否正确?如果不是,那为什么?还有什么更好的方法?
I am going to develop a 2-d ball game where two balls (circles) collide. Now I have the problem with determining the colliding point (in fact, determining whether they are colliding in x-axis/y-axis). I have an idea that when the difference between the y coordinate of 2 balls is greater than the x coordinate difference then they collide in their y axis, otherwise, they collide in their x axis. Is my idea correct? I implemented this thing in my games. Normally it works well, but sometimes, it fails. Can anyone tell me whether my idea is right? If not, then why, and is any better way?
x 轴上的碰撞是指圆的第 1、4、5 或 8 八分圆,y 轴指圆的第 2、3、6 或 7 八分圆.
By collision in the x axis, I mean the circle's 1st, 4th, 5th, or 8th octant, y axis means the circle's 2nd, 3rd, 6th, or 7th octant.
提前致谢!
推荐答案
圆之间的碰撞很容易.想象一下有两个圆圈:
Collision between circles is easy. Imagine there are two circles:
- C1 以 (x1,y1) 为中心,半径为 r1;
- 中心为 (x2,y2) 且半径为 r2 的 C2.
想象一下,在这两个中心点之间有一条线.从中心点到任一圆边缘的距离,根据定义,等于它们各自的半径.所以:
Imagine there is a line running between those two center points. The distance from the center points to the edge of either circle is, by definition, equal to their respective radii. So:
- 如果圆的边缘相接触,则圆心之间的距离为r1+r2;
- 任何更大的距离,圆圈都不会接触或碰撞;和
- 少一点就会发生碰撞.
因此您可以在以下情况下检测碰撞:
So you can detect collision if:
(x2-x1)^2 + (y1-y2)^2 <= (r1+r2)^2
表示中心点之间的距离小于半径之和.
meaning the distance between the center points is less than the sum of the radii.
同样的原理可以应用于检测三维球体之间的碰撞.
The same principle can be applied to detecting collisions between spheres in three dimensions.
如果你想计算碰撞点,一些基本的三角学可以做到这一点.你有一个三角形:
if you want to calculate the point of collision, some basic trigonometry can do that. You have a triangle:
(x1,y1)
|
|
| sqrt((x2-x1)^2 + (y2-y1)^2) = r1+r2
|y2-y1| |
|
| X
(x1,y2) +------+ (x2,y2)
|x2-x1|
表达式|x2-x1|
和|y2-y1|
是绝对值.所以对于角度 X:
The expressions |x2-x1|
and |y2-y1|
are absolute values. So for the angle X:
|y2 - y1|
sin X = -------
r1 + r2
|x2 - x1|
cos X = -------
r1 + r2
|y2 - y1|
tan X = -------
|x2 - x1|
获得角度后,您可以通过将它们应用于新三角形来计算交点:
Once you have the angle you can calculate the point of intersection by applying them to a new triangle:
+
|
|
b | r2
|
| X
+-----+
a
哪里:
a
cos X = --
r2
所以
a = r2 cos X
从前面的公式:
|x2 - x1|
a = r2 -------
r1 + r2
一旦你有了 a 和 b,你就可以根据 (x2,y2) 偏移量 (a,b) 来计算碰撞点.您甚至不需要为此计算任何正弦、余弦或反正弦或余弦.或者任何平方根.所以它很快.
Once you have a and b you can calculate the collision point in terms of (x2,y2) offset by (a,b) as appropriate. You don't even need to calculate any sines, cosines or inverse sines or cosines for this. Or any square roots for that matter. So it's fast.
但是,如果您不需要精确的角度或碰撞点,而只需要八分圆,您可以通过了解有关切线的知识来进一步优化:
But if you don't need an exact angle or point of collision and just want the octant you can optimize this further by understanding something about tangents, which is:
- 0
- tan X >= 1 for 45
- 0 >= tan X >= -1 for 0 >= X => -45;
- tan X = X => -90;和
- tan X = tan (X+180) = tan (X-180).
这四个度数范围对应于圆的四个八分圆.其他四个偏移了 180 度.如上所示,切线可以简单地计算为:
Those four degree ranges correspond to four octants of the cirlce. The other four are offset by 180 degrees. As demonstrated above, the tangent can be calculated simply as:
|y2 - y1|
tan X = -------
|x2 - x1|
去掉绝对值,这个比率会告诉你碰撞在四个八分圆中的哪一个(通过上述切线范围).要计算出确切的八分圆,只需比较 x1 和 x2 以确定哪个是最左边的.
Lose the absolute values and this ratio will tell you which of the four octants the collision is in (by the above tangent ranges). To work out the exact octant just compare x1 and x2 to determine which is leftmost.
另一单碰撞的八分圆是偏移的(C1上的八分圆1表示C2、2和6、3和7、4和8等上的八分圆).
The octant of the collision on the other single is offset (octant 1 on C1 means octant 5 on C2, 2 and 6, 3 and 7, 4 and 8, etc).
这篇关于圆圆碰撞的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!