檯球碰撞算法研究

說好的八月發文藝貼,又發一個技術貼,真不好意思。
其實文藝貼之前寫了《青灰色年華》,發到我CSDN博客了。。。
影射的太深,不好,也不想發在人多的地方。
閒話不提。
球類碰撞是一類比較普遍的問題。
根據動量定理、動能定理列出方程,
然後解方程分別算出兩個球碰撞之後的速度。
三個球同時碰撞也是一樣。
雖然高中只學過一條直線上的動量定理,
但我還是很碉堡地研究出不在一條直線上的碰撞。
動能定理沒有矢量性,跟一條直線上的一樣。
不在一條直線上的碰撞,可以分解成,在兩個小球圓心連線上方向的動量守恆。(1個方程)
或者分解成X軸Y軸分別的速度,列兩個方程。
寫程序一般都用X軸Y軸的速度,我列了4個方程式:
 

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){}

我是懶得解方程了。。。太麻煩了。

上圖,界面純代碼繪製。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章