t.vx t.vy已知 ,t.x,t.y,b.x,b.y已知,
求t.vx后 t.vy后 b.vx b.vy四个未知量:
t.vx = t.vx后 + b.vx
t.vy = t.vy后 + b.vy
t.vx平方 + t.vy平方 =t.vx后 平方 + t.vy后 平方 + b.vx平方 + b.vy平方
还有一个方程是b.vx和b.vy的比值。
4个方程4个未知数,可以解出来。。。
部分源码:
class Ball{
double X = 0,Y = 0;/*球所在正方形左上角*/
double vx = 0,vy = 0;
Color clr = null;
boolean []crlst = new boolean[10];
boolean vsble = true;
public Ball(){
}
public Ball(int x,int y,Color clr){
this.X=x;
this.Y=y;
this.clr=clr;
}
public void overturnx(){
this.vx=-vx;
}
public void overturny(){
this.vy=-vy;
}
/*生命在于运动*/
public void lifeIsMove(){
this.X += this.vx;
this.Y += this.vy;
}
public void vslow(){
double x,y;
x=this.vx;
y=this.vy;
if(x>0){
if(this.vx>=0.01){
this.vx -= x/Math.sqrt(Math.hypot(x,y))/80;
//mBall.vx *= 0.9;
}
else
this.vx=0;
}
if(x<0){
if(this.vx<=-0.01){
this.vx -= x/Math.sqrt(Math.hypot(x,y))/80;
//mBall.vx *= 0.9;
}
else
this.vx=0;
}
if(y>0){
if(this.vy>=0.01){
this.vy -= y/Math.sqrt(Math.hypot(x,y))/80;
//mBall.vy *= 0.9;
}
else
this.vy = 0;
}
else{
if(this.vy<=-0.01){
this.vy -= y/Math.sqrt(Math.hypot(x,y))/80;
//mBall.vy *= 0.9;
}
else
this.vy = 0;
}
}
public boolean isCrash(Ball b){
double x = this.X-b.X;
double y = this.Y-b.Y;
double p = this.vx*this.vx+this.vy*this.vy;
double q = b.vx*b.vx+b.vy*b.vy;
if(x*x+y*y<=24*24-50 && p+q>0)
return true;
return false;
}
public void crashWith(Ball b){
double k = (this.X-b.X)/(this.Y-b.Y);
b.vy = (k*this.vx+this.vy)/(k*k+1);
b.vx = k*b.vy;
this.vx-=b.vx;
this.vy-=b.vy;
}
public void crashWith(Ball b2,Ball b3){
/*众所周知,我是一个很懒的人*/
/*三球同时碰撞的方法,我不写了*/
/*写起来也类似,用动量定理+动能定理*/
/*不过就复杂一些*/
/*我把三球碰撞的情况看成了一个球碰一个球
* 再过一个极短瞬间碰另一个
* 这样虽然不是很好,但也凑合
* 就是这个意思,有兴趣的可以试试*/
}
}没错,就这么几行。
视为完全的弹性碰撞。
只有运动时才会有摩擦力减速。
多球碰撞我理想成了先和一个碰撞,然后过一个极短的瞬间,再和另外一个碰撞。
实际上这样不是很好,但在实际中,谁也不敢说就是真正的同时碰撞,1毫秒都不差。
多球碰撞代码也可以写的,重载crashWith(Ball b2,Ball b3){}
我是懒得解方程了。。。太麻烦了。
上图,界面纯代码绘制。