def query(self, query_point, query_radius, curr_node): # project a point onto its nearest triangles and find the nearest projection location nearest = (None, float("inf")) if type(curr_node) == Leaf: if np.linalg.norm(query_point - curr_node.center) <= query_radius: # project the point at the leaf node proj_point = project_point_to_triangle(query_point, curr_node.triangle, thickness = self.thickness) proj_dist = np.linalg.norm(query_point - proj_point) nearest = (proj_point, proj_dist) self.projection_count += 1 elif type(curr_node) == Node: dist = np.linalg.norm(query_point - curr_node.center) if dist > curr_node.radius_lo + query_radius: # query and partition spheres are completely not overlapping nearest = self.query(query_point, query_radius, curr_node.outside_node) elif dist < curr_node.radius_hi - query_radius: # query and partition spheres are completely overlapping nearest = self.query(query_point, query_radius, curr_node.inside_node) else: # must examine both subtrees as the border of the query sphere overlaps the border of the partition sphere nearest_inside = self.query(query_point, query_radius, curr_node.inside_node) nearest_outside = self.query(query_point, query_radius, curr_node.outside_node) if nearest_inside[1] < nearest_outside[1]: nearest = nearest_inside else: nearest = nearest_outside return nearest
def _query(query_point, query_radius, curr_node, thickness, center, radius_lo, radius_hi, inside_node, outside_node, triangle, is_leaf): # project a point onto its nearest triangles and find the nearest projection location nearest = (None, np.inf) if is_leaf[curr_node]: if np.linalg.norm(query_point - center[curr_node]) <= query_radius: # project the point at the leaf node proj_point = project_point_to_triangle(query_point, triangle[curr_node], thickness = thickness) proj_dist = np.linalg.norm(query_point - proj_point) nearest = (proj_point, proj_dist) else: dist = np.linalg.norm(query_point - center[curr_node]) if dist > radius_lo[curr_node] + query_radius: # query and partition spheres are completely not overlapping nearest = _query(query_point, query_radius, outside_node[curr_node], thickness, center, radius_lo, radius_hi, inside_node, outside_node, triangle, is_leaf) elif dist < radius_hi[curr_node] - query_radius: # query and partition spheres are completely overlapping nearest = _query(query_point, query_radius, inside_node[curr_node], thickness, center, radius_lo, radius_hi, inside_node, outside_node, triangle, is_leaf) else: # must examine both subtrees as the border of the query sphere overlaps the border of the partition sphere nearest_inside = _query(query_point, query_radius, inside_node[curr_node], thickness, center, radius_lo, radius_hi, inside_node, outside_node, triangle, is_leaf) nearest_outside = _query(query_point, query_radius, outside_node[curr_node], thickness, center, radius_lo, radius_hi, inside_node, outside_node, triangle, is_leaf) if nearest_inside[1] < nearest_outside[1]: nearest = nearest_inside else: nearest = nearest_outside return nearest
def visualize_projection(): tri = np.array([[0.0, 0.0, 0.0], [0.0, 1.0, 0.0], [1.0, 1.0, 0.0]]) p_perturb = np.array([1.5, 1.5, 0.5]) p_proj = project_point_to_triangle(p_perturb, tri, thickness=0.1) plt.figure(figsize=(15, 15)) plt.subplot(111, projection="3d") plt.gca().scatter(*np.vstack((p_perturb, p_proj)).T, s=500, depthshade=False, c=["r", "g"]) plt.gca().plot_trisurf(*tri.T, triangles=((0, 1, 2))) plt.show()
def _project_points_to_triangles(x, t): x_proj = np.empty((len(x), 3)) for i in range(len(x)): min_dist = np.inf for j in range(len(t)): p = project_point_to_triangle(x[i], t[j]) dist = np.linalg.norm(x[i] - p) if dist < min_dist: x_proj[i] = p min_dist = dist return x_proj
def query(self, query_point, query_radius, curr_node): # project a point onto its nearest triangles and find the nearest projection location nearest = (None, float("inf")) if type(curr_node) == Leaf: for tri in curr_node.bucket: # go through each point in the bucket and project it proj_point = project_point_to_triangle( query_point, tri, thickness=self.thickness) proj_dist = np.linalg.norm(query_point - proj_point) if proj_dist < nearest[1]: nearest = (proj_point, proj_dist) self.projection_count += len(curr_node.bucket) elif type(curr_node) == Node: dist = np.linalg.norm(query_point - curr_node.center) if dist > curr_node.radius + query_radius: # query and partition spheres are completely not overlapping nearest = self.query(query_point, query_radius, curr_node.outside_node) elif dist <= curr_node.radius - query_radius: # query and partition spheres are completely overlapping nearest = self.query(query_point, query_radius, curr_node.inside_node) else: # must examine both subtrees as the border of the query sphere overlaps the border of the partition sphere nearest_inside = self.query(query_point, query_radius, curr_node.inside_node) nearest_outside = self.query(query_point, query_radius, curr_node.outside_node) if nearest_inside[1] < nearest_outside[1]: nearest = nearest_inside else: nearest = nearest_outside return nearest
import numpy as np from matplotlib import pyplot as plt from mpl_toolkits.mplot3d import Axes3D from projection import project_point_to_triangle tri = np.array([[0.0, 0.0, 0.0], [0.0, 1.0, 0.0], [1.0, 1.0, 0.0]]) p_perturb = np.array([1.5, 1.5, 0.5]) p_proj = project_point_to_triangle(p_perturb, tri, thickness = 0.1) plt.figure(figsize = (15, 15)) plt.subplot(111, projection = "3d") plt.gca().scatter(*np.vstack((p_perturb, p_proj)).T, s = 500, depthshade = False, c = ["r", "g"]) plt.gca().plot_trisurf(*tri.T, triangles = ((0, 1, 2))) plt.show()