JavaScript Circle Collision Detection Bug
JavaScript Circle Collision Detection Bug
我在学校项目中做的圆圈/球碰撞模拟中遇到了这个奇怪的错误。我还可以补充一点,我有点菜鸟,我已经编程了大约一年。
碰撞工作正常,直到我用很多圆圈填充画布。我真的不明白为什么。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;
}
我希望我清楚这个问题。
提前感谢!
你的问题是双重的。
您的collideCircles(circle1, circle2)
假设circle1
和circle2
将在下一个坐标处发生碰撞,这是由collide()
保证的,并且不会在当前坐标中发生碰撞(请参阅如何计算collisionAngle
),这可能根本不是真的。 这就是为什么你的圈子如果彼此重叠,就会"卡住"。
如果collideCircles(circle1, circle2)
和collideCircles(circle3, circle4)
反弹circle2
并circle4
,以便它们的下一个坐标彼此重叠,则圆圈最终可能会彼此重叠。 但是,碰撞检测环路已经越过了它们,它们的碰撞不会被选中,圆圈会愉快地相互重叠。
假设您已经开发了一个铰链接头! =)实际上可能存在几个问题。例如:当您检查可用空间时,另一个圆圈已经可以占用它;我认为接下来是这种情况:让我们假设两个圆圈有
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;
在这一步,他们加入了。
- 在这个使用hasOwnProperty的对象扩展程序中有一个错误,I'我不确定那个bug是什么,也不确定这个扩展
- Socket.io客户端在使用名称空间时忽略端口[Bug?]
- angularjs formly submit bug in safari & IE 11
- Bug修复放弃了Firefox插件Wikilook
- “*[attribute ^="string”是如何/为什么是有效的querySelector?(JS bug
- HTML5 Canvas drawImage ratio bug iOS
- PrependTo() bug
- Backbone.js bug?
- Android的Bug:调试修复JS
- 在NodeJS网站中查找Bug
- SyntaxError: missing ) after argument list in fire bug
- IE11-Only Submit Bug
- jquery IE8 bug 中的 .on 方法
- fadeOut”;被禁用”;通过一行看似温和的CSS(jquery bug?)
- 使用javascript(IE bug?)在文本区域插入新行
- document.body.innerHTML 在 IE 中剥离 JavaScript - bug
- Serviceworker Bug event.respondWith
- JavaScript:将插入符号位置设置为第一段的开头(Opera bug)
- WebView bug - 替换 ContentEditable 中的选定文本
- JavaScript Circle Collision Detection Bug