def closest_point_to_a_ray(point, ray): """ Definition to calculate the point on a ray that is closest to given point. Parameters ---------- point : list Given point in X,Y,Z. ray : ndarray Given ray. Returns --------- closest_point : ndarray Calculated closest point. """ from odak.raytracing import propagate_a_ray if len(ray.shape) == 2: ray = ray.reshape((1, 2, 3)) p0 = ray[:, 0] p1 = propagate_a_ray(ray, 1.) if len(p1.shape) == 2: p1 = p1.reshape((1, 2, 3)) p1 = p1[:, 0] p1 = p1.reshape(3) p0 = p0.reshape(3) point = point.reshape(3) closest_distance = -np.dot((p0 - point), (p1 - p0)) / np.sum((p1 - p0)**2) closest_point = propagate_a_ray(ray, closest_distance)[0] return closest_point
def get_triangle_normal(triangle, triangle_center=None): """ Definition to calculate surface normal of a triangle. Parameters ---------- triangle : ndarray Set of points in X,Y and Z to define a planar surface (3,3). It can also be list of triangles (mx3x3). triangle_center : ndarray Center point of the given triangle. See odak.raytracing.center_of_triangle for more. In many scenarios you can accelerate things by precomputing triangle centers. Returns ---------- normal : ndarray Surface normal at the point of intersection. """ triangle = np.asarray(triangle) if len(triangle.shape) == 2: triangle = triangle.reshape((1, 3, 3)) normal = np.zeros((triangle.shape[0], 2, 3)) direction = np.cross(triangle[:, 0] - triangle[:, 1], triangle[:, 2] - triangle[:, 1]) if type(triangle_center) == type(None): normal[:, 0] = center_of_triangle(triangle) else: normal[:, 0] = triangle_center normal[:, 1] = direction / np.sum(direction, axis=1)[0] if normal.shape[0] == 1: normal = normal.reshape((2, 3)) return normal
def point_to_ray_distance(point, ray_point_0, ray_point_1): """ Definition to find point's closest distance to a line represented with two points. Parameters ---------- point : ndarray Point to be tested. ray_point_0 : ndarray First point to represent a line. ray_point_1 : ndarray Second point to represent a line. Returns ---------- distance : float Calculated distance. """ distance = np.sum( np.cross((point - ray_point_0), (point - ray_point_1))**2) / np.sum( (ray_point_1 - ray_point_0)**2) return distance
def distance_between_two_points(point1, point2): """ Definition to calculate distance between two given points. Parameters ---------- point1 : list First point in X,Y,Z. point2 : list Second point in X,Y,Z. Returns ---------- distance : float Distance in between given two points. """ point1 = np.asarray(point1) point2 = np.asarray(point2) if len(point1.shape) == 1 and len(point2.shape) == 1: distance = np.sqrt(np.sum((point1 - point2)**2)) elif len(point1.shape) == 2 or len(point2.shape) == 2: distance = np.sqrt(np.sum((point1 - point2)**2, axis=1)) return distance
def intersect_parametric(ray, parametric_surface, surface_function, surface_normal_function, target_error=0.00000001, iter_no_limit=100000): """ Definition to intersect a ray with a parametric surface. Parameters ---------- ray : ndarray Ray. parametric_surface : ndarray Parameters of the surfaces. surface_function : function Function to evaluate a point against a surface. surface_normal_function : function Function to calculate surface normal for a given point on a surface. target_error : float Target error that defines the precision. iter_no_limit : int Maximum number of iterations. Returns ---------- distance : float Propagation distance. normal : ndarray Ray that defines a surface normal for the intersection. """ if len(ray.shape) == 2: ray = ray.reshape((1, 2, 3)) error = [150, 100] distance = [0, 0.1] iter_no = 0 while np.abs(np.max(np.asarray(error[1]))) > target_error: error[1], point = intersection_kernel_for_parametric_surfaces( distance[1], ray, parametric_surface, surface_function) distance, error = propagate_parametric_intersection_error( distance, error) iter_no += 1 if iter_no > iter_no_limit: return False, False if np.isnan(np.sum(point)): return False, False normal = surface_normal_function(point, parametric_surface) return distance[1], normal
def distance_between_point_clouds(points0, points1): """ A definition to find distance between every point in one cloud to other points in the other point cloud. Parameters ---------- points0 : ndarray Mx3 points. points1 : ndarray Nx3 points. Returns ---------- distances : ndarray MxN distances. """ c = points1.reshape((1, points1.shape[0], points1.shape[1])) a = np.repeat(c, points0.shape[0], axis=0) b = points0.reshape((points0.shape[0], 1, points0.shape[1])) b = np.repeat(b, a.shape[1], axis=1) distances = np.sqrt(np.sum((a - b)**2, axis=2)) return distances
def roi(image, location=[0, 100, 0, 100], threshold=[0, 1, 0, 1]): """ Definition to get the lines from a target ROI. Parameters ---------- image : ndarray a 2D image to be sliced (nxm). location : ndarray Locations for taking the ROI. threshold : list Threshold below and above these numbers. Returns ------- line_x : ndarray Line slice. line_y : ndarray Line slice. """ img = image[location[0]:location[1], location[2]:location[3]] if len(img.shape) == 3: img = np.sum(img, axis=2) line_x = img[:, int(img.shape[1] / 2)] line_y = img[int(img.shape[0] / 2), :] line_x = np.asarray(line_x) line_y = np.asarray(line_y) line_x = line_x - np.amin(line_x) line_x = line_x / np.amax(line_x) line_y = line_y - np.amin(line_y) line_y = line_y / np.amax(line_y) line_x[line_x < threshold[0]] = 0 line_x[line_x > threshold[1]] = 1 line_y[line_y < threshold[2]] = 0 line_y[line_y > threshold[3]] = 1 return line_x, line_y, img