2013-09-05 43 views
1

我在圈/球的碰撞模擬得到這個奇怪的錯誤我在做一個學校項目。我還可以補充一點,我是一個小菜鳥,我已經編程了大約一年。直到我填充有很多圈的帆布的JavaScript圈的碰撞檢測錯誤

碰撞工作正常。我真的不明白爲什麼。 25個圈子工作正常,但是當我上升到50圈時,圈子開始變得越野車。

正如你可以在圓圈下面的鏈接看到開始彼此連接運行一段時間,轉圈想瘋了,這是不是我的喜歡發生後。

50圈例: https://dl.dropboxusercontent.com/u/9069602/circles/vers1/collisions.html

我的猜測是,圈地互相連接的風險更大它們之間的空間減小,但似乎他們有足夠的空間,開始模擬的時候。在實際影響發生之前,我使用nextY/nextX位置變量來計算一幀影響。這也可能是錯誤的來源。我不能指望我的手指開始調試。

下面是50圈的情況下的代碼:我希望我是清楚的問題 https://dl.dropboxusercontent.com/u/9069602/circles/vers1/circle.js

// Returns true if two circles are overlapping 
function overlapDetection(circle1, circle2) { 
    var returnValue = false; 
    var dx = circle1.nextX - circle2.nextX; 
    var dy = circle1.nextY - circle2.nextY; 
    var distance = (dx * dx + dy * dy); 

    if (distance <= (circle1.radius + circle2.radius) * (circle1.radius + circle2.radius)) { 
     returnValue = true; 
    } 
    return returnValue; 
} 

function collide() { 
    var circle; 
    var testCircle; 
    var returnValue = false; 

    for (var i = 0; i < circles.length; i += 1) { 
     circle = circles[i]; 
     for (var j = i + 1; j < circles.length; j += 1) { 
      testCircle = circles[j]; 
      if (overlapDetection(circle, testCircle)) { 
       collideCircles(circle, testCircle); 
       collideCircle1 = circle.id; 
       collideCircle2 = testCircle.id; 
       returnValue = true; 
      } 
     } 
    } 
    return returnValue; 
} 

function collideCircles(circle1, circle2) { 

    var dx = circle1.nextX - circle2.nextX; 
    var dy = circle1.nextY - circle2.nextY; 
    var collisionAngle = Math.atan2(dy, dx); 

    var speed1 = Math.sqrt(circle1.velocityX * circle1.velocityX + circle1.velocityY * circle1.velocityY); 
    var speed2 = Math.sqrt(circle2.velocityX * circle2.velocityX + circle2.velocityY * circle2.velocityY); 

    var direction1 = Math.atan2(circle1.velocityY, circle1.velocityX); 
    var direction2 = Math.atan2(circle2.velocityY, circle2.velocityX); 

    var rotatedVelocityX1 = speed1 * Math.cos(direction1 - collisionAngle); 
    var rotatedVelocityY1 = speed1 * Math.sin(direction1 - collisionAngle); 
    var rotatedVelocityX2 = speed2 * Math.cos(direction2 - collisionAngle); 
    var rotatedVelocityY2 = speed2 * Math.sin(direction2 - collisionAngle); 

    var finalVelocityX1 = ((circle1.mass - circle2.mass) * rotatedVelocityX1 + (circle2.mass + circle2.mass) * rotatedVelocityX2)/(circle1.mass + circle2.mass); 
    var finalVelocityX2 = ((circle1.mass + circle1.mass) * rotatedVelocityX1 + (circle2.mass - circle1.mass) * rotatedVelocityX2)/(circle1.mass + circle2.mass); 

    var finalVelocityY1 = rotatedVelocityY1; 
    var finalVelocityY2 = rotatedVelocityY2; 

    circle1.velocityX = Math.cos(collisionAngle) * finalVelocityX1 + Math.cos(collisionAngle + Math.PI/2) * finalVelocityY1; 
    circle1.velocityY = Math.sin(collisionAngle) * finalVelocityX1 + Math.sin(collisionAngle + Math.PI/2) * finalVelocityY1; 
    circle2.velocityX = Math.cos(collisionAngle) * finalVelocityX2 + Math.cos(collisionAngle + Math.PI/2) * finalVelocityY2; 
    circle2.velocityY = Math.sin(collisionAngle) * finalVelocityX2 + Math.sin(collisionAngle + Math.PI/2) * finalVelocityY2; 

    circle1.nextX += circle1.velocityX; 
    circle1.nextY += circle1.velocityY; 
    circle2.nextX += circle2.velocityX; 
    circle2.nextY += circle2.velocityY; 
} 

在此先感謝!

+1

你應該在你的問題中包括相關的代碼! – Paddyd

+0

什麼是collideCircle1 = circle.id; collideCircle2 = testCircle.id;'for?變量在代碼中的任何地方都沒有被引用,但是它們僅僅因爲是全局的而聞起來很糟糕(在範圍中它們沒有'var ...')。 –

回答

0

讓我們假設你已經開發了一個鉸鏈點! =) 其實可能有幾個問題。例如:當你檢查一個可用空間時,另一個圓可以佔用它; 我認爲情景是未來: 讓我們假設兩個圓有

r=1; y =0; 
circle1.x = 1, circle2.x =4; 

檢查下一步:

circle1.canMoveToX(2) //=> true; coz border will move to x=3 it's empty at the moment; 
circle2.canMoveToX(3) // => true; coz border will move to x=2 it's empty at the moment; 

,並在這一步他們加入。

1

你的問題是雙重的。

collideCircles(circle1, circle2)假設circle1circle2將在明年座標,這是由collide()保證,在當前座標(看你怎麼計算collisionAngle),這可能不是真的都沒有碰撞被碰撞。這就是爲什麼你的圈子如果彼此重疊可能會「卡住」。

如果collideCircles(circle1, circle2)collideCircles(circle3, circle4)反彈circle2circle4以使其下一個座標位於另一個的上面,則圓圈可能會彼此重疊。但是,碰撞檢測循環已經越過它們,它們的碰撞不會被挑選出來,並且圓圈將愉快地移動到彼此之上。