Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
def linearpolarizer(field, rotation=0):
    """
    Definition that represents a linear polarizer.

    Parameters
    ----------
    field        : ndarray
                   Polarization vector of an input beam.
    rotation     : float
                   Represents rotation of the polarizer along propagation direction in angles (couter-clockwise).

    Returns
    ----------
    result       : ndarray
                   Polarization vector of an output beam.
    """
    rotation = np.radians(rotation)
    rotmat = np.array([[float(np.cos(rotation)),
                        float(np.sin(rotation))],
                       [float(-np.sin(rotation)),
                        float(np.cos(rotation))]])
    linearpolarizer = np.array([[1, 0], [0, 0]])
    linearpolarizer = np.dot(rotmat.transpose(),
                             np.dot(linearpolarizer, rotmat))
    result = np.dot(linearpolarizer, field)
    return result
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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)[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
Ejemplo n.º 6
0
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.int(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
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
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