Rotation 在HTML5+中使用固定形状矩形检查旋转矩形命中点;Javascript和画布

Rotation 在HTML5+中使用固定形状矩形检查旋转矩形命中点;Javascript和画布,rotation,html5-canvas,rectangles,hit,Rotation,Html5 Canvas,Rectangles,Hit,嗨,我正在做一个汽车游戏,我画了一个汽车形状的矩形,如下所示。xP和yP动态地来自JavaScript中的键盘事件,旋转也是如此 ctxDrift.clearRect(0, 0, 426, 754); ctxDrift.save(); ctxDrift.beginPath(); ctxDrift.translate(xP-car.getWidth()/2, yP-car.getHeight()/2); ctxDrift.rotate((Math.PI / 180) * car.getRotati

嗨,我正在做一个汽车游戏,我画了一个汽车形状的矩形,如下所示。xP和yP动态地来自JavaScript中的键盘事件,旋转也是如此

ctxDrift.clearRect(0, 0, 426, 754);
ctxDrift.save();
ctxDrift.beginPath();
ctxDrift.translate(xP-car.getWidth()/2, yP-car.getHeight()/2);
ctxDrift.rotate((Math.PI / 180) * car.getRotation());
ctxDrift.translate(-xP, -yP);
ctxDrift.rect(xP-car.getWidth()/2, yP-car.getHeight()/2, car.getWidth(), car.getHeight());
ctxDrift.fillStyle = 'yellow';
ctxDrift.fill();
ctxDrift.restore();

现在有一些障碍物是矩形的,没有旋转。现在我如何检查这两个物体之间的碰撞。或者说,如果旋转,如何检查矩形点位于另一个矩形内?

最简单的方法是旋转矩形边界框,以便在执行碰撞检查之前,它们基本上不再旋转。然后在绘制图像之前将其旋转回去

更好的是,有一个不旋转的边界框,可以用于宽相位测试(快速而廉价的检查,看看是否需要进行窄相位检查)

这称为轴对齐的边界框,简称AABB。这大大简化了碰撞检测代码


更新:发现这可能很有用。

最简单的方法是旋转矩形边界框,以便在执行碰撞检查之前它们基本上不再旋转。然后在绘制图像之前将其旋转回去

更好的是,有一个不旋转的边界框,可以用于宽相位测试(快速而廉价的检查,看看是否需要进行窄相位检查)

这称为轴对齐的边界框,简称AABB。这大大简化了碰撞检测代码

更新:发现这可能很有用。

甚至在开始碰撞测试之前: 画布不会跟踪对象在画布上的位置您必须手动跟踪用户累计完成的.translate()和.rotate()。您可以通过捕获每个用户键盘事件的转换矩阵更改来实现这一点。然后将变换累积到一个最终的变换矩阵中,您可以使用该矩阵开始命中测试

从那以后,碰撞测试的数学很快变得复杂起来

最简单的碰撞测试就是用一个圆围绕每个矩形,然后计算圆的中心点是否在两个圆半径的总和内。代码如下所示:

function CirclesCollide(x1,y1,radius1,x2,y2,radius2){
    return ( Math.sqrt( ( x2-x1 ) * ( x2-x1 )  + ( y2-y1 ) * ( y2-y1 ) ) < ( radius1 + radius2 ) );
}
甚至在开始碰撞测试之前: 画布不会跟踪对象在画布上的位置您必须手动跟踪用户累计完成的.translate()和.rotate()。您可以通过捕获每个用户键盘事件的转换矩阵更改来实现这一点。然后将变换累积到一个最终的变换矩阵中,您可以使用该矩阵开始命中测试

从那以后,碰撞测试的数学很快变得复杂起来

最简单的碰撞测试就是用一个圆围绕每个矩形,然后计算圆的中心点是否在两个圆半径的总和内。代码如下所示:

function CirclesCollide(x1,y1,radius1,x2,y2,radius2){
    return ( Math.sqrt( ( x2-x1 ) * ( x2-x1 )  + ( y2-y1 ) * ( y2-y1 ) ) < ( radius1 + radius2 ) );
}

这就是我要找的问题

canvas现在有了addHitRegion()函数,在这里我们可以很容易地对此进行跟踪

新的和最好的


这就是我要寻找的查询

canvas现在有了addHitRegion()函数,在这里我们可以很容易地对此进行跟踪

新的和最好的


我终于添加了自己的逻辑,就在这里


我终于添加了自己的逻辑,就在这里


圆圈碰撞检测相当慢。做这种测试显然只适合做广泛的阶段(粗略的)碰撞检查-但是为什么不保持数学简单(快速)并使用AABB矩形?@Jarrod:嗯…圆圈碰撞很快(只有一个Math.sqrt和一些+-*)和简单(只有一行代码!)。我同意这是一个粗略的碰撞测试,但操作一开始就很简单。由于汽车的长边大部分是向前的,因此圆的不精确性被最小化(rect和圆之间的最小间距)。请注意,我确实提出了一些“更好”的测试…包括您的AABB,但这些测试需要花费更多的代码、数学和cpu周期!此外,AABB边界框在45135225315度处变为方形,几乎与圆形一样不精确!顺便说一句,我喜欢并使用AABB!这太贵了
Math.sqrt
非常昂贵。查一查。@VarunJi——希望我们对你的问题有所帮助……@Jarrod——我不喜欢火焰战争,但我坚持我的回答和评论——我完了。很抱歉延迟回复。但多亏了你们俩。。。我认为AABB是我最好的选择,因为我可以选择任何形状(矩形)。是的,圆圈很容易检查。但是带矩形的圆需要大量的编码,圆碰撞检测比较慢。做这种测试显然只适合做广泛的阶段(粗略的)碰撞检查-但是为什么不保持数学简单(快速)并使用AABB矩形?@Jarrod:嗯…圆圈碰撞很快(只有一个Math.sqrt和一些+-*)和简单(只有一行代码!)。我同意这是一个粗略的碰撞测试,但操作一开始就很简单。由于汽车的长边大部分是向前的,因此圆的不精确性被最小化(rect和圆之间的最小间距)。请注意,我确实提出了一些“更好”的测试…包括您的AABB,但这些测试需要花费更多的代码、数学和cpu周期!此外,AABB边界框在45135225315度处变为方形,几乎与圆形一样不精确!顺便说一句,我喜欢并使用AABB!这太贵了
Math.sqrt
非常昂贵。查一查。@VarunJi——希望我们对你的问题有所帮助……@Jarrod——我不喜欢火焰战争,但我坚持我的回答和评论——我完了。很抱歉延迟回复。但多亏了你们俩。。。我认为AABB是我最好的选择,因为我可以选择任何形状(矩形)。是的,圆圈很容易检查。但是矩形的圆需要很多