2013-09-05 60 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以使其下一个坐标位于另一个的上面,则圆圈可能会彼此重叠。但是,碰撞检测循环已经越过它们,它们的碰撞不会被挑选出来,并且圆圈将愉快地移动到彼此之上。