# 碰撞相同程式碼，跑出來的值會不一樣

MainActivity.java

``````B[CURRENT_BALL].Vx = (float) (-(event.getX()-B[CURRENT_BALL].BX)/s);
B[CURRENT_BALL].Vy = (float) (-(event.getY()-B[CURRENT_BALL].BY)/s);
B[CURRENT_BALL].V = (double) (4000);
//位移量X分量
B[i].MX = B[i].Vx*B[i].V*T;
//位移量Y分量
B[i].MY = B[i].Vy*B[i].V*T;

private void BallCollision(){
double T = updateT;
T = T/1000;

for(int i = 0 ; i < B.length ;i++){

if(B[i].V>0){
//hitRect(i);
}
for(int j = i+1 ; j < B.length ;j++){

//碰撞(兩球距離小於等於圓心距)

//同一顆球不判斷喔:)
if(i==j)continue;
if (B[i].V==0 && B[j].V==0) continue;
double rc = (double) countDistance(B[i],B[j]);

//修正小球碰撞距離

//獲取碰撞後的速度增量
double ax = (double) (((B[i].MX - B[j].MX)*Math.pow((B[i].BX - B[j].BX) , 2) + (B[i].MY - B[j].MY)*(B[i].BX - B[j].BX) *(B[i].BY - B[j].BY))/Math.pow(rc , 2));
double ay = (double) (((B[i].MY - B[j].MY)*Math.pow((B[i].BY - B[j].BY) , 2) + (B[i].MX - B[j].MX)*(B[i].BX - B[j].BX)*(B[i].BY - B[j].BY))/Math.pow(rc , 2));
//Log.d("Mine","ax: "+ax);
//將速度增量賦給碰撞小球
B[i].MX =  (B[i].MX- ax);
B[i].MY =  (B[i].MY- ay);
B[j].MX =  (B[j].MX+ ax);
B[j].MY =  (B[j].MY+ ay);

B[i].V =  ((double) (Math.sqrt(Math.pow((B[i].MX),2)+Math.pow((B[i].MY), 2))/T));
B[j].V =  ((double) (Math.sqrt(Math.pow((B[j].MX),2)+Math.pow((B[j].MY), 2))/T));

MoveS1 =  ((double) Math.sqrt(Math.pow((B[i].MX),2)+Math.pow((B[i].MY), 2)));
MoveS2 =  ((double) Math.sqrt(Math.pow((B[j].MX),2)+Math.pow((B[j].MY), 2)));

B[i].Vx =  (B[i].MX/MoveS1);
B[i].Vy =  (B[i].MY/MoveS1);
B[j].Vx =  (B[j].MX/MoveS2);
B[j].Vy =  (B[j].MY/MoveS2);

double cx =  (clength * (B[i].BX-B[j].BX)/rc);
double cy =  (clength * (B[i].BY-B[j].BY) /rc);
B[i].X = (int) (B[i].X+ cx);
B[i].Y = (int) (B[i].Y+ cy);
B[j].X = (int) (B[j].X- cx);
B[j].Y = (int) (B[j].Y- cy);

B[i].BX = (int) (B[i].BX+ cx);
B[i].BY = (int) (B[i].BY+ cy);
B[j].BX = (int) (B[j].BX- cx);
B[j].BY = (int) (B[j].BY- cy);

if(B[i].V>0){
B[i].V = (double) (B[i].V*0.9);
}if(B[j].V>0){
B[i].V = (double) (B[i].V*0.9);

}
}

}

}

}``````

Ball.java

``````public class Ball extends View {
int X;
int Y;
double V;//速度
double A = -10f;//加速度
double width;//長
double height;//寬
int BX;//球心X
int BY;//球心Y
double MX;
double MY;
//double M = 5;
int img;//圖片
Bitmap bitmap;
double Vx =0 , Vy =0;//移動方向 單位向量xy分量

Ball(Context c ,int x , int y , int v , int image){
super(c);
this.X = x;
this.Y = y;
this.V = v;
this.img = image;
bitmap = BitmapFactory.decodeResource(getResources(),img);
this.width = bitmap.getWidth();
this.height = bitmap.getHeight();
this.BX = (int) (x+width/2);
this.BY = (int) (y+height/2);

}
void setMove(double vx , double vy){
this.X = (int) BigDecimal(X+ vx);
this.Y = (int) BigDecimal(Y+ vy);
this.BX =(int) BigDecimal(BX+ vx);
this.BY =(int) BigDecimal(BY+ vy);
//invalidate();
}
void setVX_VY(double vx , double vy){
this.Vx = BigDecimal(vx);
this.Vy = BigDecimal(vy);
}
void setXY(double x , double y){
this.X = (int) BigDecimal(x);
this.Y = (int) BigDecimal(y);
this.BX = (int) BigDecimal(x+this.width);
this.BY = (int) BigDecimal(y+this.height);
}
private double BigDecimal(double e) {
// TODO Auto-generated method stub
BigDecimal bd= new BigDecimal(e).setScale(3, BigDecimal.ROUND_HALF_UP);// 小數後面四位, 四捨五入   ;

String a = ""+bd;

return Double.parseDouble(a);

}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

Paint p = new Paint();
p.setColor(Color.BLACK);
canvas.drawBitmap(bitmap, (float)X,(float)Y, p);
p.setTextSize(50);
canvas.drawLine((float)BX, (float)BY, (float)(200*Vx+BX), (float)(200*Vy+BY), p);
canvas.drawCircle((float)BX,(float) BY, 10, p);

//bd=bd.setScale(4, BigDecimal.ROUND_HALF_UP);// 小數後面四位, 四捨五入
canvas.drawText(V+"",(float)BX,(float)( BY+width/2+40), p);
canvas.drawText(BX+"",(float)BX,(float)( BY+width/2+140), p);
canvas.drawText(BY+"",(float)BX,(float)( BY+width/2+240), p);

}

}``````

### 回答：

``````    //像素转换
static final int pd2px(float density,int pd){
return (int)(pd*density + 0.5f);
}
//初始5个像素长度
private int pd5 = 5;
//初始化
final void initPDs(Context ctx){
DisplayMetrics dm = ctx.getResources().getDisplayMetrics();
//根据像素密度调整pd值
this.pd5 = pd2px(dm.density,5);
}
//在不同像素密度上保持大小一致
LinearLayout texts = new LinearLayout(context);