問題描述
我正在嘗試編寫一個 Java 移動應用程序 (J2ME),但遇到了一個問題:在我的項目中,有稱為鏡頭的移動圓圈和稱為球體的非移動圓圈.當一個球擊中球體時,它應該按照經典物理定律反彈.但是我找不到這種算法.
I'm trying to write a java mobile application (J2ME) and I got stuck with a problem: in my project there are moving circles called shots, and non moving circles called orbs. When a shot hits an orb, it should bounce off by classical physical laws. However I couldn't find any algorithm of this sort.
鏡頭的運動由 x 軸和 y 軸上的速度(像素/更新)來描述.所有關于圓的信息都是已知的:它們的位置、半徑和鏡頭的速度(在 x 軸和 y 軸上).
The movement of a shot is described by velocity on axis x and y (pixels/update). all the information about the circles is known: their location, radius and the speed (on axis x and y) of the shot.
注意:碰撞后球體不會開始移動,它會停留在原位.碰撞是兩者之間的彈性碰撞,而球體保持靜止
Note: the orb does not start moving after the collision, it stays at its place. The collision is an elastic collision between the two while the orb remains static
這里是Shot類中的碰撞解決方法:
here is the collision solution method in class Shot:
public void collision(Orb o)
{
//the orb's center point
Point oc=new Point(o.getTopLeft().x+o.getWidth()/2,o.getTopLeft().y+o.getWidth()/2);
//the shot's center point
Point sc=new Point(topLeft.x+width/2,topLeft.y+width/2);
//variables vx and vy are the shot's velocity on axis x and y
if(oc.x==sc.x)
{
vy=-vy;
return ;
}
if(oc.y==sc.y)
{
vx=-vx;
return ;
}
// o.getWidth() returns the orb's width, width is the shot's width
double angle=0; //here should be some sort of calculation of the shot's angle
setAngle(angle);
}
public void setAngle(double angle)
{
double v=Math.sqrt(vx*vx+vy*vy);
vx=Math.cos(Math.toRadians(angle))*v;
vy=-Math.sin(Math.toRadians(angle))*v;
}
提前感謝所有幫助者
推薦答案
在碰撞點,動量、角動量和能量被保存下來.設m1,m2為圓盤的質量,p1=(p1x,p1y),p2=(p2x,p2y)為碰撞時圓盤中心的位置,u1,u2為碰撞前的速度,v1,v2為碰撞后的速度碰撞.然后守恒定律要求
At the point of collision, momentum, angular momentum and energy are preserved. Set m1, m2 the masses of the disks, p1=(p1x,p1y), p2=(p2x,p2y) the positions of the centers of the disks at collition time, u1, u2 the velocities before and v1,v2 the velocities after collision. Then the conservation laws demand that
0 = m1*(u1-v1)+m2*(u2-v2)
0 = m1*cross(p1,u1-v1)+m2*cross(p2,u2-v2)
0 = m1*dot(u1-v1,u1+v1)+m2*dot(u2-v2,u2+v2)
使用第一個方程消除 u2-v2
Eliminate u2-v2 using the first equation
0 = m1*cross(p1-p2,u1-v1)
0 = m1*dot(u1-v1,u1+v1-u2-v2)
第一個告訴我們 (u1-v1) 和因此 (u2-v2) 是 (p1-p2) 的倍數,脈沖交換是在法線或徑向方向,沒有切向相互作用.沖動和能量守恒現在導致相互作用常數a
,因此
The first tells us that (u1-v1) and thus (u2-v2) is a multiple of (p1-p2), the impulse exchange is in the normal or radial direction, no tangential interaction. Conservation of impulse and energy now leads to a interaction constant a
so that
u1-v1 = m2*a*(p1-p2)
u2-v2 = m1*a*(p2-p1)
0 = dot(m2*a*(p1-p2), 2*u1-m2*a*(p1-p2)-2*u2+m1*a*(p2-p1))
導致非零交互項 a
2 * dot(p1-p2, u1-u2) = (m1+m2) * dot(p1-p2,p1-p2) * a
現在可以使用分數來解決
which can now be solved using the fraction
b = dot(p1-p2, u1-u2) / dot(p1-p2, p1-p2)
作為
a = 2/(m1+m2) * b
v1 = u1 - 2 * m2/(m1+m2) * b * (p1-p2)
v2 = u2 - 2 * m1/(m1+m2) * b * (p2-p1)
要讓第二個圓盤靜止,設置 u2=0 并且它的質量 m2 非常大或無限大,然后第二個公式說 v2=u2=0 和第一個
To get the second disk stationary, set u2=0 and its mass m2 to be very large or infinite, then the second formula says v2=u2=0 and the first
v1 = u1 - 2 * dot(p1-p2, u1)/dot(p1-p2, p1-p2) * (p1-p2)
<小時>
也就是說,v1 是 u1 在以 (p1-p2) 為法線的平面上的反射.請注意,碰撞點的特征是 norm(p1-p2)=r1+r2
或
dot(p1-p2, p1-p2) = (r1+r2)^2
這樣分母就已經從碰撞檢測中知道了.
so that the denominator is already known from collision detection.
根據您的代碼,oc{x,y}
包含固定磁盤或球體的中心,sc{x,y}
包含中心和 {vx,vy}
移動磁盤的速度.
Per your code, oc{x,y}
contains the center of the fixed disk or orb, sc{x,y}
the center and {vx,vy}
the velocity of the moving disk.
計算
dc={sc.x-oc.x, sc.y-oc.y}
和dist2=dc.x*dc.x+dc.y*dc.y
1.a 檢查 sqrt(dist2)
是否足夠接近 sc.radius+oc.radius
.普遍的傳說說比較正方形更有效.如果 dist2 太小,微調交點的位置.
1.a Check that sqrt(dist2)
is sufficiently close to sc.radius+oc.radius
. Common lore says that comparing the squares is more efficient. Fine-tune the location of the intersection point if dist2 is too small.
計算 dot = dc.x*vx+dcy*vy
和 dot = dot/dist2
更新vx = vx - 2*dot*dc.x
, vy = vy - 2*dot*dc.y
特殊情況包含在這些公式中,例如,對于 dc.y==0
,即 oc.y==sc.y
得到 dot=vx/dc.x
,所以 vx=-vx
, vy=vy
結果.
The special cases are contained inside these formulas, e.g., for dc.y==0
, that is, oc.y==sc.y
one gets dot=vx/dc.x
, so that vx=-vx
, vy=vy
results.
這篇關于動圈與非動圈的JAVA彈性碰撞的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!