Skip to content

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