AABB包围盒
· 阅读需 3 分钟
使用python实现点群的AABB包围盒算法。
Python代码
class AABB():
'''
点群的包围盒算法,是一种简化算法。
'''
def __init__(self, xyz=None):
if xyz is None:
pass
else:
self.maxMin = [None] * 6
self.min = [None] * 3
self.max = [None] * 3
self.len = [None] * 3
for i in range(3):
self.maxMin[i] = xyz[:, i].max()
for i in range(3):
self.maxMin[i+3] = xyz[:, i].min()
# 分别沿X, Y, Z三个方向,计算距离
for i in range(3):
self.min[i] = self.maxMin[i+3]
self.max[i] = self.maxMin[i]
self.len[i] = self.max[i] - self.min[i]
return
def distance(self, xyz1, xyz2, modelLWH=None, periodic=True):
"""
calculate the minimum distance between two AABBs
When the two AABBs collide, return 0
When the two AABBS are not collided, return the minimum distance
xyz1 or xyz2, store the coordinate data of all nodes.
modelLWH, 存储模型周期性边界数据
The structure of xyz1 and xyz2 is np.array([[x1,y1,z1],[x2,y2,z2]...])
The structure of modelLWH is (L,W,H)
Test:
xyz1 = np.array([[0,0,0],[3,3,3]])
xyz2 = np.array([[2,2,2],[6,6,6]])
xyz3 = np.array([[4,4,4],[6,6,6]])
xyz4 = np.array([[4,3,4],[6,6,6]])
print(AABBDistance(xyz1,xyz2)) # Output: 0.0
print(AABBDistance(xyz1,xyz3)) # Output: 1.732
print(AABBDistance(xyz1,xyz4)) # Output: 1.414
"""
# 储存包围盒的两个极值点坐标
maxMin1 = [] # [xmax, ymax, zmax, xmin, ymin, zmin]
maxMin2 = [] # [xmax, ymax, zmax, xmin, ymin, zmin]
# dxyz储存AABB包围盒在XYZ三个方向投影的距离
# 相交则为 0, 初始值全为 0.
dxyz = [0, 0, 0]
for i in range(3):
maxMin1.append(xyz1[:, i].max())
maxMin2.append(xyz2[:, i].max())
for i in range(3):
maxMin1.append(xyz1[:, i].min())
maxMin2.append(xyz2[:, i].min())
# 分别沿X, Y, Z三个方向,计算距离
for i in range(3):
min1 = maxMin1[i+3]
max1 = maxMin1[i]
min2 = maxMin2[i+3]
max2 = maxMin2[i]
len1 = max1 - min1
len2 = max2 - min2
# 1. -min1-----max1----min2----max2--->依次增大
if max1 < min2:
d1 = min2 - max1
d2 = max2 - min1
# 两者长度之和大于模型边界长度,则必然相交
if len1 + len2 >= modelLWH[i]:
dxyz[i] = 0 # 相交
# len1,2长度与周期性缩短的d1的和大于模型边界长度,
# 必然相交
elif len1 + len2 + d1 % modelLWH[i] >= modelLWH[i]:
dxyz[i] = 0 # 相交
else:
dxyz[i] = min(
d1 % modelLWH[i],
modelLWH[i] - d2 % modelLWH[i])
# 2. -min2-----max2----min1-----max1-->依次增大
elif maxMin1[i+3] > maxMin2[i]:
d1 = min1 - max2
d2 = max1 - min2
# 两者长度之和大于模型边界长度,则必然相交
if len1 + len2 >= modelLWH[i]:
dxyz[i] = 0 # 相交
# len1,2长度与周期性缩短的d1的和大于模型边界长度,
# 必然相交
elif len1 + len2 + d1 % modelLWH[i] >= modelLWH[i]:
dxyz[i] = 0 # 相交
else:
dxyz[i] = min(
d1 % modelLWH[i],
modelLWH[i] - d2 % modelLWH[i])
# 3. 其他情况
else:
dxyz[i] = 0
distance = (dxyz[0]**2 + dxyz[1]**2 + dxyz[2]**2)**0.5
return distance