Example #1
0
def reflection_normal(outgoing_ray, incoming_ray):
  """Returns the normal vector between incoming and outgoing
  reflection rays.

  """
  ray1 = normalize(-incoming_ray)
  ray2 = normalize(outgoing_ray)
  return normalize((ray1 + ray2)/2)
Example #2
0
def refract(ray, normal, origin_index, final_index):
  """Returns the normalized direction of a given ray (normalized or not) after
  refraction through a boundary between two media with given normal vector and
  indexes of refraction

  """
  rho = final_index / origin_index
  ray_direction = normalize(ray)
  normal = normalize(normal)
  if normal.dot(ray_direction) > 0:
    normal = -normal
  incidence = dot(-ray_direction, normal)
  complement = (1.0 - (1.0 - incidence**2) / rho**2)**(0.5)
  return (ray_direction / rho) + ((incidence / rho - complement) * normal)
Example #3
0
def reconstruct_mirror_normal(
    outgoing_ray, incoming_ray, surface_normal, inside_index, outside_index):
  """Reconstructs the mirror normal vector given the incoming ray
  vector, outgoing ray vector, front face normal vector and the indexes of
  refraction.

  """
  outgoing_ray = normalize(outgoing_ray)
  incoming_ray = normalize(incoming_ray)
  surface_normal = normalize(surface_normal)
  inner_downstream = -refract(
      -outgoing_ray, surface_normal, outside_index, inside_index)
  inner_upstream = refract(
      incoming_ray, surface_normal, outside_index, inside_index)
  return reflection_normal(inner_downstream, inner_upstream)
Example #4
0
 def normal(self, point):
   """Return the normal at the point on the surface."""
   point = self._center - np.array(point)
   # if abs(point.dot(point) - self._radius**2) > 1e-15:
   #   raise RayTraceError(
   #       'Cannot compute normal. Point is too far from surface ({}).'.format(
   #       (abs(point.dot(point) - self._radius**2))))
   return normalize(point / self._radius)
Example #5
0
def _radius_parameters(normal_1, normal_2, input_1, impact_1, impact_2):
  """Return a tuple (separation, radius).

  The beam separation is reported in the normal sector plane. The radius
  reported is that of the sphere connecting the given normal vectors normal_1
  and normal_2 at the beam impact position vectors impact_1 and impact_2
  for the direction input_1 of the beam at normal_1.
  """
  alpha = abs(sys_math.acos(normal_1.dot(normal_2)))
  plane = normalize(Vector(np.cross(normal_1, normal_2)))
  input_in_plane = normalize(input_1 - (input_1.dot(plane) * plane))
  theta = abs(sys_math.acos(normal_1.dot(input_in_plane)))
  separation = impact_1 - impact_2
  #separation = np.append(separation, 0)
  separation -= separation.dot(plane) * plane
  separation = Vector(separation)
  separation = (abs(separation)).value

  return (separation, alpha, theta)
Example #6
0
 def __init__(self, initial_direction, initial_position,
     initial_element=None, jitter=None):
   """Create a beam along the initial direction and position given. Optionally,
   jitter can be added to the beam by passing the standard deviation of the
   polar direction in radians."""
   if jitter is not None:
     initial_direction = normalize(initial_direction)
     initial_direction += np.linalg.inv(
         rotation_matrix_arrays(initial_direction)).dot(array(
             [np.random.normal(0, jitter), np.random.normal(0, jitter), 0]))
   self._ray = Ray(initial_direction, initial_position)
   self._history = [(0, self._ray)]
   self._element = Air() if initial_element is None else initial_element
Example #7
0
 def __init__(self, direction, position):
   """Construct a Ray from a direction and a position from the origin.
   The direction will be forced normal."""
   self.direction = normalize(direction)
   self.position = np.array(position)
Example #8
0
 def __init__(self, normal, position, name=None, reflective=False):
   """Construct a plane from a normal vector and the
   position to a point on the plane."""
   _Surface.__init__(self, name, reflective)
   self._normal = normalize(normal)
   self._position = np.array(position)