def refract(self, ray): """ Calculates the new direction of the ray incident to the refracting surface using Snell's law in vector form. """ n = self._n0 / self._n1 intercept = self.intersect(ray) if intercept is None: return None k1_ray = ray.k() normal = nk.normalise((intercept - self._O) * (np.sign(k1_ray[2]) * np.sign(self._curv))) c = np.dot(-normal, k1_ray) sin_t1_sq = 1 - c*c if sin_t1_sq > 1./(n*n): return None k2_ray = nk.normalise(n*k1_ray + (n*c - np.sqrt(1-n*n*(1-c*c)))*normal) return k2_ray
def reflect(self, ray): """ Calculates the reflected direction of the ray incident to the surface. """ intercept = self.intersect(ray) if intercept is None: return None k1_ray = ray.k() normal = nk.normalise((intercept - self._O) * (np.sign(k1_ray[2]) * np.sign(self._curv))) cos_t = - np.dot(normal, k1_ray) k2_ray = k1_ray + 2*cos_t*normal return k2_ray
def append(self, r, k): """ Appends new point and direction to the ray usually after interaction with optical element. r, k can be numpy arrays or lists of floats and/or integers. Appended points and directions are numpy arrays of floats. Directions are normalised. """ if len(r) != 3 or len(k) != 3: raise Exception('3D vector size') r = np.array(r, dtype=float) k = nk.normalise(np.array(k, dtype=float)) self._vertices.append(r) self._directions.append(k)
def __init__(self, r=[0, 0, 0], k=[0, 0, 1], wavelength = 0): """ Instantiates an optical ray at a starting position r with initial (normalised) direction k. Coordinates are in the x,y,z Cartesian form. r and k can be numpy arrays or lists of integers and/or floats. wavelength is a float (measured in nanometres). """ if len(r) != 3 or len(k) != 3: raise Exception('3D vector size') self._r = np.array(r, dtype=float) self._k = nk.normalise(np.array(k, dtype=float)) if wavelength == 0: self._wavelength = None self._wavelength = float(wavelength) # __vertices and __directions are lists of all segment endpoints and # directions of the ray. They are useful for plotting but not useful # for the user. self._vertices = [self._r] self._directions = [self._k]