检测两个圆之间的碰撞并将它们彼此滑动

时间:2018-10-26 14:30:43

标签: javascript math collision-detection

我试图像这样检测两个圆之间的碰撞:

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);
}

现在,当检测到碰撞时,我想像这样从circle1circle2正在移动)上滑动circle1

enter image description here
--circle1 --------------------------------- circle2 ------------- ------------

我可以通过更新circle1的角度并在检测到碰撞时将其移向新角度来实现。

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

我将不胜感激

2 个答案:

答案 0 :(得分:1)

这将取决于您如何使用这些圆,以及在单个系统中将有多少圆,但是如果您要模拟两个物体在重力作用下碰撞的效果,其中一个作用在边缘,则跌落(或类似的下冲情况),则应向移动的对象施加恒定的加速度或速度,然后在计算其移动阶段之后,执行位移阶段,在该阶段中,将与要碰撞的对象成角度,然后将其在该方向上移回足够远的位置,以达到circle1.radius + circle2.radius。

[edit]为了在跌倒后获得重定向(不确定是要绘制还是只是草图),可能会有另外一种作用。最有可能的是,这将涉及在身体之间施加的“粘性”。基本上,在发生碰撞时,您需要确保在下一个运动周期中应用“正常运动”,然后朝另一个身体运动,然后进行排斥以确保它们不重叠。这样,它将粘在大圆圈上,直到重力以足够的直角拉动方式断开连接为止。

[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;

这样,当物体撞击时,它们会减速(或停止),然后在它们再次开始移动时又加速。恢复到加速时的加速度随着它的下落而获得更自然的弧度。

答案 1 :(得分:0)

您可以获取两个圆之间的接触点的切线,这将指示您与目标点(或任何水平面)相比可以改变多少角度。