Start with two rectangles:

aOrigin = np.array([
    [2.1],
    [5.1],
    [5.3],
    [2.3],
])
bOrigin = np.array([
    [2.3],
    [4.3],
    [4.4],
    [2.4]])# Center point position
aPosOrigin = np.array([3.5.2])
bPosOrigin = np.array([3.3.5])

Half the length of x and y
ahOrigin = np.array([1.5.1])
bhOrigin = np.array([1.0.5])
Copy the code

Add rotation:

rotateA = np.array([
    [math.cos(math.pi / 180 * 40), math.sin(math.pi / 180 * 40) * -1],
    [math.sin(math.pi / 180 * 40), math.cos(math.pi / 180 * 40)]
])

rotateB = np.array([
    [math.cos(math.pi / 180 * 50), math.sin(math.pi / 180 * 50) * -1],
    [math.sin(math.pi / 180 * 50), math.cos(math.pi / 180 * 50)]
])

iRotateA = np.linalg.inv(rotateA) The inverse of A, useful later

a = np.array([rotateA.dot(item) for item in aOrigin])
b = np.array([rotateB.dot(item) for item in bOrigin])
aPos = rotateA.dot(aPosOrigin)
bPos = rotateB.dot(bPosOrigin)
Copy the code

Now we have two rotated rectangles, and let’s see if they overlap

First, we transform the coordinate system to the coordinate system based on the rotation of rectangle A, which can make rectangle A horizontal, flat and vertical for the convenience of subsequent calculation

aBase = np.array([iRotateA.dot(item) for item in a])
iAPos = iRotateA.dot(aPos)
Copy the code

And now I’m going to transform rectangle B into rectangle A’s coordinate system

bBase = np.array([iRotateA.dot(item) for item in b])
iBPos = iRotateA.dot(bPos)
Copy the code

The x and y distance between the center points can be obtained by subtracting the center point vectors of the two rectangles

posTotal = abs(iBPos - iAPos) # array ([1.15334536, 1.96777167])
Copy the code

The difference between x axis and Y axis of central point is 1.15334536 and 1.96777167

When creating the rectangle, we know that the length of x and half of y of horizontal and vertical rectangle A is the variable ahOrigin. If we calculate the maximum length of x and half of y of rectangle B at this time (the green line in the following figure, assuming bh),

So the posTotal -BH-ahorigin vector if x and y are both negative then the two rectangles overlap

Bh can be solved by traversing four points of rectangle B. Here we introduce a method that does not require traversal:

We know that the largest x of the horizontal, horizontal and vertical rectangle B, and half of the y is bhOrigin, has undergone two rotateB and iRotateA rotateB transformations

Merge two transformations first:

rotateC = iRotateA.dot(rotateB)
Copy the code

Take the absolute value of rotateC and dot it with bhOrigin to get bh

bh = np.array([ abs(item) for item in rotateC ]).dot(bhOrigin)

posTotal - bh - ahOrigin Array ([-1.41828648, 0.30171961]) x,y
Copy the code

The following introduces the principle of the method of BH (personal understanding, please comment) :

According to the matrix multiplication formula, the X-axis value of the dot product of rotateC and a point is (the same as the Y-axis) :

cos * x - sin * y
Copy the code

The cosine of theta and the sine of theta in the quadrants of the coordinate system are plus and minus

[+ +] [-, +] [-, -] [+, -]Copy the code

We now take the center of rectangle B as the point [0, 0]

The f vector is bhOrigin

Assuming the rotation is now 30 degrees (first quadrant), then cosine and sine are both positive and the coordinates of the four points of the rectangle are:

cos * -1 - sin * 0.5
cos * 1 - sin * 0.5
cos * 1 + sin * 0.5
cos * -1 + sin * 0.5
Copy the code

The maximum X-axis value is cosine * 1 + sine * 0.5

Assuming the rotation is now 100 degrees (second quadrant), then cosine is negative, sine is positive, and the coordinates of the four points of the rectangle are:

cos * 1 - sin * 0.5
-cos * 1 - sin * 0.5
-cos * 1 + sin * 0.5
cos * 1 + sin * 0.5
Copy the code

The maximum X-axis value is cosine * 1 + sine * 0.5

And so on, whatever the Angle of rotation is, the maximum X-axis value is cosine * 1 + sine * 0.5

So you just take the absolute value of each term of the transformation matrix and dot it with bhOrigin to get the desired bh

Box2d-lite source code reading notes