圆圆碰撞.

我要开发一个二维球游戏,其中两个球(圆)碰撞。现在,我遇到了确定碰撞点的问题(实际上是确定它们是否在x轴/ y轴上碰撞)。我有一个想法,当2个球的y坐标之间的差大于x坐标差时,它们将在其y轴上碰撞,否则,它们将在其x轴上碰撞。我的想法正确吗?我在游戏中实现了这个东西。通常,它运作良好,但有时会失败。谁能告诉我我的想法是否正确?如果不是,那为什么呢,还有更好的方法吗?

x轴上的碰撞是指圆的第1、4、5或8个八分圆,y轴是指圆的第2、3、6、7号圆。

提前致谢!


回首忆惘然
浏览 636回答 3
3回答

宝慕林4294392

圆圈之间的碰撞很容易。想象有两个圈子:具有中心(x1,y1)和半径r1的C1;中心(x2,y2)和半径r2的C2。想象一下,在这两个中心点之间有一条直线。根据定义,从中心点到每个圆的边缘的距离等于它们各自的半径。所以:如果圆的边缘接触,则中心之间的距离为r1 + r2;更远的距离,圆圈不会碰触或碰撞;和然后减少碰撞。因此,您可以在以下情况下检测碰撞:(x2-x1)^2 + (y1-y2)^2 <= (r1+r2)^2表示中心点之间的距离小于半径的总和。可以将相同原理应用于检测三维球体之间的碰撞。编辑:如果要计算碰撞点,则可以使用一些基本的三角函数来实现。你有一个三角形:&nbsp; &nbsp; &nbsp; &nbsp; (x1,y1)&nbsp; &nbsp; &nbsp; &nbsp; |\&nbsp; &nbsp; &nbsp; &nbsp; | \&nbsp; &nbsp; &nbsp; &nbsp; |&nbsp; \ sqrt((x2-x1)^2 + (y2-y1)^2) = r1+r2|y2-y1| |&nbsp; &nbsp;\&nbsp; &nbsp; &nbsp; &nbsp; |&nbsp; &nbsp; \&nbsp; &nbsp; &nbsp; &nbsp; |&nbsp; &nbsp;X \(x1,y2) +------+ (x2,y2)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|x2-x1|表达式|x2-x1|和|y2-y1|是绝对值。因此对于角度X:&nbsp; &nbsp; &nbsp; &nbsp; |y2 - y1|sin X =&nbsp; -------&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;r1 + r2&nbsp; &nbsp; &nbsp; &nbsp; |x2 - x1|cos X =&nbsp; -------&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;r1 + r2&nbsp; &nbsp; &nbsp; &nbsp; |y2 - y1|tan X =&nbsp; -------&nbsp; &nbsp; &nbsp; &nbsp; |x2 - x1|一旦有了角度,就可以通过将它们应用于新三角形来计算相交点:&nbsp; +&nbsp; |\&nbsp; | \b |&nbsp; \ r2&nbsp; |&nbsp; &nbsp;\&nbsp; |&nbsp; X \&nbsp; +-----+&nbsp; &nbsp; &nbsp;a哪里:&nbsp; &nbsp; &nbsp; &nbsp; acos X = --&nbsp; &nbsp; &nbsp; &nbsp; r2所以a = r2 cos X根据以前的公式:&nbsp; &nbsp; &nbsp; &nbsp;|x2 - x1|a = r2 -------&nbsp; &nbsp; &nbsp; &nbsp; r1 + r2一旦有了a和b,就可以根据(x,y2)偏移(a,b)的方式计算碰撞点。您甚至不需要为此计算任何正弦,余弦或反正弦或余弦。或与此相关的任何平方根。这样很快。但是,如果您不需要精确的碰撞角度或碰撞点,而只想八分圆,则可以通过了解切线来进一步优化它,这是:0 <= tan X <= 1表示0 <= X <= 45度;tan X> = 1表示45 <= X <= 900> = tan X> = -1表示0> = X => -45;tan X <= -1表示-45> = X => -90; 和棕褐色X =棕褐色(X + 180)=棕褐色(X-180)。这四个度范围对应于圆的四个八分圆。其他四个偏移180度。如上所示,正切可以简单地计算为:&nbsp; &nbsp; &nbsp; &nbsp; |y2 - y1|tan X =&nbsp; -------&nbsp; &nbsp; &nbsp; &nbsp; |x2 - x1|失去绝对值,该比率将告诉您碰撞在四个八分之一中(通过上述切线范围)。要计算出确切的八分圆,只需比较x1和x2以确定哪一个最左边。另一个碰撞上的碰撞的八分圆是偏移的(C1上的八分圆1表示C2、2和6、3和7、4和8等上的八分圆)。

慕后森

正如cletus所说,您想使用两个球的半径之和。您要计算球的中心之间的总距离,如下所示:Ball 1:&nbsp; center: p1=(x1,y1)&nbsp; radius: r1Ball 2:&nbsp; center: p2=(x2,y2)&nbsp; radius: r2collision distance: R= r1 + r2actual distance:&nbsp; &nbsp; r12= sqrt( (x2-x1)^2 + (y2-y2)^2 )只要(r12 <R),就会发生碰撞。正如Artelius所说,它们实际上不应在x / y轴上发生碰撞,而是以特定角度发生碰撞。除此以外,您实际上并不想要那个角度。您想要碰撞矢量。这是两个圆心碰撞时的中心之间的差异:collision vector: d12= (x2-x1,y2-y1) = (dx,dy)actual distance:&nbsp; r12= sqrt( dx*dx + dy*dy )请注意,在计算实际距离时,您已经在上面计算了dx和dy,因此出于这种目的,您最好也可以对其进行跟踪。您可以使用此碰撞向量来确定球的新速度-您将最终通过某些因素缩放碰撞向量,并将其添加到旧速度中……但是,要返回到实际碰撞点:collision point:&nbsp; pcollision= ( (x1*r2+x2*r1)/(r1+r2), (y1*r2+y2*r1)/(r1+r2) )为了弄清楚如何找到球的新速度(通常从整体上讲更有意义),您可能应该找到一本高中物理书或同等学历书。不幸的是,我不知道一个好的网络教程-建议,有人吗?哦,如果仍然想坚持使用x / y轴,我认为您可以使用以下方法:if( abs(dx) > abs(dy) ) then { x-axis } else { y-axis }至于为什么它可能会失败,很难在没有更多信息的情况下知道,但是您可能会遇到一个问题,即您的球移动得太快,并且在一个时间步中彼此直传。有一些方法可以解决此问题,但是最简单的方法是确保它们不会太快地移动...

慕虎7371278

该站点解释了物理原理,推导了算法,并提供了2D球碰撞的代码。此函数计算以下内容后计算八分圆:碰撞点相对于物体质心的位置a;碰撞点相对于质心a的位置/**This function calulates the velocities after a 2D collision vaf, vbf, waf and wbf from information about the colliding bodies@param double e coefficient of restitution which depends on the nature of the two colliding materials@param double ma total mass of body a@param double mb total mass of body b@param double Ia inertia for body a.@param double Ib inertia for body b.@param vector ra position of collision point relative to centre of mass of body a in absolute coordinates (if this is&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;known in local body coordinates it must be converted before this is called).@param vector rb position of collision point relative to centre of mass of body b in absolute coordinates (if this is&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;known in local body coordinates it must be converted before this is called).@param vector n normal to collision point, the line along which the impulse acts.@param vector vai initial velocity of centre of mass on object a@param vector vbi initial velocity of centre of mass on object b@param vector wai initial angular velocity of object a@param vector wbi initial angular velocity of object b@param vector vaf final velocity of centre of mass on object a@param vector vbf final velocity of centre of mass on object a@param vector waf final angular velocity of object a@param vector wbf final angular velocity of object b*/CollisionResponce(double e,double ma,double mb,matrix Ia,matrix Ib,vector ra,vector rb,vector n,&nbsp; &nbsp; vector vai, vector vbi, vector wai, vector wbi, vector vaf, vector vbf, vector waf, vector wbf) {&nbsp; double k=1/(ma*ma)+ 2/(ma*mb) +1/(mb*mb) - ra.x*ra.x/(ma*Ia) - rb.x*rb.x/(ma*Ib)&nbsp; - ra.y*ra.y/(ma*Ia)&nbsp; &nbsp; - ra.y*ra.y/(mb*Ia) - ra.x*ra.x/(mb*Ia) - rb.x*rb.x/(mb*Ib) - rb.y*rb.y/(ma*Ib)&nbsp; &nbsp; - rb.y*rb.y/(mb*Ib) + ra.y*ra.y*rb.x*rb.x/(Ia*Ib) + ra.x*ra.x*rb.y*rb.y/(Ia*Ib) - 2*ra.x*ra.y*rb.x*rb.y/(Ia*Ib);&nbsp; double Jx = (e+1)/k * (Vai.x - Vbi.x)( 1/ma - ra.x*ra.x/Ia + 1/mb - rb.x*rb.x/Ib)&nbsp; &nbsp; &nbsp;- (e+1)/k * (Vai.y - Vbi.y) (ra.x*ra.y / Ia + rb.x*rb.y / Ib);&nbsp; double Jy = - (e+1)/k * (Vai.x - Vbi.x) (ra.x*ra.y / Ia + rb.x*rb.y / Ib)&nbsp; &nbsp; &nbsp;+ (e+1)/k&nbsp; * (Vai.y - Vbi.y) ( 1/ma - ra.y*ra.y/Ia + 1/mb - rb.y*rb.y/Ib);&nbsp; Vaf.x = Vai.x - Jx/Ma;&nbsp; Vaf.y = Vai.y - Jy/Ma;&nbsp; Vbf.x = Vbi.x - Jx/Mb;&nbsp; Vbf.y = Vbi.y - Jy/Mb;&nbsp; waf.x = wai.x - (Jx*ra.y - Jy*ra.x) /Ia;&nbsp; waf.y = wai.y - (Jx*ra.y - Jy*ra.x) /Ia;&nbsp; wbf.x = wbi.x - (Jx*rb.y - Jy*rb.x) /Ib;&nbsp; wbf.y = wbi.y - (Jx*rb.y - Jy*rb.x) /Ib;}
打开App,查看更多内容
随时随地看视频慕课网APP