javascript - 检测圆形和方形之间的碰撞
问题描述
我知道这已经被问了很多,但就个人而言,我找不到合适的答案。几乎在任何地方,该函数看起来都像:
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));
}
这非常有效。问题是我在游戏中使用它进行碰撞检测,其中圆圈是玩家的碰撞框,而正方形是比方说一堵墙。我需要能够确定接触发生的位置,这样我才能真正防止“玩家”进入“墙”,因此返回的简单布尔值在我的用例中实际上不起作用。
解决方案
有了圆心坐标(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
我们也可以删除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
你可以得到零(无碰撞)、一个(触摸事件)或两个根(碰撞时刻和退出时刻)。
推荐阅读
- python-3.x - 获取迭代六次的列表中的第一个
- javascript - 简单的 JS 问题。(更改字符串的字体)
- php - 尝试使用 Laravel 5.0 创建项目时出现 Composer 错误
- javascript - 未捕获的类型错误:无法读取 null 的“已检查”属性 - html 复选框切换
- c - 我不认为我完全理解 realloc,有人可以向我解释为什么我的代码中的 realloc 有时会失败但有时不会
- java - Java NIO 为什么 Selector 必须在非阻塞模式下使用 Channel?
- python - Python matplotlib散点图导入颜色图列表
- r - R将整个数据表转换为小写的最快方法
- java - Java FX:如何在没有匿名内部类的情况下重写 RowFactory - Java 8 Compatible
- arrays - 如何访问此 json 响应对象?