3 回答

TA貢獻1850條經驗 獲得超11個贊
圓圈之間的碰撞很容易。想象有兩個圈子:
具有中心(x1,y1)和半徑r1的C1;
中心(x2,y2)和半徑r2的C2。
想象一下,在這兩個中心點之間有一條直線。根據定義,從中心點到每個圓的邊緣的距離等于它們各自的半徑。所以:
如果圓的邊緣接觸,則中心之間的距離為r1 + r2;
更遠的距離,圓圈不會碰觸或碰撞;和
然后減少碰撞。
因此,您可以在以下情況下檢測碰撞:
(x2-x1)^2 + (y1-y2)^2 <= (r1+r2)^2
表示中心點之間的距離小于半徑的總和。
可以將相同原理應用于檢測三維球體之間的碰撞。
編輯:如果要計算碰撞點,則可以使用一些基本的三角函數來實現。你有一個三角形:
(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:
|y2 - y1|
sin X = -------
r1 + r2
|x2 - x1|
cos X = -------
r1 + r2
|y2 - y1|
tan X = -------
|x2 - x1|
一旦有了角度,就可以通過將它們應用于新三角形來計算相交點:
+
|\
| \
b | \ r2
| \
| X \
+-----+
a
哪里:
a
cos X = --
r2
所以
a = r2 cos X
根據以前的公式:
|x2 - x1|
a = r2 -------
r1 + r2
一旦有了a和b,就可以根據(x,y2)偏移(a,b)的方式計算碰撞點。您甚至不需要為此計算任何正弦,余弦或反正弦或余弦?;蚺c此相關的任何平方根。這樣很快。
但是,如果您不需要精確的碰撞角度或碰撞點,而只想八分圓,則可以通過了解切線來進一步優化它,這是:
0 <= tan X <= 1表示0 <= X <= 45度;
tan X> = 1表示45 <= X <= 90
0> = tan X> = -1表示0> = X => -45;
tan X <= -1表示-45> = X => -90; 和
棕褐色X =棕褐色(X + 180)=棕褐色(X-180)。
這四個度范圍對應于圓的四個八分圓。其他四個偏移180度。如上所示,正切可以簡單地計算為:
|y2 - y1|
tan X = -------
|x2 - x1|
失去絕對值,該比率將告訴您碰撞在四個八分之一中(通過上述切線范圍)。要計算出確切的八分圓,只需比較x1和x2以確定哪一個最左邊。
另一個碰撞上的碰撞的八分圓是偏移的(C1上的八分圓1表示C2、2和6、3和7、4和8等上的八分圓)。

TA貢獻2016條經驗 獲得超9個贊
您想使用兩個球的半徑之和。您要計算球的中心之間的總距離,如下所示:
Ball 1:? center: p1=(x1,y1)? radius: r1
Ball 2:? center: p2=(x2,y2)? radius: r2
collision distance: R= r1 + r2
actual distance:? ? r12= sqrt( (x2-x1)^2 + (y2-y2)^2 )
只要(r12 <R),就會發生碰撞。正如Artelius所說,它們實際上不應在x / y軸上發生碰撞,而是以特定角度發生碰撞。除此以外,您實際上并不想要那個角度。您想要碰撞矢量。這是兩個圓心碰撞時的中心之間的差異:
collision vector: d12= (x2-x1,y2-y1) = (dx,dy)
actual distance:? r12= sqrt( dx*dx + dy*dy )
請注意,在計算實際距離時,您已經在上面計算了dx和dy,因此出于這種目的,您最好也可以對其進行跟蹤。您可以使用此碰撞向量來確定球的新速度-您將最終通過某些因素縮放碰撞向量,并將其添加到舊速度中……但是,要返回到實際碰撞點:
collision point:? 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 }
至于為什么它可能會失敗,很難在沒有更多信息的情況下知道,但是您可能會遇到一個問題,即您的球移動得太快,并且在一個時間步中彼此直傳。有一些方法可以解決此問題,但是最簡單的方法是確保它們不會太快地移動...

TA貢獻1804條經驗 獲得超3個贊
該站點解釋了物理原理,推導了算法,并提供了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
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
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,
vector vai, vector vbi, vector wai, vector wbi, vector vaf, vector vbf, vector waf, vector wbf) {
double k=1/(ma*ma)+ 2/(ma*mb) +1/(mb*mb) - ra.x*ra.x/(ma*Ia) - rb.x*rb.x/(ma*Ib) - ra.y*ra.y/(ma*Ia)
- ra.y*ra.y/(mb*Ia) - ra.x*ra.x/(mb*Ia) - rb.x*rb.x/(mb*Ib) - rb.y*rb.y/(ma*Ib)
- 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);
double Jx = (e+1)/k * (Vai.x - Vbi.x)( 1/ma - ra.x*ra.x/Ia + 1/mb - rb.x*rb.x/Ib)
- (e+1)/k * (Vai.y - Vbi.y) (ra.x*ra.y / Ia + rb.x*rb.y / Ib);
double Jy = - (e+1)/k * (Vai.x - Vbi.x) (ra.x*ra.y / Ia + rb.x*rb.y / Ib)
+ (e+1)/k * (Vai.y - Vbi.y) ( 1/ma - ra.y*ra.y/Ia + 1/mb - rb.y*rb.y/Ib);
Vaf.x = Vai.x - Jx/Ma;
Vaf.y = Vai.y - Jy/Ma;
Vbf.x = Vbi.x - Jx/Mb;
Vbf.y = Vbi.y - Jy/Mb;
waf.x = wai.x - (Jx*ra.y - Jy*ra.x) /Ia;
waf.y = wai.y - (Jx*ra.y - Jy*ra.x) /Ia;
wbf.x = wbi.x - (Jx*rb.y - Jy*rb.x) /Ib;
wbf.y = wbi.y - (Jx*rb.y - Jy*rb.x) /Ib;
}
添加回答
舉報