分离轴定理和 Python [英] Separating Axis Theorem and Python

查看:31
本文介绍了分离轴定理和 Python的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我目前正在做的:

创建与 2 个矩形的 4 个边垂直的 4 个轴.因为它们是矩形,所以我不需要为每条边生成一个轴(法线).

然后我在我的 4 个轴上循环.

所以对于每个轴:我将矩形的每个角投影到轴上.有 2 个列表(数组)包含这些投影.每个矩形一个.然后我得到每个投影和轴的点积.这将返回一个标量值可用于确定最小值和最大值.

现在这两个列表包含标量而不是向量.我对列表进行排序,以便我可以轻松选择最小值和最大值.如果框 B 的最小值 >= 框 A 的最大值或框 B 的最大值 <= 框 A 的最小值,则该轴上没有碰撞,物体之间也没有碰撞.

此时函数完成,循环中断.

如果所有轴都没有满足这些条件,那么我们就会发生碰撞

我希望这是正确的做法.

python 代码本身可以在这里找到 http://pastebin.com/vNFP3mAb

还有:http://www.gamedev.net/page/reference/index.html/_/reference/programming/game-programming/collision-detection/2d-rotated-rectangle-collision-r2604>

我遇到的问题是上面的代码不起作用.即使没有碰撞,它也始终检测到碰撞.我输入的正是代码在做什么.如果我遗漏了任何步骤或只是不了解 SAT 的工作原理,请告诉我.

解决方案

我觉得有两点不对.首先,投影应该只是顶点与轴的点积.你做的太复杂了.其次,您获取轴的方式不正确.你写:

Axis1 = [ -(A_TR[0] - A_TL[0]),A_TR[1] - A_TL[1] ]

它应该在哪里读:

Axis1 = [ -(A_TR[1] - A_TL[1]),A_TR[0] - A_TL[0] ]

不同之处在于坐标确实为您提供了一个向量,但要获得垂直,您需要交换 x 和 y 值并将其中一个取反.

希望有所帮助.

编辑发现另一个错误

在这段代码中:

如果不是( B_Scalars[0] <= A_Scalars[3] 或 B_Scalars[3] >= A_Scalars[0] ):#没有重叠所以没有碰撞返回 0

应该是:

如果不是( B_Scalars[3] <= A_Scalars[0] 或 A_Scalars[3] <= B_Scalars[0] ):

Sort 为您提供一个价值增加的列表.所以 [1,2,3,4] 和 [10,11,12,13] 不重叠,因为后者的最小值大于前者的最大值.第二个比较是针对输入集交换时的情况.

This is what I am currently doing:

Creating 4 axis that are perpendicular to 4 edges of 2 rectangles. Since they are rectangles I do not need to generate an axis (normal) per edge.

I then loop over my 4 axes.

So for each axis: I get the projection of every corner of a rectangle on to the axis. There are 2 lists (arrays) containing those projections. One for each rectangle. I then get the dot product of each projection and the axis. This returns a scalar value that can be used to to determine the min and max.

Now the 2 lists contain scalars and not vectors. I sort the lists so I can easily select the min and max values. If the min of box B >= the max of box A OR the max of box B <= the min of box A then there is no collision on that axis and no collision between the objects.

At this point the function finishes and the loop breaks.

If those conditions are never met for all the axis then we have a collision

I hope this was the correct way of doing it.

The python code itself can be found here http://pastebin.com/vNFP3mAb

Also: http://www.gamedev.net/page/reference/index.html/_/reference/programming/game-programming/collision-detection/2d-rotated-rectangle-collision-r2604

The problem i was having is that the code above does not work. It always detects a a collision even where there is not a collision. What i typed out is exactly what the code is doing. If I am missing any steps or just not understanding how SAT works please let me know.

解决方案

I see two things wrong. First, the projection should simply be the dot product of a vertex with the axis. What you're doing is way too complicated. Second, the way you get your axis is incorrect. You write:

Axis1 = [  -(A_TR[0] - A_TL[0]),
             A_TR[1] - A_TL[1] ]

Where it should read:

Axis1 = [  -(A_TR[1] - A_TL[1]),
             A_TR[0] - A_TL[0] ]

The difference is coordinates does give you a vector, but to get the perpendicular you need to exchange the x and y values and negate one of them.

Hope that helps.

EDIT Found another bug

In this code:

if not ( B_Scalars[0] <= A_Scalars[3] or B_Scalars[3] >= A_Scalars[0] ):
            #no overlap so no collision
            return 0

That should read:

if not ( B_Scalars[3] <= A_Scalars[0] or A_Scalars[3] <= B_Scalars[0] ):

Sort gives you a list increasing in value. So [1,2,3,4] and [10,11,12,13] do not overlap because the minimum of the later is greater than the maximum of the former. The second comparison is for when the input sets are swapped.

这篇关于分离轴定理和 Python的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆