2D 碰撞检测代码

发布于 2024-09-14 14:13:22 字数 1435 浏览 2 评论 0原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦旅人picnic 2024-09-21 14:13:22

这是我在点/线碰撞检测方面的镜头。重要的是避免三角函数、除法和其他昂贵的操作,以免减慢速度太多。

正如 GMan 的评论所指出的,你需要记住这一点将会移动。因此,您将获得该点的当前位置(我们将其称为 A)以及该点可能的新位置(B)。您需要确定当点从 A 移动到 B 时,它是否会与直线碰撞。

我们将线的起点和终点称为 CD。仅当线 ABCD 相交时才会发生碰撞。

让我们使用标准方程 Ux + Vy + W = 0 来描述直线 AB。经过一些代数运算后,方程如下:

(ay - by) x + (bx - ax) y + ax by - bx ay = 0

我们可以用参数 t 和常量 XYU V 来描述线 CD

x = X + Ut
y = Y + Vt

这很有帮助如果我们在C点设置t=0,在D点设置t=1。通过考虑t=0,我们可以计算出XY。通过考虑t=1,我们可以计算出UV。这给出了

x = cx + (dx - cx) t
y = cy + (dy - cy) t

要找到两条线的交点,请将它们代入我们为 AB 找到的方程,该方程给出

(ay - by) (cx + (dx - cx) t) + (bx - ax) (cy + (dy - cy) t) + ax by - bx ay = 0

这可以简化为

t = (ax by - bx ay + bx cy - cx by + cx ay - ax cy) / q

q = (ay - by)(cx - dx) - (ax - bx)(cy - dy)

  • 如果 q 为零,则直线平行且不相交。
  • 如果 0 < t < 1 则从 AB 推断的直线与 CD 相交。

但我们仍然不知道这个交点实际上是在 AB 点之间。因此,我们需要重复前面的所有步骤,交换 ABCD,并根据参数 s 编写 AB。这给出:

s = (cx dy - dx cy + dx ay - ax dy + ax cy - cx ay) / q
  • 如果 0 0 s < 1 则从 CD 推断的直线与 AB 相交。

就是这样。因此,在您的代码中,您首先计算 q。如果 q 为零,则直线是平行的。否则,继续计算ts。如果 0 < t < 10 s < 1 那么碰撞即将发生。要查找碰撞位置,请将 ts 代入 CD 的原始方程中。

为了获得额外的速度,您可以删除 q 的除法 - 可以只检查每个分数的上半部分是否在正确的范围内,然后每次检查应该只需要 10 次乘法运算。

Here's my shot at point/line collision detection. The important thing is to avoid trig functions, divisions, and other expensive operations so as not to slow things down too much.

As GMan's comment notes, you need to bear in mind that the point will be moving. So you'll have the current position of the point (let's call it A) and the possible new position of the point (B). You need to find out if, when the point moves from A to B, it would collide with a line.

Let's call the start and end points of the line C and D. A collision will occur only if the lines AB and CD intersect.

Let's describe the line AB using the standard equation Ux + Vy + W = 0. After some algebra, the equation comes out as:

(ay - by) x + (bx - ax) y + ax by - bx ay = 0

We can describe the line CD in terms of a parameter t and constants X Y U V:

x = X + Ut
y = Y + Vt

It's helpful if we set t=0 at point C, and t=1 at point D. By considering t=0 we can work out X and Y. And by considering t=1 we can work out U and V. This gives

x = cx + (dx - cx) t
y = cy + (dy - cy) t

To find the intersection point of the two lines, substitute these into the equation we found for AB, which gives

(ay - by) (cx + (dx - cx) t) + (bx - ax) (cy + (dy - cy) t) + ax by - bx ay = 0

This reduces to

t = (ax by - bx ay + bx cy - cx by + cx ay - ax cy) / q

where q = (ay - by)(cx - dx) - (ax - bx)(cy - dy)

  • If q is zero, the lines are parallel and do not meet.
  • If 0 < t < 1 then the line extrapolated from AB intersects CD.

But we still don't know that this intersection is actually between the points A and B. So we need to repeat all the previous steps, swapping AB and CD, and writing the line AB in terms of a parameter s. This gives:

s = (cx dy - dx cy + dx ay - ax dy + ax cy - cx ay) / q
  • If 0 < s < 1 then the line extrapolated from CD intersects AB.

That's it. So in your code you start by calculating q. If q is zero then the lines are parallel. Otherwise, go on to calculate t and s. If 0 < t < 1 and 0 < s < 1 then a collision is about to happen. To find the location of the collision, substitute t or s back into the original equations for CD.

For extra speed you can remove the divisions by q - it's possible to just check whether the top half of each fraction is in the correct range, and then each check should only need 10 multiplication operations.

苹果你个爱泡泡 2024-09-21 14:13:22

您是否有理由不能使用基本几何来实现此目的?

当两个点的坐标相同时,它们就会发生碰撞。

当点的位置是直线方程的解时,点与直线相交。

当点以矩形为界时,该点与矩形相交。

通过组合这些案例可以构建更复杂的复合案例。您是否出于某种原因专门寻找图书馆?

Is there a reason you couldn't use basic geometry for this?

Two points collide when their coordinates are the same.

A point intersects with a line when its position is a solution to the equation for the line.

A point intersects a rectangle when the point is bounded by the rectangle.

More complex composite cases can be constructed by composing these cases. Were you specifically looking for a library for some reason?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文