需求:
程序如下:
import copy
from stl import stl
import mpl_toolkits.mplot3d as a3
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as colors
from mpl_toolkits.mplot3d import Axes3D
#加载stl函数
def load_stl(stl_name):
for i in range(len(stl_name)):
mesh = stl.StlMesh('./'+stl_name[i]+'.stl')
dot_matrix=np.zeros((len(mesh),3,3))
#将每个三角面的三个顶点坐标存在矩阵dot_original中
for i in range(len(mesh)):
s1=mesh.points[i]
s2=s1.reshape(3,3)
dot_matrix[i]=s2
#返回每个面片三个顶点的坐标以及法相量
return dot_matrix,mesh.normals
#画出图像
def plot_stl(dot_matrix):
fig = plt.figure()
ax = Axes3D(fig)
kwargs = {'alpha': 0.8,'color':'blue'}
for i in np.arange(len(dot_matrix)):
dot_m=np.vstack((dot_matrix[i],dot_matrix[i][0]))
ax.plot3D(dot_m[:,0].tolist(),dot_m[:,1].tolist(),dot_m[:,2].tolist(),linewidth=0.5,**kwargs)
plt.show()
#判断两个三角面是否有公共点,如果有则将share_dot_num计数器加1
def topology(m1,m2):
return share_dot_num
#生成拓扑关系
def topology_creation(dot_matrix):
#记录图谱
topology_list=[]
return topology_list
#计算两个向量之间的夹角
def vector_angle(x,y):
Lx=np.sqrt(x.dot(x))
Ly=np.sqrt(y.dot(y))
if Lx*Ly==0:
angle2=90
else:
#相当于勾股定理,求得斜线的长度
cos_angle=x.dot(y)/(Lx*Ly)
if cos_angle>1:
angle2=0
else:
#求得cos_sita的值再反过来计算,绝对长度乘以cos角度为矢量长度,初中知识。。
angle=np.arccos(cos_angle)
angle2=round(angle*180/np.pi,0)
# print(angle2)
#变为角度
return angle2
#计算每个三角面片与水平面夹角
def nvhp_angle_cal(nv_matrix):
nvhp_angle_list=[]
for i in np.arange(len(nv_matrix)):
nv_vector=nv_matrix[i]
hp_vector=copy.deepcopy(nv_matrix[i])
hp_vector[2]=0
nvhp_angle_list.append(vector_angle(nv_vector,hp_vector))
return nvhp_angle_list
#计算夹角变化率
def change_rate_cal(topology_relation,nvhp_angle):
change_rate_matrix=np.zeros((len(topology_relation),3))
return change_rate_matrix
#这个需求的核心,针对yuanhuyuqiu效果最好,针对方块与球效果一般,针对qumian效果差
def change_rate_stl1(change_r,topology_r,nvhp_a):
special_list=[]
return special_list
def change_rate_stl2(change_r,topology_r,nvhp_a):
special_list=[]
return special_list
def main():
#加载stl数据
dot_matrix,nv_matrix=load_stl(['fangkuaiyuqiu'])
#求拓扑关系
topology_relation=topology_creation(dot_matrix)
#计算每个法相量与水平面夹角
nvhp_angle=nvhp_angle_cal(nv_matrix)
#计算具有拓扑关系的三角面片法向量夹角的变化率
change_rate=change_rate_cal(topology_relation,nvhp_angle)
# print(change_rate)
special_list1=change_rate_stl1(change_rate,topology_relation,nvhp_angle)
special_list2=change_rate_stl2(change_rate,topology_relation,nvhp_angle)
print(special_list1)
#画出完整的图
print(len(dot_matrix))
plot_stl(dot_matrix)
plot_stl(dot_matrix[special_list1])
plot_stl(dot_matrix[special_list2])
#画出分割的图
main()
效果如下:
补充说明:
说明:
本代码是在python3.8环境下运行,部分python包为第三方包,如:
from stl import stl
import mpl_toolkits.mplot3d as a3
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as colors
from mpl_toolkits.mplot3d import Axes3D
安装方法(以stl为例):pip install stl,其他类似。
该程序由9个函数组成分别为:
1.load_stl(stl_name):输入stl名称,返回每个三角面片的顶点(3x3矩阵)以及每个三角面片的法相量
2.plot_stl(dot_matrix):输入每个三角面片的顶点,输出三角面片图像
3.topology_creation(dot_matrix):输入三角面片顶点,输出拓扑关系topology_list
4.topology(m1,m2):输入两个三角面片,判断它们有几个共同点,被topology_creation调用
5.vector_angle(x,y):计算两个向量x,y之间的夹角,输入两个向量,输出向量之间的夹角
6.nvhp_angle_cal(nv_matrix):计算每个三角面片法相量与水平面之间的夹角,输入为法相量,输出为夹角
7.change_rate_cal(topology_relation,nvhp_angle):计算夹角的变化率,输入为拓扑关系和法相量与平面的夹角,输出为夹角变化率
8.change_rate_stl1和change_rate_stl2:将法相量与平面夹角的变化率呈现不同规律的的面片找出来,三角面片与相邻三角面片法相量夹角变化率小于零同时本身的法相量不等于0;另一个是三角面片与相邻三角面片法相量夹角变化率大于等于零同时本身的法相量等于0,实现曲面与直角面的分割,这个比较粗糙,不具有普适性,还需要进一步研究
9.main():主函数入口,负责调用上述函数