Separating Axis Theorem and Python

前端 未结 2 1642
青春惊慌失措
青春惊慌失措 2021-01-06 11:17

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 (no

相关标签:
2条回答
  • 2021-01-06 11:48

    In general it is necessary to carry out the steps outlined in the Question to determine if the rectangles "collide" (intersect), noting as the OP does that we can break (with a conclusion of non-intersection) as soon as a separating axis is found.

    There are a couple of simple ways to "optimize" in the sense of providing chances for earlier exits. The practical value of these depends on the distribution of rectangles being checked, but both are easily incorporated in the existing framework.

    (1) Bounding Circle Check

    One quick way to prove non-intersection is by showing the bounding circles of the two rectangles do not intersect. The bounding circle of a rectangle shares its center, the midpoint of either diagonal, and has diameter equal to the length of either diagonal. If the distance between the two centers exceeds the sum of the two circles' radii, then the circles do not intersect. Thus the rectangles also cannot intersect. If the purpose was to find an axis of separation, we haven't accomplished that yet. However if we only want to know if the rectangles "collide", this allows an early exit.

    (2) Vertex of one rectangle inside the other

    The projection of a vertex of one rectangle on axes parallel to the other rectangle's edges provides enough information to detect when that vertex is inside the other rectangle. This check is especially easy when the latter rectangle has been translated and unrotated to the origin (with edges parallel to the ordinary axes). If it happens that a vertex of one rectangle is inside the other, the rectangles obviously intersect. Of course this is a sufficient condition for intersection, not a necessary one. But it allows for an early exit with a conclusion of intersection (and of course without finding an axis of separation because none will exist).

    0 讨论(0)
  • 2021-01-06 11:55

    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.

    0 讨论(0)
提交回复
热议问题