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
예제 #3
0
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()