示例#1
0
    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)
示例#2
0
 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
示例#3
0
 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