首页 > 解决方案 > 检测两个圆之间的碰撞并将它们相互滑动

问题描述

我正在尝试检测两个圆圈之间的碰撞,如下所示:

var circle1 = {radius: 20, x: 5, y: 5}; //moving
var circle2 = {radius: 12, x: 10, y: 5}; //not moving

var dx = circle1.x - circle2.x;
var dy = circle1.y - circle2.y;
var distance = Math.sqrt(dx * dx + dy * dy);


if (distance < circle1.radius + circle2.radius) {
    // collision detected

}else{ 
    circle1.x += 1 * Math.cos(circle1.angle);
    circle1.y += 1 * Math.sin(circle1.angle);
}

现在,当检测到碰撞时,我想circle1circle2circle1正在移动)上滑动,如下所示:

在此处输入图像描述
--circle1---------------------------------circle2------------- ------------

我可以通过在circle1检测到碰撞时更新角度并将其移向新角度来做到这一点。

现在我的问题是,如何根据circle2 circle1碰撞的部分来检测是更新/增加角度还是更新/减少角度?(圈一个来自各个角度)

我将不胜感激任何帮助

标签: javascriptmathcollision-detection

解决方案


这将在一定程度上取决于您如何使用这些圆圈,以及单个系统中将存在多少个圆圈,但是如果您试图模拟两个物体在重力作用下碰撞的效果,其中一个角色在边缘附近然后脱落(或类似的推力不足的情况),那么您应该对移动的物体施加恒定的加速度或速度,并在计算出它的运动阶段后,进行位移阶段,在该阶段您与正在碰撞的物体成角度并将其移回在那个方向上足够远,可以到达 circle1.radius + circle2.radius。

[编辑] 但是,为了在跌倒后获得重定向(不确定您是有意这样做还是只是您的草图),可能会有另一种力量在起作用。很可能它会涉及在身体之间施加的“粘性”。基本上,在发生碰撞时,您需要确保在下一个运动周期中,您应用正常运动,然后向另一个身体运动,然后是斥力以确保它们不重叠。这样,它会粘在大圆圈上,直到重力以足够的直接角度拉动以破坏连接。

[edit2] 如果你想让它更平滑并在你跌落时获得自然曲线,你可以使用摩擦下的加速度公式。所以,而不是这个:

circle1.x += 1 * Math.cos(circle1.angle);
circle1.y += 1 * Math.sin(circle1.angle);

您想为对象创建速度属性,这些属性受加速度和摩擦力的作用,直到它们平衡到固定的终端速度。思考:

// constants - adjust these to get the speed and smoothness you desire
var acceleration = 1;
var friction = 0.8; 

// part of physics loop
circle1.velX += (acceleration * Math.cos(circle1.angle)) - (friction * circle1.velX);
circle1.velY += (acceleration * Math.sin(circle1.angle)) - (friction * circle1.velX);
circle1.x += circle1.velX;
circle1.y += circle1.velY;

这样,当物体撞击时,它们会减速(或停止),然后在它们再次开始移动时加速。当它恢复速度时的加速度将在它下降时实现更自然的弧线。


推荐阅读