2008-12-27 94 views
2

我無法計算球撞擊斜壁時的反射角度。我正在使用從這個tutorial解除的算法。它看起來像這樣(在ActionScript 3),P1是當前速度矢量和P2正常壁的:斜壁與球之間的彈性碰撞

private function getReflect2(p1 : Point, p2 : Point) : Point 
{ 

    var wallvec : Point = getNorm(p2); 
    var wallnorm : Point = p2; 

    var t : Number = dotProduct(wallvec, p1); 
    var n : Number = dotProduct(wallnorm, p1); 
    var vt : Point = new Point(wallvec.x * t, wallvec.y * t); 
    var vn : Point = new Point(wallnorm.x * -n, wallnorm.y * -n); 

    var vx : Number = dotProduct(new Point(1,0), vn) + dotProduct(new Point(1,0), vt); 
    var vy : Number = dotProduct(new Point(0,1), vn) + dotProduct(new Point(0,1), vt); 
    return new Point(vx, vy); 
} 

該函數返回新的速度矢量,所以正確地做與垂直的壁而碰撞不適合傾斜的人。球可能從兩側撞到牆上(即法線可能在另一個方向上伸出)。

任何人都可以發現我的錯誤嗎?或者建議一個更好的算法?

回答

0

如果它適用於垂直,也許wallvec是不正確的。你打印出wallvec和其他值嗎?

編輯:你能提供所有的矢量值時,P1(1, 0)P2(0, 1)

+0

是啊,我甚至有一個調試模式顯示各種載體。唯一看起來不對的是外向的。 – friism 2008-12-27 23:54:52

0

我認爲答案可能是關於「(即正常可能在另一方向突出)」的部分。「如果法線指向「進入」牆壁,反射將是牆壁,而不是您期望的方向。

+0

正常方向不影響碰撞。 (我剛剛測試過。) – 2008-12-28 00:29:14

1

向量wallvec和wallnorm的值必須爲1才能使用。我懷疑函數getNorm()爲你處理wallvec的工作,但是wallnorm似乎得到了一個任意的大小。

此外,您的實現並不完全匹配頁面上鍊接的算法。特別是,頁面使用P2作爲牆本身的方向。然後對矢量進行歸一化處理(在不改變方向的情況下將大小降至1)並將其複製到wallvec中。 Wallnorm接收到牆的法線(已經處於1級)。

我的C實現看起來像這樣。請注意,即使wnx和wny與p2c和p2y的方向相同,我仍然必須除以大小。

void solve (double p1x, double p1y, double p2x, double p2y, double *p3x, double *p3y) 
{ 
double wvx = -p2y/sqrt(p2x*p2x+p2y*p2y); 
double wvy = p2x/sqrt(p2x*p2x+p2y*p2y); 
double wnx= p2x/ sqrt(p2x*p2x+p2y*p2y); 
double wny= p2y/ sqrt(p2x*p2x+p2y*p2y); 

double t = wvx*p1x+wvy*p1y; 
double n = wnx*p1x+wny*p1y; 

double vtx = wvx*t; 
double vty = wvy*t; 
double vnx = wnx*-n; 
double vny = wny*-n; 

*p3x=vnx+vtx; 
*p3y=vny+vty; 

} 
0

這不是你問的答案,而是最後幾行不必要的複雜。由於(1,0)表示X軸,

dotProduct(new Point(1,0), vn) 

可以通過vn.x.代替因此,最後三行的功能都可以做了很多更加清晰簡單地指的是相應的成員VN和VT:

return new Point(vn.x + vt.x, vn.y + vt.y); 

我不夠使用ActionScript熟悉,知道如果有一個更方便表示向量加法的方式,但直接表示向量加法會更好。

0

這是未經測試,但這應該反映你的速度

private function reflectVectors(p1 : Point, p2 : Point) : Point 
{ 
    // get the normalized normal 
    var wallNorm:Point = p2.clone(); 
    wallNorm.normalize(1); 

    // v1 = v - 2 * (v.n).n 
    var dot:Number = p1.x * wallNorm.x + p1.y * wallNorm.y; 
    var diff:Point = wallNorm.clone(); 
    diff.normalize(dot * -2); 
    return p1.add(diff); 
}