def get_normals(hull, number_fitnodes=12):
"""
Calculate normals from given hull points using local convex hull fitting.
Orientation of normals is found using local center of mass.
:param hull: 3D coordinates of points representing cell hull
:type hull: np.array
:return: normals for each hull point
"""
normals = np.zeros_like(hull, dtype=np.float)
hull_tree = spatial.cKDTree(hull)
dists, nearest_nodes_ixs = hull_tree.query(hull, k=number_fitnodes,
distance_upper_bound=1000)
for ii, nearest_ixs in enumerate(nearest_nodes_ixs):
nearest_nodes = hull[nearest_ixs[dists[ii] != np.inf]]
ch = ConvexHull(nearest_nodes, qhull_options='QJ Pp')
triangles = ch.points[ch.simplices]
normal = np.zeros((3), dtype=np.float)
# average normal
for triangle in triangles:
cnt = 0
n_help = unit_normal(triangle[0], triangle[1], triangle[2])
if not np.any(np.isnan(n_help)):
normal += np.abs(n_help)
normal /= np.linalg.norm(normal)
normal_sign = (hull[ii] - np.mean(nearest_nodes, axis=0))/\
np.abs(hull[ii] - np.mean(nearest_nodes, axis=0))
normals[ii] = normal * normal_sign
return normals
评论列表
文章目录