[英]Detecting collision between circle and square
我知道这已经被问了很多,但就个人而言,我找不到合适的答案。 几乎无处不在,function 看起来像:
function rccol(rect, circle){
var dx = Math.abs(circle.x - (rect.x + rect.width / 2));
var dy = Math.abs(circle.y - (rect.y + rect.height / 2));
if(dx > circle.radius + rect.width / 2) return false;
if(dy > circle.radius + rect.height / 2) return false;
if(dx <= rect.width) return true;
if(dy <= rect.height) return true;
var dx = dx - rect.width;
var dy = dy - rect.height
return((dx * dx + dy * dy) <= (circle.radius * circle.radius));
}
这非常有效。 问题是我在游戏中使用它进行碰撞检测,其中圆圈是玩家的碰撞框,而正方形是比方说一堵墙。 我需要能够确定接触发生的位置,这样我才能真正防止“播放器”进入“墙”,因此返回的简单 boolean 在我的用例中实际上不起作用。
具有圆心坐标(cx, cy)
,您可以计算从圆心到矩形的平方距离。
dx = Max(Abs(cx - rect.center.x) - rect.width / 2, 0)
dy = Max(Abs(cy - rect.center.y) - rect.height / 2, 0)
SquaredDistance = dx * dx + dy * dy
当圆形最初在矩形之外时,可以删除Max
调用。
dx = Abs(cx - rect.center.x) - rect.width / 2
dy = Abs(cy - rect.center.y) - rect.height / 2
我们还可以删除已知初始 position 的Abs
(注意 - 直到符号更改的时刻!)
if cx >= rect.center.x:
dx = cx - rect.center.x - rect.width / 2
else:
dx = - cx + rect.center.x - rect.width / 2
为了避免很多不同的情况,我们可以虚拟地将玩家放在相对于矩形中心的第一象限,并相应地改变坐标和速度分量
if cx0 < 0:
cx0 = - cx0
vx = -vx
if cy0 < 0:
cy0 = - cy0
vy = -vy
要记录碰撞时刻,您必须使用起点和速度矢量分量(vx, vy)
将坐标替换为参数方程
cx = cx0 + vx * t
cy = cy0 + vy * t
并求解t
的(二次)方程
SquaredDistance - Radius^2 = 0
(cx0 + vx * t - rect.center.x - rect.width/2)^2 +
(cy0 + vy * t - rect.center.y - rect.height/2)^2 -
Radius^2 = 0
你可以得到零(无碰撞)、一个(触摸事件)或两个根(碰撞时刻和退出时刻)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.