Javascript 我的碰撞检测算法似乎在物体接触之前就触发了

Javascript 我的碰撞检测算法似乎在物体接触之前就触发了,javascript,collision-detection,Javascript,Collision Detection,我编写了一个非常简单的碰撞检测演示: 如您所见,对象有时根本不连接,但碰撞仍在触发。球的半径为10px,因此只要两个球中心之间的距离小于20px,algo就会触发碰撞。为了更好的视觉效果,我把它减少到18px,但是空的碰撞仍然是随机发生的。我做错什么了吗?看起来你没有使用正确的两点间距离公式。请参阅以获取完整的解释 您正在这样做: this.ballCollide = function(balli) { if (Math.abs((this.x) - (balli.x)) < (

我编写了一个非常简单的碰撞检测演示:


如您所见,对象有时根本不连接,但碰撞仍在触发。球的半径为10px,因此只要两个球中心之间的距离小于20px,algo就会触发碰撞。为了更好的视觉效果,我把它减少到18px,但是空的碰撞仍然是随机发生的。我做错什么了吗?

看起来你没有使用正确的两点间距离公式。请参阅以获取完整的解释

您正在这样做:

this.ballCollide = function(balli) {
    if (Math.abs((this.x) - (balli.x)) < (2*radius - buffer)) {
        if (Math.abs((this.y) - (balli.y)) < (2*radius - buffer)) {
             // Do collision
        }
    }
};
this.ballclide=函数(balli){
如果(数学绝对值((this.x)-(balli.x))<(2*半径-缓冲区)){
if(数学绝对值((this.y)-(balli.y))<(2*半径-缓冲区)){
//碰撞
}
}
};
那是一个正方形的边框,不是圆形的。要获得圆形边界框,可以根据引用网页中的公式执行以下操作:

this.ballCollide = function(balli) {
    var deltax = this.x - balli.x;
    var deltay = this.y - balli.y;
    if (Math.sqrt(deltax * deltax + deltay * deltay) < 2 * radius - buffer) {
        // Do collision
    }
};
this.ballclide=函数(balli){
var deltax=this.x-balli.x;
var deltay=this.y-balli.y;
if(数学sqrt(deltax*deltax+deltay*deltay)<2*半径-缓冲区){
//碰撞
}
};
有关工作示例,请参见

请注意,完美圆形边界框的算法比方形边界框近似算法慢得多

按照Jarrod Roberson的观点(一个完美的圆总是在一个完美的正方形中),你可以通过将你的原始代码和我发布的代码基本上结合起来,就像这样(如果你想的话,你可以将它们结合成一个条件开关):

var deltax=this.x-balli.x;
var deltay=this.y-balli.y;
var dist=2*半径-缓冲区;
if(数学abs(deltax)
请参阅一个工作示例(我将
缓冲区保留为
,因为变量在2处调用,但我个人认为值为1时效果更好)


如果需要的话,还有很多其他方法可以优化速度,但是Jarrod的建议会给你带来最大的即时速度提升。

看起来你没有使用正确的两点距离公式。请参阅以获取完整的解释

您正在这样做:

this.ballCollide = function(balli) {
    if (Math.abs((this.x) - (balli.x)) < (2*radius - buffer)) {
        if (Math.abs((this.y) - (balli.y)) < (2*radius - buffer)) {
             // Do collision
        }
    }
};
this.ballclide=函数(balli){
如果(数学绝对值((this.x)-(balli.x))<(2*半径-缓冲区)){
if(数学绝对值((this.y)-(balli.y))<(2*半径-缓冲区)){
//碰撞
}
}
};
那是一个正方形的边框,不是圆形的。要获得圆形边界框,可以根据引用网页中的公式执行以下操作:

this.ballCollide = function(balli) {
    var deltax = this.x - balli.x;
    var deltay = this.y - balli.y;
    if (Math.sqrt(deltax * deltax + deltay * deltay) < 2 * radius - buffer) {
        // Do collision
    }
};
this.ballclide=函数(balli){
var deltax=this.x-balli.x;
var deltay=this.y-balli.y;
if(数学sqrt(deltax*deltax+deltay*deltay)<2*半径-缓冲区){
//碰撞
}
};
有关工作示例,请参见

请注意,完美圆形边界框的算法比方形边界框近似算法慢得多

按照Jarrod Roberson的观点(一个完美的圆总是在一个完美的正方形中),你可以通过将你的原始代码和我发布的代码基本上结合起来,就像这样(如果你想的话,你可以将它们结合成一个条件开关):

var deltax=this.x-balli.x;
var deltay=this.y-balli.y;
var dist=2*半径-缓冲区;
if(数学abs(deltax)
请参阅一个工作示例(我将
缓冲区保留为
,因为变量在2处调用,但我个人认为值为1时效果更好)


如果需要的话,还有很多其他方法可以优化速度,但是Jarrod的建议会给您带来最大的即时速度提升。

您只检查x轴和y轴上的碰撞。您需要使用毕达哥拉斯定理,以牺牲效率为代价在所有轴上进行检测。比如说

您的算法将检测到围绕这两个球所在点的碰撞,因为如果从一个球沿x或y轴绘制切线,它将穿过另一个球:

在这里,您可以看到它们实际碰撞的位置:

如果更改碰撞检测算法以检查完美碰撞(效率会降低),则也可以删除缓冲区:

(使用毕达哥拉斯定理,碰撞公式为:

 Math.sqrt((this.x - balli.x)*(this.x - balli.x) 
   + (this.y - balli.y)*(this.y - balli.y)) < 2*radius
Math.sqrt((this.x-balli.x)*(this.x-balli.x)
+(this.y-balli.y)*(this.y-balli.y))<2*半径
Jarrod的评论也非常聪明。你可以使用这样的技术来加速。因为平方根只在球彼此靠近时计算:


您只检查x轴和y轴上的碰撞。您需要使用毕达哥拉斯定理来检测所有轴上的碰撞,但要以效率为代价。例如

您的算法将检测到围绕这两个球所在点的碰撞,因为如果从一个球沿x或y轴绘制切线,它将穿过另一个球:

在这里,您可以看到它们实际碰撞的位置:

如果更改碰撞检测算法以检查完美碰撞(效率会降低),则也可以删除缓冲区:

(使用毕达哥拉斯定理,碰撞公式为:

 Math.sqrt((this.x - balli.x)*(this.x - balli.x) 
   + (this.y - balli.y)*(this.y - balli.y)) < 2*radius
Math.sqrt((this.x-balli.x)*(this.x-balli.x)
+(this.y-balli.y)*(this.y-balli.y))<2*半径
Jarrod的评论也非常聪明。你可以使用这样的技术来加速。因为平方根只在球彼此靠近时计算:


这是正确的,我想补充一点,你可以做边界