예제 #1
0
    def add_ray_path(self, rays: [Ray]) -> str:
        """ Add the ray path as a single connected line and return an identifier. 
        
            Parameters
            ----------
            rays : list of Ray
                List of ray objects.
            length : float
                The length of the line to render. Default to 1000.

            See also
            --------
            add_path : Draws the line in more efficient way than `add_ray_path` but
                limits the line to be a single colour.

            Returns
            -------
            identifier : str
                The string identifier used to add the line to the scene.
        """
        vis = self.vis
        if len(rays) < 2:
            raise AppError("Need at least two points to render a line.")
        ids = []
        for (start_ray, end_ray) in zip(rays[:-1], rays[1:]):
            nanometers = start_ray.wavelength
            start = start_ray.position
            end = end_ray.position
            colour = wavelength_to_hex_int(nanometers)
            ids.append(self.add_line_segment(start, end, colour=colour))
        return ids
예제 #2
0
    def add_ray_path(self, rays: [Ray]) -> str:
        """ Add the ray path as a single connected line and return an identifier. 
        
            Parameters
            ----------
            rays : list of Ray
                List of ray objects.
            length : float
                The length of the line to render. Default to 1000.

            See also
            --------
            add_path : Draws the line in more efficient way than `add_ray_path` but
                limits the line to be a single colour.

            Returns
            -------
            identifier : str
                The string identifier used to add the line to the scene.
        """
        vis = self.vis
        if len(rays) < 2:
            raise AppError("Need at least two points to render a line.")
        for (start_ray, end_ray) in zip(rays[:-1], rays[1:]):
            nanometers = start_ray.wavelength
            start = start_ray.position
            end = end_ray.position
            colour = wavelength_to_hex_int(nanometers)
            self.add_line_segment(start, end, colour=colour)
예제 #3
0
    def add_ray(self, ray: Ray, length: float) -> str:
        """ Add the ray path as a single connected line and return an identifier. 
        
            Parameters
            ----------
            ray : Ray
                The ray to add to the scene.

            Notes
            -----
            Internally the line is drawn using `add_line_segment` because the colour of
            each segment could be unique. If this proves too inefficiency use 
            `add_path`.

            See also
            --------
            add_ray_path : Adds multiple rays to the scene.

            Returns
            -------
            identifier : str
                The string identifier used to add the object to the scene.
        """
        nanometers = ray.wavelength
        start = ray.position
        end = np.array(start) + np.array(ray.direction) * length
        colour = wavelength_to_hex_int(nanometers)
        identifier = self.add_line_segment(start, end, colour=colour)
        return identifier
예제 #4
0
    def add_ray(self, ray : Ray, length: float) -> str:
        """ Add the ray path as a single connected line and return an identifier. 
        
            Parameters
            ----------
            ray : Ray
                The ray to add to the scene.

            Notes
            -----
            Internally the line is drawn using `add_line_segment` because the colour of
            each segment could be unique. If this proves too inefficiency use 
            `add_path`.

            See also
            --------
            add_ray_path : Adds multiple rays to the scene.

            Returns
            -------
            identifier : str
                The string identifier used to add the object to the scene.
        """
        nanometers = ray.wavelength
        start = ray.position
        end = np.array(start) + np.array(ray.direction) * length
        colour = wavelength_to_hex_int(nanometers)
        identifier = self.add_line_segment(start, end, colour=colour)
        return identifier
예제 #5
0
    def add_history(
        self,
        history: Tuple,
        baubles: bool = True,
        world_segment: str = "short",
        short_length: float = 1.0,
        bauble_radius: float = 0.01,
    ):
        """ Similar to `add_ray_path` but with improved visualisation options.
    
            Parameters
            ----------
            history: tuple
                Tuple of rays and events as returned from `photon_tracer.follow`
            baubles: bool (optional)
                Default is True. Draws baubles at exit location.
            world_segment: str (optional)
                Opt-out (`'exclude'`) or draw short (`'short`) path segments to the
                world node.
            short_length: float
                The length of the final path segment when `world_segment='short'`.
            bauble_radius: float
                The bauble radius when `baubles=True`.
        """
        vis = self.vis
        if not world_segment in {"exclude", "short"}:
            raise ValueError(
                "`world_segment` should be either `'exclude'` or `'short'`.")

        if world_segment == "exclude":
            rays, events = zip(*history)
            try:
                idx = events.index(Event.EXIT)
                history = history[0:idx]
                if len(history) < 2:
                    # nothing left to render
                    return
            except ValueError:
                pass

        if len(history) < 2:
            raise AppError("Need at least two points to render a line.")

        ids = []
        rays, events = zip(*history)
        for (start_part, end_part) in zip(history[:-1], history[1:]):
            start_ray, end_ray = start_part[0], end_part[0]
            nanometers = start_ray.wavelength
            start = start_ray.position
            end = end_ray.position
            if world_segment == "short":
                if end_ray == history[-1][0]:
                    end = (np.array(start_ray.position) +
                           np.array(start_ray.direction) * short_length)
            colour = wavelength_to_hex_int(nanometers)
            ids.append(self.add_line_segment(start, end, colour=colour))

            if baubles:
                event = start_part[1]
                if event in {Event.TRANSMIT}:
                    baubid = self.get_next_identifer()
                    vis[f"exit/{baubid}"].set_object(
                        g.Sphere(bauble_radius),
                        g.MeshBasicMaterial(color=colour,
                                            transparency=False,
                                            opacity=1),
                    )
                    vis[f"exit/{baubid}"].set_transform(
                        tf.translation_matrix(start))

                    ids.append(baubid)
        return ids