最近在做一個關(guān)于牙齒正畸的實驗,用到了碰撞檢測,自然想到用obb包圍盒來簡化碰撞檢測的過程,python目前貌似沒有現(xiàn)成的包可以用,一怒之下自己寫了一個,雖然是用在牙齒模型上,但是只要給出三維空間中任一模型的坐標(biāo)集,均可以套用這個方法實現(xiàn)obb包圍盒(部分代碼有刪減)。
import numpy as np
from numpy.linalg import solve
def tooth_obb_box(dot):
covariance_matrix = np.cov(np.transpose(dot))
a,b=np.linalg.eig(covariance_matrix)
project=np.zeros((3,len(dot),3))
for i in range(3):
for j in range(len(dot)):
project[i,j]=
#將投影
re_project=np.zeros((3,len(dot),3))
for i in range(3):
for j in range(len(dot)):
P=np.zeros((3,2,3))
for i in range(3):
center=np.zeros((3,3))
for i in range(3):
pro=np.transpose(b)
K=np.sum(np.multiply(center,pro),axis=1)
parameter_a=pro#系數(shù)矩陣
parameter_b=K.T #常數(shù)項列矩陣
ps=np.flipud(pro)
bs=np.zeros((6,1))
k=0
for i in range(3):
for j in range(2):
k=k+1
point_a=ps#系數(shù)矩陣
point_b=np.zeros((8,3))
res=1
ans=np.zeros((8,3))
vec=np.zeros((8,3))
les=np.zeros((8,1))
for i in range(8):
les[i]=np.sqrt(sum(np.multiply(vec[i],vec[i])))
cos=np.zeros((8,1))
for i in range(8):
return b,x,ans,vec,les,cos
效果如下:

obb包圍盒的python實現(xiàn)

完整的牙齒包圍盒.png
包圍框的實現(xiàn):
import numpy as np
from sympy import *
import matplotlib.pyplot as plt
dot=np.array([[3.7, 1.7], [4.1, 3.8], [4.7, 2.9], [5.2, 2.8], [6.0, 4.0], [6.3, 3.6], [9.7, 6.3], [10.0, 4.9]])
# dot=np.random.rand(30,2)
covariance_matrix = np.cov(np.transpose(dot))
print(covariance_matrix)
a,b=np.linalg.eig(covariance_matrix)
#特征向量的斜率分別為k1,k2
k1=b[1,0]/b[0,0]
k2=b[1,1]/b[0,1]
#每個點在兩個特征向量上的投影分別表示為project1和project2
project1=np.zeros((len(dot),2))
project2=np.zeros((len(dot),2))
for i in range(len(dot)):
project1[i,0]=(k1*(dot[i,1])+dot[i,0])/(k1*k1+1)
project1[i,1]=k1*project1[i,0]
project2[i,0]=(k2*(dot[i,1]-9)+dot[i,0])/(k2*k2+1)
project2[i,1]=k2*project2[i,0]+9
#求解投影點的均值
mean_p1=[(max(project1[:,0])+min(project1[:,0]))/2,(max(project1[:,1])+min(project1[:,1]))/2]
mean_p2=[(max(project2[:,0])+min(project2[:,0]))/2,(max(project2[:,1])+min(project2[:,1]))/2]
#求中心點坐標(biāo)
center1=
center2=
#四個外圍輪廓,分別有四條直線組成
#line1與line2
x_12=
y_12=
#line2與line3
x_23=
y_23=
#line1與line4
x_14=
y_14=
#line3與line4
x_34=
y_34=
plt.plot(dot[:,0],dot[:,1],'o')
plt.plot(center1,center2,'r*')
plt.plot([x_12,x_23,x_34,x_14,x_12],[y_12,y_23,y_34,y_14,y_12],'r')
plt.xlim(0,20)
plt.ylim(0,10)
plt.show()
效果圖:

obb包圍框的python實現(xiàn)