def probability(self, ray: Ray) -> float: """ Returns the probability that the interaction will occur. """ context = self.context normal = np.array(context.normal) n1 = context.n1 n2 = context.n2 # Be flexible with how the normal is defined ray_ = ray.representation(context.normal_node.root, context.normal_node) if np.dot(normal, ray_.direction) < 0.0: normal = flip(normal) angle = angle_between(normal, np.array(ray_.direction)) logger.debug("Incident angle {:.2f}".format(np.degrees(angle))) if angle < 0.0 or angle > 0.5 * np.pi: raise ValueError("The incident angle must be between 0 and pi/2.") # Catch TIR case if n2 < n1 and angle > np.arcsin(n2/n1): return 1.0 c = np.cos(angle) s = np.sin(angle) k = np.sqrt(1 - (n1/n2 * s)**2) Rs1 = n1 * c - n2 * k Rs2 = n1 * c + n2 * k Rs = (Rs1/Rs2)**2 Rp1 = n1 * k - n2 * c Rp2 = n1 * k + n2 * c Rp = (Rp1/Rp2)**2 return 0.5 * (Rs + Rp)
def transform(self, ray: Ray) -> Ray: """ Transform ray according to the physics of the interaction. """ context = self.context normal = np.array(context.normal) ray_ = ray.representation(context.normal_node.root, context.normal_node) vec = np.array(ray_.direction) d = np.dot(normal, vec) reflected_direction = vec - 2 * d * normal new_ray_ = replace(ray_, direction=tuple(reflected_direction.tolist())) new_ray = new_ray_.representation(context.normal_node, context.normal_node.root) return new_ray # back to world node
def transform(self, ray: Ray) -> Ray: """ Transform ray according to the physics of the interaction. """ context = self.context n1 = context.n1 n2 = context.n2 ray_ = ray.representation(context.normal_node.root, context.normal_node) normal = np.array(context.normal) vector = np.array(ray_.direction) n = n1/n2 dot = np.dot(vector, normal) c = np.sqrt(1 - n**2 * (1 - dot**2)) sign = 1 if dot < 0.0: sign = -1 refracted_direction = n * vector + sign*(c - sign*n*dot) * normal new_ray_ = replace(ray_, direction=tuple(refracted_direction.tolist())) new_ray = new_ray_.representation(context.normal_node, context.normal_node.root) return new_ray