Skip to content

Commit 9f8069e

Browse files
committed
added skeleton for point_2_mesh_distance
1 parent 3837516 commit 9f8069e

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed

src/gh/diffCheck/diffCheck/df_error_estimation.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,101 @@ def cloud_2_cloud_distance(source, target, signed=False):
2828

2929

3030
def cloud_2_mesh_distance(source, target):
31+
"""
32+
Calculate the distance between every point of a source pcd to its closest point on a target mesh
33+
"""
34+
35+
# for every point on the PCD compute the point_2_mesh_distance
3136

3237
distances = np.ones(len(source.points), dtype=float)
3338

3439
return distances
3540

3641

42+
def point_2_mesh_distance(mesh, point):
43+
"""
44+
Calculate the closest distance between a point and a mesh
45+
"""
46+
pass
47+
# make a kdtree of the vertices to get the relevant vertices indexes
48+
49+
# assume smallest distance is the distance to the closest vertex
50+
51+
# create a box centered around the query point with an edge length equal to two times the distance to the nearest vertex
52+
# query a kd tree for all the faces that intersect this box
53+
54+
# compute the closest point for the faces that we get back
55+
56+
57+
def point_2_face_distance(face, point):
58+
"""
59+
Calculate the closest distance between a point and a face
60+
"""
61+
62+
if len(face.vertices) == 3:
63+
return point_2_triangle_distance(point, face)
64+
elif len(face.vertices) == 4:
65+
return point_2_quad_distance(point, face)
66+
else:
67+
raise ValueError("Face must be a triangle or quadrilateral")
68+
69+
70+
def point_2_triangle_distance(point, triangle):
71+
"""
72+
Calculate the shortest distance from a point to a triangle.
73+
"""
74+
a, b, c = triangle
75+
76+
bary_coords = barycentric_coordinates(point, a, b, c)
77+
78+
# If the point is inside or on the triangle, use the barycentric coordinates to find the closest point
79+
if np.all(bary_coords >= 0):
80+
closest_point = bary_coords[0] * a + bary_coords[1] * b + bary_coords[2] * c
81+
82+
# If the point is outside the triangle, project it onto the triangle edges and find the closest point
83+
else:
84+
proj = np.array([np.dot(point - a, b - a) / np.dot(b - a, b - a),
85+
np.dot(point - b, c - b) / np.dot(c - b, c - b),
86+
np.dot(point - c, a - c) / np.dot(a - c, a - c)])
87+
proj = np.clip(proj, 0, 1)
88+
closest_point = np.array([a + proj[0] * (b - a), b + proj[1] * (c - b), c + proj[2] * (a - c)]).min(axis=0)
89+
90+
return np.linalg.norm(closest_point - point)
91+
92+
93+
def barycentric_coordinates(p, a, b, c):
94+
"""
95+
Calculate the barycentric coordinates of point p with respect to the triangle defined by points a, b, and c.
96+
"""
97+
v0 = b - a
98+
v1 = c - a
99+
v2 = p - a
100+
101+
d00 = np.dot(v0, v0)
102+
d01 = np.dot(v0, v1)
103+
d11 = np.dot(v1, v1)
104+
d20 = np.dot(v2, v0)
105+
d21 = np.dot(v2, v1)
106+
107+
denom = d00 * d11 - d01 * d01
108+
v = (d11 * d20 - d01 * d21) / denom
109+
w = (d00 * d21 - d01 * d20) / denom
110+
u = 1.0 - v - w
111+
112+
return np.array([u, v, w])
113+
114+
115+
def point_2_quad_distance(point, quad):
116+
"""
117+
Calculate the shortest distance from a point to a quadrilateral.
118+
"""
119+
a, b, c, d = quad.vertices
120+
121+
# Calculate the distance to the two triangles that form the quadrilateral
122+
return min(point_2_triangle_distance(point, [a, b, c]),
123+
point_2_triangle_distance(point, [c, d, a]))
124+
125+
37126
def compute_mse(distances):
38127
"""
39128
Calculate mean squared distance

0 commit comments

Comments
 (0)