# odak.raytracing

odak.raytracing

Provides necessary definitions for geometric optics. See "General Ray tracing procedure" from G.H. Spencerand M.V.R.K Murty for the theoratical explanation.

## bring_plane_to_origin(point, plane, shape=[10.0, 10.0], center=[0.0, 0.0, 0.0], angles=[0.0, 0.0, 0.0], mode='XYZ')¶

Definition to bring points back to reference origin with respect to a plane.

Parameters:

• point
             Point(s) to be tested.

• shape
             Dimensions of the rectangle along X and Y axes.

• center
             Center of the rectangle.

• angles
             Rotation angle of the rectangle.

• mode
             Rotation mode of the rectangle, for more see odak.tools.rotate_point and odak.tools.rotate_points.


Returns:

• transformed_points ( ndarray ) –

Point(s) that are brought back to reference origin with respect to given plane.

Source code in odak/raytracing/primitives.py
 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 def bring_plane_to_origin(point, plane, shape=[10., 10.], center=[0., 0., 0.], angles=[0., 0., 0.], mode='XYZ'): """ Definition to bring points back to reference origin with respect to a plane. Parameters ---------- point : ndarray Point(s) to be tested. shape : list Dimensions of the rectangle along X and Y axes. center : list Center of the rectangle. angles : list Rotation angle of the rectangle. mode : str Rotation mode of the rectangle, for more see odak.tools.rotate_point and odak.tools.rotate_points. Returns ---------- transformed_points : ndarray Point(s) that are brought back to reference origin with respect to given plane. """ if point.shape[0] == 3: point = point.reshape((1, 3)) reverse_mode = mode[::-1] angles = [-angles[0], -angles[1], -angles[2]] center = np.asarray(center).reshape((1, 3)) transformed_points = point-center transformed_points = rotate_points( transformed_points, angles=angles, mode=reverse_mode, ) if transformed_points.shape[0] == 1: transformed_points = transformed_points.reshape((3,)) return transformed_points 

## calculate_intersection_of_two_rays(ray0, ray1)¶

Definition to calculate the intersection of two rays.

Parameters:

• ray0
     A ray.

• ray1
     A ray.


Returns:

• point ( ndarray ) –

Point in X,Y,Z.

• distances ( ndarray ) –

Distances.

Source code in odak/raytracing/ray.py
 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 def calculate_intersection_of_two_rays(ray0, ray1): """ Definition to calculate the intersection of two rays. Parameters ---------- ray0 : ndarray A ray. ray1 : ndarray A ray. Returns ---------- point : ndarray Point in X,Y,Z. distances : ndarray Distances. """ A = np.array([ [float(ray0[1][0]), float(ray1[1][0])], [float(ray0[1][1]), float(ray1[1][1])], [float(ray0[1][2]), float(ray1[1][2])] ]) B = np.array([ ray0[0][0]-ray1[0][0], ray0[0][1]-ray1[0][1], ray0[0][2]-ray1[0][2] ]) distances = np.linalg.lstsq(A, B, rcond=None)[0] if np.allclose(np.dot(A, distances), B) == False: distances = np.array([0, 0]) distances = distances[np.argsort(-distances)] point = propagate_a_ray(ray0, distances[0])[0] return point, distances 

## center_of_triangle(triangle)¶

Definition to calculate center of a triangle.

Parameters:

• triangle
        An array that contains three points defining a triangle (Mx3). It can also parallel process many triangles (NxMx3).

Source code in odak/raytracing/primitives.py
 73 74 75 76 77 78 79 80 81 82 83 84 85 def center_of_triangle(triangle): """ Definition to calculate center of a triangle. Parameters ---------- triangle : ndarray An array that contains three points defining a triangle (Mx3). It can also parallel process many triangles (NxMx3). """ if len(triangle.shape) == 2: triangle = triangle.reshape((1, 3, 3)) center = np.mean(triangle, axis=1) return center 

## closest_point_to_a_ray(point, ray)¶

Definition to calculate the point on a ray that is closest to given point.

Parameters:

• point
        Given point in X,Y,Z.

• ray
        Given ray.


Returns:

• closest_point ( ndarray ) –

Calculated closest point.

Source code in odak/tools/vector.py
 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 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 

## create_ray(x0y0z0, abg)¶

Definition to create a ray.

Parameters:

• x0y0z0
       List that contains X,Y and Z start locations of a ray.

• abg
       List that contaings angles in degrees with respect to the X,Y and Z axes.


Returns:

• ray ( ndarray ) –

Array that contains starting points and cosines of a created ray.

Source code in odak/raytracing/ray.py
  5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 def create_ray(x0y0z0, abg): """ Definition to create a ray. Parameters ---------- x0y0z0 : list List that contains X,Y and Z start locations of a ray. abg : list List that contaings angles in degrees with respect to the X,Y and Z axes. Returns ---------- ray : ndarray Array that contains starting points and cosines of a created ray. """ # Due to Python 2 -> Python 3. x0, y0, z0 = x0y0z0 alpha, beta, gamma = abg # Create a vector with the given points and angles in each direction point = np.array([x0, y0, z0], dtype=np.float64) alpha = np.cos(np.radians(alpha)) beta = np.cos(np.radians(beta)) gamma = np.cos(np.radians(gamma)) # Cosines vector. cosines = np.array([alpha, beta, gamma], dtype=np.float64) ray = np.array([point, cosines], dtype=np.float64) return ray 

## create_ray_from_angles(point, angles, mode='XYZ')¶

Definition to create a ray from a point and angles.

Parameters:

• point
     Point in X,Y and Z.

• angles
     Angles with X,Y,Z axes in degrees. All zeros point Z axis.

• mode
     Rotation mode determines ordering of the rotations at each axis. There are XYZ,YXZ    ,ZXY and ZYX modes.


Returns:

• ray ( ndarray ) –

Created ray.

Source code in odak/raytracing/ray.py
  74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 def create_ray_from_angles(point, angles, mode='XYZ'): """ Definition to create a ray from a point and angles. Parameters ---------- point : ndarray Point in X,Y and Z. angles : ndarray Angles with X,Y,Z axes in degrees. All zeros point Z axis. mode : str Rotation mode determines ordering of the rotations at each axis. There are XYZ,YXZ ,ZXY and ZYX modes. Returns ---------- ray : ndarray Created ray. """ if len(point.shape) == 1: point = point.reshape((1, 3)) new_point = np.zeros(point.shape) new_point[:, 2] += 5. new_point = rotate_points(new_point, angles, mode=mode, offset=point[:, 0]) ray = create_ray_from_two_points(point, new_point) if ray.shape[0] == 1: ray = ray.reshape((2, 3)) return ray 

## create_ray_from_two_points(x0y0z0, x1y1z1)¶

Definition to create a ray from two given points. Note that both inputs must match in shape.

Parameters:

• x0y0z0
       List that contains X,Y and Z start locations of a ray (3). It can also be a list of points as well (mx3). This is the starting point.

• x1y1z1
       List that contains X,Y and Z ending locations of a ray (3). It can also be a list of points as well (mx3). This is the end point.


Returns:

• ray ( ndarray ) –

Array that contains starting points and cosines of a created ray.

Source code in odak/raytracing/ray.py
 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 def create_ray_from_two_points(x0y0z0, x1y1z1): """ Definition to create a ray from two given points. Note that both inputs must match in shape. Parameters ---------- x0y0z0 : list List that contains X,Y and Z start locations of a ray (3). It can also be a list of points as well (mx3). This is the starting point. x1y1z1 : list List that contains X,Y and Z ending locations of a ray (3). It can also be a list of points as well (mx3). This is the end point. Returns ---------- ray : ndarray Array that contains starting points and cosines of a created ray. """ x0y0z0 = np.asarray(x0y0z0, dtype=np.float64) x1y1z1 = np.asarray(x1y1z1, dtype=np.float64) if len(x0y0z0.shape) == 1: x0y0z0 = x0y0z0.reshape((1, 3)) if len(x1y1z1.shape) == 1: x1y1z1 = x1y1z1.reshape((1, 3)) xdiff = x1y1z1[:, 0] - x0y0z0[:, 0] ydiff = x1y1z1[:, 1] - x0y0z0[:, 1] zdiff = x1y1z1[:, 2] - x0y0z0[:, 2] s = np.sqrt(xdiff ** 2 + ydiff ** 2 + zdiff ** 2) s[s == 0] = np.nan cosines = np.zeros((xdiff.shape[0], 3)) cosines[:, 0] = xdiff/s cosines[:, 1] = ydiff/s cosines[:, 2] = zdiff/s ray = np.zeros((xdiff.shape[0], 2, 3), dtype=np.float64) ray[:, 0] = x0y0z0 ray[:, 1] = cosines if ray.shape[0] == 1: ray = ray.reshape((2, 3)) return ray 

## cylinder_function(point, cylinder)¶

Definition of a cylinder function. Evaluate a point against a cylinder function. Inspired from https://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html

Parameters:

• cylinder
     Cylinder parameters, XYZ center and radius.

• point
     Point in XYZ.

Return

result : float Result of the evaluation. Zero if point is on sphere.

Source code in odak/raytracing/primitives.py
 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 def cylinder_function(point, cylinder): """ Definition of a cylinder function. Evaluate a point against a cylinder function. Inspired from https://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html Parameters ---------- cylinder : ndarray Cylinder parameters, XYZ center and radius. point : ndarray Point in XYZ. Return ---------- result : float Result of the evaluation. Zero if point is on sphere. """ point = np.asarray(point) if len(point.shape) == 1: point = point.reshape((1, 3)) distance = point_to_ray_distance( point, np.array([cylinder[0], cylinder[1], cylinder[2]], dtype=np.float64), np.array([cylinder[4], cylinder[5], cylinder[6]], dtype=np.float64) ) r = cylinder[3] result = distance - r ** 2 return result 

## define_circle(center, radius, angles)¶

Definition to describe a circle in a single variable packed form.

Parameters:

• center
  Center of a circle to be defined.

• radius
  Radius of a circle to be defined.

• angles
  Angular tilt of a circle.


Returns:

• circle ( list ) –

Single variable packed form.

Source code in odak/raytracing/primitives.py
 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 def define_circle(center, radius, angles): """ Definition to describe a circle in a single variable packed form. Parameters ---------- center : float Center of a circle to be defined. radius : float Radius of a circle to be defined. angles : float Angular tilt of a circle. Returns ---------- circle : list Single variable packed form. """ points = define_plane(center, angles=angles) circle = [ points, center, radius ] return circle 

## define_cylinder(center, radius, rotation=[0.0, 0.0, 0.0])¶

Definition to define a cylinder

Parameters:

• center
     Center of a cylinder in X,Y,Z.

• radius
     Radius of a cylinder along X axis.

• rotation
     Direction angles in degrees for the orientation of a cylinder.


Returns:

• cylinder ( ndarray ) –

Single variable packed form.

Source code in odak/raytracing/primitives.py
 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 def define_cylinder(center, radius, rotation=[0., 0., 0.]): """ Definition to define a cylinder Parameters ---------- center : ndarray Center of a cylinder in X,Y,Z. radius : float Radius of a cylinder along X axis. rotation : list Direction angles in degrees for the orientation of a cylinder. Returns ---------- cylinder : ndarray Single variable packed form. """ cylinder_ray = create_ray_from_angles( np.asarray(center), np.asarray(rotation)) cylinder = np.array( [ center[0], center[1], center[2], radius, center[0]+cylinder_ray[1, 0], center[1]+cylinder_ray[1, 1], center[2]+cylinder_ray[1, 2] ], dtype=np.float64 ) return cylinder 

## define_plane(point, angles=[0.0, 0.0, 0.0])¶

Definition to generate a rotation matrix along X axis.

Parameters:

• point
       A point that is at the center of a plane.

• angles
       Rotation angles in degrees.


Returns:

• plane ( ndarray ) –

Points defining plane.

Source code in odak/raytracing/primitives.py
  7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 def define_plane(point, angles=[0., 0., 0.]): """ Definition to generate a rotation matrix along X axis. Parameters ---------- point : ndarray A point that is at the center of a plane. angles : list Rotation angles in degrees. Returns ---------- plane : ndarray Points defining plane. """ plane = np.array([ [10., 10., 0.], [0., 10., 0.], [0., 0., 0.] ], dtype=np.float64) point = np.asarray(point) for i in range(0, plane.shape[0]): plane[i], _, _, _ = rotate_point(plane[i], angles=angles) plane[i] = plane[i]+point return plane 

## define_sphere(center, radius)¶

Definition to define a sphere.

Parameters:

• center
     Center of a sphere in X,Y,Z.

• radius
     Radius of a sphere.


Returns:

• sphere ( ndarray ) –

Single variable packed form.

Source code in odak/raytracing/primitives.py
 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 def define_sphere(center, radius): """ Definition to define a sphere. Parameters ---------- center : ndarray Center of a sphere in X,Y,Z. radius : float Radius of a sphere. Returns ---------- sphere : ndarray Single variable packed form. """ sphere = np.array( [center[0], center[1], center[2], radius], dtype=np.float64) return sphere 

## distance_between_two_points(point1, point2)¶

Definition to calculate distance between two given points.

Parameters:

• point1
      First point in X,Y,Z.

• point2
      Second point in X,Y,Z.


Returns:

• distance ( float ) –

Distance in between given two points.

Source code in odak/tools/vector.py
 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 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 

## find_nearest_points(ray0, ray1)¶

Find the nearest points on given rays with respect to the other ray.

Parameters:

• ray0
     A ray.

• ray1
     A ray.


Returns:

• c0 ( ndarray ) –

Closest point on ray0.

• c1 ( ndarray ) –

Closest point on ray1.

Source code in odak/raytracing/ray.py
 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 def find_nearest_points(ray0, ray1): """ Find the nearest points on given rays with respect to the other ray. Parameters ---------- ray0 : ndarray A ray. ray1 : ndarray A ray. Returns ---------- c0 : ndarray Closest point on ray0. c1 : ndarray Closest point on ray1. """ p0 = ray0[0].reshape(3,) d0 = ray0[1].reshape(3,) p1 = ray1[0].reshape(3,) d1 = ray1[1].reshape(3,) n = np.cross(d0, d1) if np.all(n) == 0: point, distances = calculate_intersection_of_two_rays(ray0, ray1) c0 = c1 = point else: n0 = np.cross(d0, n) n1 = np.cross(d1, n) c0 = p0+(np.dot((p1-p0), n1)/np.dot(d0, n1))*d0 c1 = p1+(np.dot((p0-p1), n0)/np.dot(d1, n0))*d1 return c0, c1 

## get_cylinder_normal(point, cylinder)¶

Parameters:

• point
        Point on a cylinder defined in X,Y,Z.


Returns:

• normal_vector ( ndarray ) –

Normal vector.

Source code in odak/raytracing/boundary.py
 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 def get_cylinder_normal(point, cylinder): """ Parameters ---------- point : ndarray Point on a cylinder defined in X,Y,Z. Returns ---------- normal_vector : ndarray Normal vector. """ cylinder_ray = create_ray_from_two_points(cylinder[0:3], cylinder[4:7]) closest_point = closest_point_to_a_ray( point, cylinder_ray ) normal_vector = create_ray_from_two_points(closest_point, point) return normal_vector 

## get_sphere_normal(point, sphere)¶

Definition to get a normal of a point on a given sphere.

Parameters:

• point
        Point on sphere in X,Y,Z.

• sphere
        Center defined in X,Y,Z and radius.


Returns:

• normal_vector ( ndarray ) –

Normal vector.

Source code in odak/raytracing/boundary.py
 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 def get_sphere_normal(point, sphere): """ Definition to get a normal of a point on a given sphere. Parameters ---------- point : ndarray Point on sphere in X,Y,Z. sphere : ndarray Center defined in X,Y,Z and radius. Returns ---------- normal_vector : ndarray Normal vector. """ if len(point.shape) == 1: point = point.reshape((1, 3)) normal_vector = create_ray_from_two_points(point, sphere[0:3]) return normal_vector 

## get_triangle_normal(triangle, triangle_center=None)¶

Definition to calculate surface normal of a triangle.

Parameters:

• triangle
          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, default: None ) –
          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.

Source code in odak/raytracing/boundary.py
  83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 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 

## intersect_parametric(ray, parametric_surface, surface_function, surface_normal_function, target_error=1e-08, iter_no_limit=100000)¶

Definition to intersect a ray with a parametric surface.

Parameters:

• ray
                  Ray.

• parametric_surface
                  Parameters of the surfaces.

• surface_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
                  Target error that defines the precision.

• iter_no_limit
                  Maximum number of iterations.


Returns:

• distance ( float ) –

Propagation distance.

• normal ( ndarray ) –

Ray that defines a surface normal for the intersection.

Source code in odak/raytracing/boundary.py
 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 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 

## intersect_w_circle(ray, circle)¶

Definition to find intersection point of a ray with a circle. Returns False for each variable if the ray doesn't intersect with a given circle. Returns distance as zero if there isn't an intersection.

Parameters:

• ray
       A vector/ray.

• circle
       A list that contains (0) Set of points in X,Y and Z to define plane of a circle, (1) circle center, and (2) circle radius.


Returns:

• normal ( ndarray ) –

Surface normal at the point of intersection.

• distance ( float ) –

Distance in between a starting point of a ray and the intersection point with a given triangle.

Source code in odak/raytracing/boundary.py
 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 def intersect_w_circle(ray, circle): """ Definition to find intersection point of a ray with a circle. Returns False for each variable if the ray doesn't intersect with a given circle. Returns distance as zero if there isn't an intersection. Parameters ---------- ray : ndarray A vector/ray. circle : list A list that contains (0) Set of points in X,Y and Z to define plane of a circle, (1) circle center, and (2) circle radius. Returns ---------- normal : ndarray Surface normal at the point of intersection. distance : float Distance in between a starting point of a ray and the intersection point with a given triangle. """ normal, distance = intersect_w_surface(ray, circle[0]) if len(normal.shape) == 2: normal = normal.reshape((1, 2, 3)) distance_to_center = distance_between_two_points(normal[:, 0], circle[1]) distance[np.nonzero(distance_to_center > circle[2])] = 0 if len(ray.shape) == 2: normal = normal.reshape((2, 3)) return normal, distance 

## intersect_w_cylinder(ray, cylinder)¶

Definition to intersect a ray with a cylinder.

Parameters:

• ray
     A ray definition.

• cylinder
     A cylinder defined with a center in XYZ and radius of curvature.


Returns:

• normal ( ndarray ) –

A ray defining surface normal at the point of intersection.

• distance ( float ) –

Total optical propagation distance.

Source code in odak/raytracing/boundary.py
 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 def intersect_w_cylinder(ray, cylinder): """ Definition to intersect a ray with a cylinder. Parameters ---------- ray : ndarray A ray definition. cylinder : ndarray A cylinder defined with a center in XYZ and radius of curvature. Returns ---------- normal : ndarray A ray defining surface normal at the point of intersection. distance : float Total optical propagation distance. """ distance, normal = intersect_parametric( ray, cylinder, cylinder_function, get_cylinder_normal ) return normal, distance 

## intersect_w_sphere(ray, sphere)¶

Definition to intersect a ray with a sphere.

Parameters:

• ray
     A ray definition.

• sphere
     A sphere defined with a center in XYZ and radius of curvature.


Returns:

• normal ( ndarray ) –

A ray defining surface normal at the point of intersection.

• distance ( float ) –

Total optical propagation distance.

Source code in odak/raytracing/boundary.py
 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 def intersect_w_sphere(ray, sphere): """ Definition to intersect a ray with a sphere. Parameters ---------- ray : ndarray A ray definition. sphere : ndarray A sphere defined with a center in XYZ and radius of curvature. Returns ---------- normal : ndarray A ray defining surface normal at the point of intersection. distance : float Total optical propagation distance. """ distance, normal = intersect_parametric( ray, sphere, sphere_function, get_sphere_normal ) return normal, distance 

## intersect_w_surface(ray, points)¶

Definition to find intersection point inbetween a surface and a ray. For more see: http://geomalgorithms.com/a06-_intersect-2.html

Parameters:

• ray
       A vector/ray.

• points
       Set of points in X,Y and Z to define a planar surface.


Returns:

• normal ( ndarray ) –

Surface normal at the point of intersection.

• distance ( float ) –

Distance in between starting point of a ray with it's intersection with a planar surface.

Source code in odak/raytracing/boundary.py
 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 def intersect_w_surface(ray, points): """ Definition to find intersection point inbetween a surface and a ray. For more see: http://geomalgorithms.com/a06-_intersect-2.html Parameters ---------- ray : ndarray A vector/ray. points : ndarray Set of points in X,Y and Z to define a planar surface. Returns ---------- normal : ndarray Surface normal at the point of intersection. distance : float Distance in between starting point of a ray with it's intersection with a planar surface. """ points = np.asarray(points) normal = get_triangle_normal(points) if len(ray.shape) == 2: ray = ray.reshape((1, 2, 3)) if len(points) == 2: points = points.reshape((1, 3, 3)) if len(normal.shape) == 2: normal = normal.reshape((1, 2, 3)) f = normal[:, 0]-ray[:, 0] distance = np.dot(normal[:, 1], f.T)/np.dot(normal[:, 1], ray[:, 1].T) n = np.int64(np.amax(np.array([ray.shape[0], normal.shape[0]]))) normal = np.zeros((n, 2, 3)) normal[:, 0] = ray[:, 0]+distance.T*ray[:, 1] distance = np.abs(distance) if normal.shape[0] == 1: normal = normal.reshape((2, 3)) distance = distance.reshape((1)) if distance.shape[0] == 1 and len(distance.shape) > 1: distance = distance.reshape((distance.shape[1])) return normal, distance 

## intersect_w_triangle(ray, triangle)¶

Definition to find intersection point of a ray with a triangle. Returns False for each variable if the ray doesn't intersect with a given triangle.

Parameters:

• ray
       A vector/ray (2 x 3). It can also be a list of rays (n x 2 x 3).

• triangle
       Set of points in X,Y and Z to define a planar surface. It can also be a list of triangles (m x 3 x 3).


Returns:

• normal ( ndarray ) –

Surface normal at the point of intersection.

• distance ( float ) –

Distance in between a starting point of a ray and the intersection point with a given triangle.

Source code in odak/raytracing/boundary.py
 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 def intersect_w_triangle(ray, triangle): """ Definition to find intersection point of a ray with a triangle. Returns False for each variable if the ray doesn't intersect with a given triangle. Parameters ---------- ray : torch.tensor A vector/ray (2 x 3). It can also be a list of rays (n x 2 x 3). triangle : torch.tensor Set of points in X,Y and Z to define a planar surface. It can also be a list of triangles (m x 3 x 3). Returns ---------- normal : ndarray Surface normal at the point of intersection. distance : float Distance in between a starting point of a ray and the intersection point with a given triangle. """ normal, distance = intersect_w_surface(ray, triangle) if is_it_on_triangle(normal[0], triangle[0], triangle[1], triangle[2]) == False: return 0, 0 return normal, distance 

## intersection_kernel_for_parametric_surfaces(distance, ray, parametric_surface, surface_function)¶

Definition for the intersection kernel when dealing with parametric surfaces.

Parameters:

• distance
             Distance.

• ray
             Ray.

• parametric_surface (ndarray) –
             Array that defines a parametric surface.

• surface_function
             Function to evaluate a point against a parametric surface.


Returns:

• point ( ndarray ) –

Location in X,Y,Z after propagation.

• error ( float ) –

Error.

Source code in odak/raytracing/boundary.py
 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 def intersection_kernel_for_parametric_surfaces(distance, ray, parametric_surface, surface_function): """ Definition for the intersection kernel when dealing with parametric surfaces. Parameters ---------- distance : float Distance. ray : ndarray Ray. parametric_surface : ndarray Array that defines a parametric surface. surface_function : ndarray Function to evaluate a point against a parametric surface. Returns ---------- point : ndarray Location in X,Y,Z after propagation. error : float Error. """ new_ray = propagate_a_ray(ray, distance) if len(new_ray) == 2: new_ray = new_ray.reshape((1, 2, 3)) point = new_ray[:, 0] error = surface_function(point, parametric_surface) return error, point 

## is_it_on_triangle(pointtocheck, point0, point1, point2)¶

Definition to check if a given point is inside a triangle. If the given point is inside a defined triangle, this definition returns True.

Parameters:

• pointtocheck
        Point to check.

• point0
        First point of a triangle.

• point1
        Second point of a triangle.

• point2
        Third point of a triangle.

Source code in odak/raytracing/primitives.py
  88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 def is_it_on_triangle(pointtocheck, point0, point1, point2): """ Definition to check if a given point is inside a triangle. If the given point is inside a defined triangle, this definition returns True. Parameters ---------- pointtocheck : list Point to check. point0 : list First point of a triangle. point1 : list Second point of a triangle. point2 : list Third point of a triangle. """ # point0, point1 and point2 are the corners of the triangle. pointtocheck = np.asarray(pointtocheck).reshape(3) point0 = np.asarray(point0) point1 = np.asarray(point1) point2 = np.asarray(point2) side0 = same_side(pointtocheck, point0, point1, point2) side1 = same_side(pointtocheck, point1, point0, point2) side2 = same_side(pointtocheck, point2, point0, point1) if side0 == True and side1 == True and side2 == True: return True return False 

## 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
      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.

Source code in odak/tools/vector.py
 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 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 

## propagate_a_ray(ray, distance)¶

Definition to propagate a ray at a certain given distance.

Parameters:

• ray
     A ray.

• distance
     Distance.


Returns:

• new_ray ( ndarray ) –

Propagated ray.

Source code in odak/raytracing/ray.py
 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 def propagate_a_ray(ray, distance): """ Definition to propagate a ray at a certain given distance. Parameters ---------- ray : ndarray A ray. distance : float Distance. Returns ---------- new_ray : ndarray Propagated ray. """ if len(ray.shape) == 2: ray = ray.reshape((1, 2, 3)) new_ray = np.copy(ray) new_ray[:, 0, 0] = distance*new_ray[:, 1, 0] + new_ray[:, 0, 0] new_ray[:, 0, 1] = distance*new_ray[:, 1, 1] + new_ray[:, 0, 1] new_ray[:, 0, 2] = distance*new_ray[:, 1, 2] + new_ray[:, 0, 2] if new_ray.shape[0] == 1: new_ray = new_ray.reshape((2, 3)) return new_ray 

## propagate_parametric_intersection_error(distance, error)¶

Definition to propagate the error in parametric intersection to find the next distance to try.

Parameters:

• distance
       List that contains the new and the old distance.

• error
       List that contains the new and the old error.


Returns:

• distance ( list ) –

New distance.

• error ( list ) –

New error.

Source code in odak/raytracing/boundary.py
 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 def propagate_parametric_intersection_error(distance, error): """ Definition to propagate the error in parametric intersection to find the next distance to try. Parameters ---------- distance : list List that contains the new and the old distance. error : list List that contains the new and the old error. Returns ---------- distance : list New distance. error : list New error. """ new_distance = distance[1]-error[1] * \ (distance[1]-distance[0])/(error[1]-error[0]) distance[0] = distance[1] distance[1] = np.abs(new_distance) error[0] = error[1] return distance, error 

## reflect(input_ray, normal)¶

Definition to reflect an incoming ray from a surface defined by a surface normal. Used method described in G.H. Spencer and M.V.R.K. Murty, "General Ray-Tracing Procedure", 1961.

Parameters:

• input_ray
       A vector/ray (2x3). It can also be a list of rays (nx2x3).

• normal
       A surface normal (2x3). It also be a list of normals (nx2x3).


Returns:

• output_ray ( ndarray ) –

Array that contains starting points and cosines of a reflected ray.

Source code in odak/raytracing/boundary.py
  7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 def reflect(input_ray, normal): """ Definition to reflect an incoming ray from a surface defined by a surface normal. Used method described in G.H. Spencer and M.V.R.K. Murty, "General Ray-Tracing Procedure", 1961. Parameters ---------- input_ray : ndarray A vector/ray (2x3). It can also be a list of rays (nx2x3). normal : ndarray A surface normal (2x3). It also be a list of normals (nx2x3). Returns ---------- output_ray : ndarray Array that contains starting points and cosines of a reflected ray. """ input_ray = np.asarray(input_ray) normal = np.asarray(normal) if len(input_ray.shape) == 2: input_ray = input_ray.reshape((1, 2, 3)) if len(normal.shape) == 2: normal = normal.reshape((1, 2, 3)) mu = 1 div = normal[:, 1, 0]**2 + normal[:, 1, 1]**2 + normal[:, 1, 2]**2 a = mu * (input_ray[:, 1, 0]*normal[:, 1, 0] + input_ray[:, 1, 1]*normal[:, 1, 1] + input_ray[:, 1, 2]*normal[:, 1, 2]) / div n = np.int64(np.amax(np.array([normal.shape[0], input_ray.shape[0]]))) output_ray = np.zeros((n, 2, 3)) output_ray[:, 0] = normal[:, 0] output_ray[:, 1] = input_ray[:, 1]-2*a*normal[:, 1] if output_ray.shape[0] == 1: output_ray = output_ray.reshape((2, 3)) return output_ray 

## rotate_point(point, angles=[0, 0, 0], mode='XYZ', origin=[0, 0, 0], offset=[0, 0, 0])¶

Definition to rotate a given point. Note that rotation is always with respect to 0,0,0.

Parameters:

• point
       A point.

• angles
       Rotation angles in degrees.

• mode
       Rotation mode determines ordering of the rotations at each axis. There are XYZ,YXZ,ZXY and ZYX modes.

• origin
       Reference point for a rotation.

• offset
       Shift with the given offset.


Returns:

• result ( ndarray ) –

Result of the rotation

• rotx ( ndarray ) –

Rotation matrix along X axis.

• roty ( ndarray ) –

Rotation matrix along Y axis.

• rotz ( ndarray ) –

Rotation matrix along Z axis.

Source code in odak/tools/transformation.py
  76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 def rotate_point(point, angles = [0, 0, 0], mode = 'XYZ', origin = [0, 0, 0], offset = [0, 0, 0]): """ Definition to rotate a given point. Note that rotation is always with respect to 0,0,0. Parameters ---------- point : ndarray A point. angles : list Rotation angles in degrees. mode : str Rotation mode determines ordering of the rotations at each axis. There are XYZ,YXZ,ZXY and ZYX modes. origin : list Reference point for a rotation. offset : list Shift with the given offset. Returns ---------- result : ndarray Result of the rotation rotx : ndarray Rotation matrix along X axis. roty : ndarray Rotation matrix along Y axis. rotz : ndarray Rotation matrix along Z axis. """ point = np.asarray(point) point -= np.asarray(origin) rotx = rotmatx(angles[0]) roty = rotmaty(angles[1]) rotz = rotmatz(angles[2]) if mode == 'XYZ': result = np.dot(rotz, np.dot(roty, np.dot(rotx, point))) elif mode == 'XZY': result = np.dot(roty, np.dot(rotz, np.dot(rotx, point))) elif mode == 'YXZ': result = np.dot(rotz, np.dot(rotx, np.dot(roty, point))) elif mode == 'ZXY': result = np.dot(roty, np.dot(rotx, np.dot(rotz, point))) elif mode == 'ZYX': result = np.dot(rotx, np.dot(roty, np.dot(rotz, point))) result += np.asarray(origin) result += np.asarray(offset) return result, rotx, roty, rotz 

## rotate_points(points, angles=[0, 0, 0], mode='XYZ', origin=[0, 0, 0], offset=[0, 0, 0])¶

Definition to rotate points.

Parameters:

• points
       Points.

• angles
       Rotation angles in degrees.

• mode
       Rotation mode determines ordering of the rotations at each axis. There are XYZ,YXZ,ZXY and ZYX modes.

• origin
       Reference point for a rotation.

• offset
       Shift with the given offset.


Returns:

• result ( ndarray ) –

Result of the rotation

Source code in odak/tools/transformation.py
 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 def rotate_points(points, angles = [0, 0, 0], mode = 'XYZ', origin = [0, 0, 0], offset = [0, 0, 0]): """ Definition to rotate points. Parameters ---------- points : ndarray Points. angles : list Rotation angles in degrees. mode : str Rotation mode determines ordering of the rotations at each axis. There are XYZ,YXZ,ZXY and ZYX modes. origin : list Reference point for a rotation. offset : list Shift with the given offset. Returns ---------- result : ndarray Result of the rotation """ points = np.asarray(points) if angles[0] == 0 and angles[1] == 0 and angles[2] == 0: result = np.array(offset) + points return result points -= np.array(origin) rotx = rotmatx(angles[0]) roty = rotmaty(angles[1]) rotz = rotmatz(angles[2]) if mode == 'XYZ': result = np.dot(rotz, np.dot(roty, np.dot(rotx, points.T))).T elif mode == 'XZY': result = np.dot(roty, np.dot(rotz, np.dot(rotx, points.T))).T elif mode == 'YXZ': result = np.dot(rotz, np.dot(rotx, np.dot(roty, points.T))).T elif mode == 'ZXY': result = np.dot(roty, np.dot(rotx, np.dot(rotz, points.T))).T elif mode == 'ZYX': result = np.dot(rotx, np.dot(roty, np.dot(rotz, points.T))).T result += np.array(origin) result += np.array(offset) return result 

## same_side(p1, p2, a, b)¶

Definition to figure which side a point is on with respect to a line and a point. See http://www.blackpawn.com/texts/pointinpoly/ for more. If p1 and p2 are on the sameside, this definition returns True.

Parameters:

• p1
      Point(s) to check.

• p2
      This is the point check against.

• a
      First point that forms the line.

• b
      Second point that forms the line.

Source code in odak/tools/vector.py
 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 def same_side(p1, p2, a, b): """ Definition to figure which side a point is on with respect to a line and a point. See http://www.blackpawn.com/texts/pointinpoly/ for more. If p1 and p2 are on the sameside, this definition returns True. Parameters ---------- p1 : list Point(s) to check. p2 : list This is the point check against. a : list First point that forms the line. b : list Second point that forms the line. """ ba = np.subtract(b, a) p1a = np.subtract(p1, a) p2a = np.subtract(p2, a) cp1 = np.cross(ba, p1a) cp2 = np.cross(ba, p2a) test = np.dot(cp1, cp2) if len(p1.shape) > 1: return test >= 0 if test >= 0: return True return False 

## sphere_function(point, sphere)¶

Definition of a sphere function. Evaluate a point against a sphere function.

Parameters:

• sphere
     Sphere parameters, XYZ center and radius.

• point
     Point in XYZ.

Return

result : float Result of the evaluation. Zero if point is on sphere.

Source code in odak/raytracing/primitives.py
 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 def sphere_function(point, sphere): """ Definition of a sphere function. Evaluate a point against a sphere function. Parameters ---------- sphere : ndarray Sphere parameters, XYZ center and radius. point : ndarray Point in XYZ. Return ---------- result : float Result of the evaluation. Zero if point is on sphere. """ point = np.asarray(point) if len(point.shape) == 1: point = point.reshape((1, 3)) result = (point[:, 0]-sphere[0])**2 + (point[:, 1]-sphere[1] )**2 + (point[:, 2]-sphere[2])**2 - sphere[3]**2 return result 

## get_cylinder_normal(point, cylinder)¶

Parameters:

• point
        Point on a cylinder defined in X,Y,Z.


Returns:

• normal_vector ( ndarray ) –

Normal vector.

Source code in odak/raytracing/boundary.py
 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 def get_cylinder_normal(point, cylinder): """ Parameters ---------- point : ndarray Point on a cylinder defined in X,Y,Z. Returns ---------- normal_vector : ndarray Normal vector. """ cylinder_ray = create_ray_from_two_points(cylinder[0:3], cylinder[4:7]) closest_point = closest_point_to_a_ray( point, cylinder_ray ) normal_vector = create_ray_from_two_points(closest_point, point) return normal_vector 

## get_sphere_normal(point, sphere)¶

Definition to get a normal of a point on a given sphere.

Parameters:

• point
        Point on sphere in X,Y,Z.

• sphere
        Center defined in X,Y,Z and radius.


Returns:

• normal_vector ( ndarray ) –

Normal vector.

Source code in odak/raytracing/boundary.py
 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 def get_sphere_normal(point, sphere): """ Definition to get a normal of a point on a given sphere. Parameters ---------- point : ndarray Point on sphere in X,Y,Z. sphere : ndarray Center defined in X,Y,Z and radius. Returns ---------- normal_vector : ndarray Normal vector. """ if len(point.shape) == 1: point = point.reshape((1, 3)) normal_vector = create_ray_from_two_points(point, sphere[0:3]) return normal_vector 

## get_triangle_normal(triangle, triangle_center=None)¶

Definition to calculate surface normal of a triangle.

Parameters:

• triangle
          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, default: None ) –
          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.

Source code in odak/raytracing/boundary.py
  83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 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 

## intersect_parametric(ray, parametric_surface, surface_function, surface_normal_function, target_error=1e-08, iter_no_limit=100000)¶

Definition to intersect a ray with a parametric surface.

Parameters:

• ray
                  Ray.

• parametric_surface
                  Parameters of the surfaces.

• surface_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
                  Target error that defines the precision.

• iter_no_limit
                  Maximum number of iterations.


Returns:

• distance ( float ) –

Propagation distance.

• normal ( ndarray ) –

Ray that defines a surface normal for the intersection.

Source code in odak/raytracing/boundary.py
 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 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 

## intersect_w_circle(ray, circle)¶

Definition to find intersection point of a ray with a circle. Returns False for each variable if the ray doesn't intersect with a given circle. Returns distance as zero if there isn't an intersection.

Parameters:

• ray
       A vector/ray.

• circle
       A list that contains (0) Set of points in X,Y and Z to define plane of a circle, (1) circle center, and (2) circle radius.


Returns:

• normal ( ndarray ) –

Surface normal at the point of intersection.

• distance ( float ) –

Distance in between a starting point of a ray and the intersection point with a given triangle.

Source code in odak/raytracing/boundary.py
 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 def intersect_w_circle(ray, circle): """ Definition to find intersection point of a ray with a circle. Returns False for each variable if the ray doesn't intersect with a given circle. Returns distance as zero if there isn't an intersection. Parameters ---------- ray : ndarray A vector/ray. circle : list A list that contains (0) Set of points in X,Y and Z to define plane of a circle, (1) circle center, and (2) circle radius. Returns ---------- normal : ndarray Surface normal at the point of intersection. distance : float Distance in between a starting point of a ray and the intersection point with a given triangle. """ normal, distance = intersect_w_surface(ray, circle[0]) if len(normal.shape) == 2: normal = normal.reshape((1, 2, 3)) distance_to_center = distance_between_two_points(normal[:, 0], circle[1]) distance[np.nonzero(distance_to_center > circle[2])] = 0 if len(ray.shape) == 2: normal = normal.reshape((2, 3)) return normal, distance 

## intersect_w_cylinder(ray, cylinder)¶

Definition to intersect a ray with a cylinder.

Parameters:

• ray
     A ray definition.

• cylinder
     A cylinder defined with a center in XYZ and radius of curvature.


Returns:

• normal ( ndarray ) –

A ray defining surface normal at the point of intersection.

• distance ( float ) –

Total optical propagation distance.

Source code in odak/raytracing/boundary.py
 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 def intersect_w_cylinder(ray, cylinder): """ Definition to intersect a ray with a cylinder. Parameters ---------- ray : ndarray A ray definition. cylinder : ndarray A cylinder defined with a center in XYZ and radius of curvature. Returns ---------- normal : ndarray A ray defining surface normal at the point of intersection. distance : float Total optical propagation distance. """ distance, normal = intersect_parametric( ray, cylinder, cylinder_function, get_cylinder_normal ) return normal, distance 

## intersect_w_sphere(ray, sphere)¶

Definition to intersect a ray with a sphere.

Parameters:

• ray
     A ray definition.

• sphere
     A sphere defined with a center in XYZ and radius of curvature.


Returns:

• normal ( ndarray ) –

A ray defining surface normal at the point of intersection.

• distance ( float ) –

Total optical propagation distance.

Source code in odak/raytracing/boundary.py
 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 def intersect_w_sphere(ray, sphere): """ Definition to intersect a ray with a sphere. Parameters ---------- ray : ndarray A ray definition. sphere : ndarray A sphere defined with a center in XYZ and radius of curvature. Returns ---------- normal : ndarray A ray defining surface normal at the point of intersection. distance : float Total optical propagation distance. """ distance, normal = intersect_parametric( ray, sphere, sphere_function, get_sphere_normal ) return normal, distance 

## intersect_w_surface(ray, points)¶

Definition to find intersection point inbetween a surface and a ray. For more see: http://geomalgorithms.com/a06-_intersect-2.html

Parameters:

• ray
       A vector/ray.

• points
       Set of points in X,Y and Z to define a planar surface.


Returns:

• normal ( ndarray ) –

Surface normal at the point of intersection.

• distance ( float ) –

Distance in between starting point of a ray with it's intersection with a planar surface.

Source code in odak/raytracing/boundary.py
 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 def intersect_w_surface(ray, points): """ Definition to find intersection point inbetween a surface and a ray. For more see: http://geomalgorithms.com/a06-_intersect-2.html Parameters ---------- ray : ndarray A vector/ray. points : ndarray Set of points in X,Y and Z to define a planar surface. Returns ---------- normal : ndarray Surface normal at the point of intersection. distance : float Distance in between starting point of a ray with it's intersection with a planar surface. """ points = np.asarray(points) normal = get_triangle_normal(points) if len(ray.shape) == 2: ray = ray.reshape((1, 2, 3)) if len(points) == 2: points = points.reshape((1, 3, 3)) if len(normal.shape) == 2: normal = normal.reshape((1, 2, 3)) f = normal[:, 0]-ray[:, 0] distance = np.dot(normal[:, 1], f.T)/np.dot(normal[:, 1], ray[:, 1].T) n = np.int64(np.amax(np.array([ray.shape[0], normal.shape[0]]))) normal = np.zeros((n, 2, 3)) normal[:, 0] = ray[:, 0]+distance.T*ray[:, 1] distance = np.abs(distance) if normal.shape[0] == 1: normal = normal.reshape((2, 3)) distance = distance.reshape((1)) if distance.shape[0] == 1 and len(distance.shape) > 1: distance = distance.reshape((distance.shape[1])) return normal, distance 

## intersect_w_triangle(ray, triangle)¶

Definition to find intersection point of a ray with a triangle. Returns False for each variable if the ray doesn't intersect with a given triangle.

Parameters:

• ray
       A vector/ray (2 x 3). It can also be a list of rays (n x 2 x 3).

• triangle
       Set of points in X,Y and Z to define a planar surface. It can also be a list of triangles (m x 3 x 3).


Returns:

• normal ( ndarray ) –

Surface normal at the point of intersection.

• distance ( float ) –

Distance in between a starting point of a ray and the intersection point with a given triangle.

Source code in odak/raytracing/boundary.py
 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 def intersect_w_triangle(ray, triangle): """ Definition to find intersection point of a ray with a triangle. Returns False for each variable if the ray doesn't intersect with a given triangle. Parameters ---------- ray : torch.tensor A vector/ray (2 x 3). It can also be a list of rays (n x 2 x 3). triangle : torch.tensor Set of points in X,Y and Z to define a planar surface. It can also be a list of triangles (m x 3 x 3). Returns ---------- normal : ndarray Surface normal at the point of intersection. distance : float Distance in between a starting point of a ray and the intersection point with a given triangle. """ normal, distance = intersect_w_surface(ray, triangle) if is_it_on_triangle(normal[0], triangle[0], triangle[1], triangle[2]) == False: return 0, 0 return normal, distance 

## intersection_kernel_for_parametric_surfaces(distance, ray, parametric_surface, surface_function)¶

Definition for the intersection kernel when dealing with parametric surfaces.

Parameters:

• distance
             Distance.

• ray
             Ray.

• parametric_surface (ndarray) –
             Array that defines a parametric surface.

• surface_function
             Function to evaluate a point against a parametric surface.


Returns:

• point ( ndarray ) –

Location in X,Y,Z after propagation.

• error ( float ) –

Error.

Source code in odak/raytracing/boundary.py
 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 def intersection_kernel_for_parametric_surfaces(distance, ray, parametric_surface, surface_function): """ Definition for the intersection kernel when dealing with parametric surfaces. Parameters ---------- distance : float Distance. ray : ndarray Ray. parametric_surface : ndarray Array that defines a parametric surface. surface_function : ndarray Function to evaluate a point against a parametric surface. Returns ---------- point : ndarray Location in X,Y,Z after propagation. error : float Error. """ new_ray = propagate_a_ray(ray, distance) if len(new_ray) == 2: new_ray = new_ray.reshape((1, 2, 3)) point = new_ray[:, 0] error = surface_function(point, parametric_surface) return error, point 

## propagate_parametric_intersection_error(distance, error)¶

Definition to propagate the error in parametric intersection to find the next distance to try.

Parameters:

• distance
       List that contains the new and the old distance.

• error
       List that contains the new and the old error.


Returns:

• distance ( list ) –

New distance.

• error ( list ) –

New error.

Source code in odak/raytracing/boundary.py
 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 def propagate_parametric_intersection_error(distance, error): """ Definition to propagate the error in parametric intersection to find the next distance to try. Parameters ---------- distance : list List that contains the new and the old distance. error : list List that contains the new and the old error. Returns ---------- distance : list New distance. error : list New error. """ new_distance = distance[1]-error[1] * \ (distance[1]-distance[0])/(error[1]-error[0]) distance[0] = distance[1] distance[1] = np.abs(new_distance) error[0] = error[1] return distance, error 

## reflect(input_ray, normal)¶

Definition to reflect an incoming ray from a surface defined by a surface normal. Used method described in G.H. Spencer and M.V.R.K. Murty, "General Ray-Tracing Procedure", 1961.

Parameters:

• input_ray
       A vector/ray (2x3). It can also be a list of rays (nx2x3).

• normal
       A surface normal (2x3). It also be a list of normals (nx2x3).


Returns:

• output_ray ( ndarray ) –

Array that contains starting points and cosines of a reflected ray.

Source code in odak/raytracing/boundary.py
  7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 def reflect(input_ray, normal): """ Definition to reflect an incoming ray from a surface defined by a surface normal. Used method described in G.H. Spencer and M.V.R.K. Murty, "General Ray-Tracing Procedure", 1961. Parameters ---------- input_ray : ndarray A vector/ray (2x3). It can also be a list of rays (nx2x3). normal : ndarray A surface normal (2x3). It also be a list of normals (nx2x3). Returns ---------- output_ray : ndarray Array that contains starting points and cosines of a reflected ray. """ input_ray = np.asarray(input_ray) normal = np.asarray(normal) if len(input_ray.shape) == 2: input_ray = input_ray.reshape((1, 2, 3)) if len(normal.shape) == 2: normal = normal.reshape((1, 2, 3)) mu = 1 div = normal[:, 1, 0]**2 + normal[:, 1, 1]**2 + normal[:, 1, 2]**2 a = mu * (input_ray[:, 1, 0]*normal[:, 1, 0] + input_ray[:, 1, 1]*normal[:, 1, 1] + input_ray[:, 1, 2]*normal[:, 1, 2]) / div n = np.int64(np.amax(np.array([normal.shape[0], input_ray.shape[0]]))) output_ray = np.zeros((n, 2, 3)) output_ray[:, 0] = normal[:, 0] output_ray[:, 1] = input_ray[:, 1]-2*a*normal[:, 1] if output_ray.shape[0] == 1: output_ray = output_ray.reshape((2, 3)) return output_ray 

## bring_plane_to_origin(point, plane, shape=[10.0, 10.0], center=[0.0, 0.0, 0.0], angles=[0.0, 0.0, 0.0], mode='XYZ')¶

Definition to bring points back to reference origin with respect to a plane.

Parameters:

• point
             Point(s) to be tested.

• shape
             Dimensions of the rectangle along X and Y axes.

• center
             Center of the rectangle.

• angles
             Rotation angle of the rectangle.

• mode
             Rotation mode of the rectangle, for more see odak.tools.rotate_point and odak.tools.rotate_points.


Returns:

• transformed_points ( ndarray ) –

Point(s) that are brought back to reference origin with respect to given plane.

Source code in odak/raytracing/primitives.py
 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 def bring_plane_to_origin(point, plane, shape=[10., 10.], center=[0., 0., 0.], angles=[0., 0., 0.], mode='XYZ'): """ Definition to bring points back to reference origin with respect to a plane. Parameters ---------- point : ndarray Point(s) to be tested. shape : list Dimensions of the rectangle along X and Y axes. center : list Center of the rectangle. angles : list Rotation angle of the rectangle. mode : str Rotation mode of the rectangle, for more see odak.tools.rotate_point and odak.tools.rotate_points. Returns ---------- transformed_points : ndarray Point(s) that are brought back to reference origin with respect to given plane. """ if point.shape[0] == 3: point = point.reshape((1, 3)) reverse_mode = mode[::-1] angles = [-angles[0], -angles[1], -angles[2]] center = np.asarray(center).reshape((1, 3)) transformed_points = point-center transformed_points = rotate_points( transformed_points, angles=angles, mode=reverse_mode, ) if transformed_points.shape[0] == 1: transformed_points = transformed_points.reshape((3,)) return transformed_points 

## center_of_triangle(triangle)¶

Definition to calculate center of a triangle.

Parameters:

• triangle
        An array that contains three points defining a triangle (Mx3). It can also parallel process many triangles (NxMx3).

Source code in odak/raytracing/primitives.py
 73 74 75 76 77 78 79 80 81 82 83 84 85 def center_of_triangle(triangle): """ Definition to calculate center of a triangle. Parameters ---------- triangle : ndarray An array that contains three points defining a triangle (Mx3). It can also parallel process many triangles (NxMx3). """ if len(triangle.shape) == 2: triangle = triangle.reshape((1, 3, 3)) center = np.mean(triangle, axis=1) return center 

## cylinder_function(point, cylinder)¶

Definition of a cylinder function. Evaluate a point against a cylinder function. Inspired from https://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html

Parameters:

• cylinder
     Cylinder parameters, XYZ center and radius.

• point
     Point in XYZ.

Return

result : float Result of the evaluation. Zero if point is on sphere.

Source code in odak/raytracing/primitives.py
 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 def cylinder_function(point, cylinder): """ Definition of a cylinder function. Evaluate a point against a cylinder function. Inspired from https://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html Parameters ---------- cylinder : ndarray Cylinder parameters, XYZ center and radius. point : ndarray Point in XYZ. Return ---------- result : float Result of the evaluation. Zero if point is on sphere. """ point = np.asarray(point) if len(point.shape) == 1: point = point.reshape((1, 3)) distance = point_to_ray_distance( point, np.array([cylinder[0], cylinder[1], cylinder[2]], dtype=np.float64), np.array([cylinder[4], cylinder[5], cylinder[6]], dtype=np.float64) ) r = cylinder[3] result = distance - r ** 2 return result 

## define_circle(center, radius, angles)¶

Definition to describe a circle in a single variable packed form.

Parameters:

• center
  Center of a circle to be defined.

• radius
  Radius of a circle to be defined.

• angles
  Angular tilt of a circle.


Returns:

• circle ( list ) –

Single variable packed form.

Source code in odak/raytracing/primitives.py
 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 def define_circle(center, radius, angles): """ Definition to describe a circle in a single variable packed form. Parameters ---------- center : float Center of a circle to be defined. radius : float Radius of a circle to be defined. angles : float Angular tilt of a circle. Returns ---------- circle : list Single variable packed form. """ points = define_plane(center, angles=angles) circle = [ points, center, radius ] return circle 

## define_cylinder(center, radius, rotation=[0.0, 0.0, 0.0])¶

Definition to define a cylinder

Parameters:

• center
     Center of a cylinder in X,Y,Z.

• radius
     Radius of a cylinder along X axis.

• rotation
     Direction angles in degrees for the orientation of a cylinder.


Returns:

• cylinder ( ndarray ) –

Single variable packed form.

Source code in odak/raytracing/primitives.py
 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 def define_cylinder(center, radius, rotation=[0., 0., 0.]): """ Definition to define a cylinder Parameters ---------- center : ndarray Center of a cylinder in X,Y,Z. radius : float Radius of a cylinder along X axis. rotation : list Direction angles in degrees for the orientation of a cylinder. Returns ---------- cylinder : ndarray Single variable packed form. """ cylinder_ray = create_ray_from_angles( np.asarray(center), np.asarray(rotation)) cylinder = np.array( [ center[0], center[1], center[2], radius, center[0]+cylinder_ray[1, 0], center[1]+cylinder_ray[1, 1], center[2]+cylinder_ray[1, 2] ], dtype=np.float64 ) return cylinder 

## define_plane(point, angles=[0.0, 0.0, 0.0])¶

Definition to generate a rotation matrix along X axis.

Parameters:

• point
       A point that is at the center of a plane.

• angles
       Rotation angles in degrees.


Returns:

• plane ( ndarray ) –

Points defining plane.

Source code in odak/raytracing/primitives.py
  7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 def define_plane(point, angles=[0., 0., 0.]): """ Definition to generate a rotation matrix along X axis. Parameters ---------- point : ndarray A point that is at the center of a plane. angles : list Rotation angles in degrees. Returns ---------- plane : ndarray Points defining plane. """ plane = np.array([ [10., 10., 0.], [0., 10., 0.], [0., 0., 0.] ], dtype=np.float64) point = np.asarray(point) for i in range(0, plane.shape[0]): plane[i], _, _, _ = rotate_point(plane[i], angles=angles) plane[i] = plane[i]+point return plane 

## define_sphere(center, radius)¶

Definition to define a sphere.

Parameters:

• center
     Center of a sphere in X,Y,Z.

• radius
     Radius of a sphere.


Returns:

• sphere ( ndarray ) –

Single variable packed form.

Source code in odak/raytracing/primitives.py
 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 def define_sphere(center, radius): """ Definition to define a sphere. Parameters ---------- center : ndarray Center of a sphere in X,Y,Z. radius : float Radius of a sphere. Returns ---------- sphere : ndarray Single variable packed form. """ sphere = np.array( [center[0], center[1], center[2], radius], dtype=np.float64) return sphere 

## is_it_on_triangle(pointtocheck, point0, point1, point2)¶

Definition to check if a given point is inside a triangle. If the given point is inside a defined triangle, this definition returns True.

Parameters:

• pointtocheck
        Point to check.

• point0
        First point of a triangle.

• point1
        Second point of a triangle.

• point2
        Third point of a triangle.

Source code in odak/raytracing/primitives.py
  88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 def is_it_on_triangle(pointtocheck, point0, point1, point2): """ Definition to check if a given point is inside a triangle. If the given point is inside a defined triangle, this definition returns True. Parameters ---------- pointtocheck : list Point to check. point0 : list First point of a triangle. point1 : list Second point of a triangle. point2 : list Third point of a triangle. """ # point0, point1 and point2 are the corners of the triangle. pointtocheck = np.asarray(pointtocheck).reshape(3) point0 = np.asarray(point0) point1 = np.asarray(point1) point2 = np.asarray(point2) side0 = same_side(pointtocheck, point0, point1, point2) side1 = same_side(pointtocheck, point1, point0, point2) side2 = same_side(pointtocheck, point2, point0, point1) if side0 == True and side1 == True and side2 == True: return True return False 

## sphere_function(point, sphere)¶

Definition of a sphere function. Evaluate a point against a sphere function.

Parameters:

• sphere
     Sphere parameters, XYZ center and radius.

• point
     Point in XYZ.

Return

result : float Result of the evaluation. Zero if point is on sphere.

Source code in odak/raytracing/primitives.py
 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 def sphere_function(point, sphere): """ Definition of a sphere function. Evaluate a point against a sphere function. Parameters ---------- sphere : ndarray Sphere parameters, XYZ center and radius. point : ndarray Point in XYZ. Return ---------- result : float Result of the evaluation. Zero if point is on sphere. """ point = np.asarray(point) if len(point.shape) == 1: point = point.reshape((1, 3)) result = (point[:, 0]-sphere[0])**2 + (point[:, 1]-sphere[1] )**2 + (point[:, 2]-sphere[2])**2 - sphere[3]**2 return result 

## calculate_intersection_of_two_rays(ray0, ray1)¶

Definition to calculate the intersection of two rays.

Parameters:

• ray0
     A ray.

• ray1
     A ray.


Returns:

• point ( ndarray ) –

Point in X,Y,Z.

• distances ( ndarray ) –

Distances.

Source code in odak/raytracing/ray.py
 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 def calculate_intersection_of_two_rays(ray0, ray1): """ Definition to calculate the intersection of two rays. Parameters ---------- ray0 : ndarray A ray. ray1 : ndarray A ray. Returns ---------- point : ndarray Point in X,Y,Z. distances : ndarray Distances. """ A = np.array([ [float(ray0[1][0]), float(ray1[1][0])], [float(ray0[1][1]), float(ray1[1][1])], [float(ray0[1][2]), float(ray1[1][2])] ]) B = np.array([ ray0[0][0]-ray1[0][0], ray0[0][1]-ray1[0][1], ray0[0][2]-ray1[0][2] ]) distances = np.linalg.lstsq(A, B, rcond=None)[0] if np.allclose(np.dot(A, distances), B) == False: distances = np.array([0, 0]) distances = distances[np.argsort(-distances)] point = propagate_a_ray(ray0, distances[0])[0] return point, distances 

## create_ray(x0y0z0, abg)¶

Definition to create a ray.

Parameters:

• x0y0z0
       List that contains X,Y and Z start locations of a ray.

• abg
       List that contaings angles in degrees with respect to the X,Y and Z axes.


Returns:

• ray ( ndarray ) –

Array that contains starting points and cosines of a created ray.

Source code in odak/raytracing/ray.py
  5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 def create_ray(x0y0z0, abg): """ Definition to create a ray. Parameters ---------- x0y0z0 : list List that contains X,Y and Z start locations of a ray. abg : list List that contaings angles in degrees with respect to the X,Y and Z axes. Returns ---------- ray : ndarray Array that contains starting points and cosines of a created ray. """ # Due to Python 2 -> Python 3. x0, y0, z0 = x0y0z0 alpha, beta, gamma = abg # Create a vector with the given points and angles in each direction point = np.array([x0, y0, z0], dtype=np.float64) alpha = np.cos(np.radians(alpha)) beta = np.cos(np.radians(beta)) gamma = np.cos(np.radians(gamma)) # Cosines vector. cosines = np.array([alpha, beta, gamma], dtype=np.float64) ray = np.array([point, cosines], dtype=np.float64) return ray 

## create_ray_from_angles(point, angles, mode='XYZ')¶

Definition to create a ray from a point and angles.

Parameters:

• point
     Point in X,Y and Z.

• angles
     Angles with X,Y,Z axes in degrees. All zeros point Z axis.

• mode
     Rotation mode determines ordering of the rotations at each axis. There are XYZ,YXZ    ,ZXY and ZYX modes.


Returns:

• ray ( ndarray ) –

Created ray.

Source code in odak/raytracing/ray.py
  74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 def create_ray_from_angles(point, angles, mode='XYZ'): """ Definition to create a ray from a point and angles. Parameters ---------- point : ndarray Point in X,Y and Z. angles : ndarray Angles with X,Y,Z axes in degrees. All zeros point Z axis. mode : str Rotation mode determines ordering of the rotations at each axis. There are XYZ,YXZ ,ZXY and ZYX modes. Returns ---------- ray : ndarray Created ray. """ if len(point.shape) == 1: point = point.reshape((1, 3)) new_point = np.zeros(point.shape) new_point[:, 2] += 5. new_point = rotate_points(new_point, angles, mode=mode, offset=point[:, 0]) ray = create_ray_from_two_points(point, new_point) if ray.shape[0] == 1: ray = ray.reshape((2, 3)) return ray 

## create_ray_from_two_points(x0y0z0, x1y1z1)¶

Definition to create a ray from two given points. Note that both inputs must match in shape.

Parameters:

• x0y0z0
       List that contains X,Y and Z start locations of a ray (3). It can also be a list of points as well (mx3). This is the starting point.

• x1y1z1
       List that contains X,Y and Z ending locations of a ray (3). It can also be a list of points as well (mx3). This is the end point.


Returns:

• ray ( ndarray ) –

Array that contains starting points and cosines of a created ray.

Source code in odak/raytracing/ray.py
 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 def create_ray_from_two_points(x0y0z0, x1y1z1): """ Definition to create a ray from two given points. Note that both inputs must match in shape. Parameters ---------- x0y0z0 : list List that contains X,Y and Z start locations of a ray (3). It can also be a list of points as well (mx3). This is the starting point. x1y1z1 : list List that contains X,Y and Z ending locations of a ray (3). It can also be a list of points as well (mx3). This is the end point. Returns ---------- ray : ndarray Array that contains starting points and cosines of a created ray. """ x0y0z0 = np.asarray(x0y0z0, dtype=np.float64) x1y1z1 = np.asarray(x1y1z1, dtype=np.float64) if len(x0y0z0.shape) == 1: x0y0z0 = x0y0z0.reshape((1, 3)) if len(x1y1z1.shape) == 1: x1y1z1 = x1y1z1.reshape((1, 3)) xdiff = x1y1z1[:, 0] - x0y0z0[:, 0] ydiff = x1y1z1[:, 1] - x0y0z0[:, 1] zdiff = x1y1z1[:, 2] - x0y0z0[:, 2] s = np.sqrt(xdiff ** 2 + ydiff ** 2 + zdiff ** 2) s[s == 0] = np.nan cosines = np.zeros((xdiff.shape[0], 3)) cosines[:, 0] = xdiff/s cosines[:, 1] = ydiff/s cosines[:, 2] = zdiff/s ray = np.zeros((xdiff.shape[0], 2, 3), dtype=np.float64) ray[:, 0] = x0y0z0 ray[:, 1] = cosines if ray.shape[0] == 1: ray = ray.reshape((2, 3)) return ray 

## find_nearest_points(ray0, ray1)¶

Find the nearest points on given rays with respect to the other ray.

Parameters:

• ray0
     A ray.

• ray1
     A ray.


Returns:

• c0 ( ndarray ) –

Closest point on ray0.

• c1 ( ndarray ) –

Closest point on ray1.

Source code in odak/raytracing/ray.py
 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 def find_nearest_points(ray0, ray1): """ Find the nearest points on given rays with respect to the other ray. Parameters ---------- ray0 : ndarray A ray. ray1 : ndarray A ray. Returns ---------- c0 : ndarray Closest point on ray0. c1 : ndarray Closest point on ray1. """ p0 = ray0[0].reshape(3,) d0 = ray0[1].reshape(3,) p1 = ray1[0].reshape(3,) d1 = ray1[1].reshape(3,) n = np.cross(d0, d1) if np.all(n) == 0: point, distances = calculate_intersection_of_two_rays(ray0, ray1) c0 = c1 = point else: n0 = np.cross(d0, n) n1 = np.cross(d1, n) c0 = p0+(np.dot((p1-p0), n1)/np.dot(d0, n1))*d0 c1 = p1+(np.dot((p0-p1), n0)/np.dot(d1, n0))*d1 return c0, c1 

## propagate_a_ray(ray, distance)¶

Definition to propagate a ray at a certain given distance.

Parameters:

• ray
     A ray.

• distance
     Distance.


Returns:

• new_ray ( ndarray ) –

Propagated ray.

Source code in odak/raytracing/ray.py
 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 def propagate_a_ray(ray, distance): """ Definition to propagate a ray at a certain given distance. Parameters ---------- ray : ndarray A ray. distance : float Distance. Returns ---------- new_ray : ndarray Propagated ray. """ if len(ray.shape) == 2: ray = ray.reshape((1, 2, 3)) new_ray = np.copy(ray) new_ray[:, 0, 0] = distance*new_ray[:, 1, 0] + new_ray[:, 0, 0] new_ray[:, 0, 1] = distance*new_ray[:, 1, 1] + new_ray[:, 0, 1] new_ray[:, 0, 2] = distance*new_ray[:, 1, 2] + new_ray[:, 0, 2] if new_ray.shape[0] == 1: new_ray = new_ray.reshape((2, 3)) return new_ray