Source code for pydy.viz.camera

import warnings
from sympy.matrices.expressions import Identity

from ..utils import PyDyUserWarning
from .visualization_frame import VisualizationFrame

__all__ = ['PerspectiveCamera', 'OrthoGraphicCamera']

warnings.simplefilter('once', PyDyUserWarning)


[docs]class PerspectiveCamera(VisualizationFrame): """Creates a Perspective Camera for visualization. The camera is inherited from VisualizationFrame. It can be attached to dynamics objects, hence we can get a moving camera. All the transformation matrix generation methods are applicable to a Perspective Camera. Like VisualizationFrame, it can also be initialized using: 1. Rigidbody 2. ReferenceFrame, Point 3. ReferenceFrame, Particle Either one of these must be supplied during initialization. Unlike VisualizationFrame, it does not require a Shape argument. Parameters ========== name : str A name for the PerspectiveCamera(optional). Default is 'unnamed' fov : float, default=45.0 Field Of View, It determines the angle between the top and bottom of the viewable area (in degrees). near : float The distance of near plane of the PerspectiveCamera. All objects closer to this distance are not displayed. far : int or float The distance of far plane of the PerspectiveCamera. All objects farther than this distance are not displayed. """ def __init__(self, *args, **kwargs): """Initialises a PerspectiveCamera object. To initialize a visualization frame, one needs to supply a name (optional), a reference frame, a point, field of view (fov) (optional), near plane distance (optional) and far plane distance (optional). Examples ======== >>> from pydy.viz import VisualizationFrame, Shape >>> from sympy.physics.mechanics import (ReferenceFrame, Point, ... RigidBody, Particle, ... inertia) >>> from sympy import symbols >>> I = ReferenceFrame('I') >>> O = Point('O') >>> shape = Shape() >>> # initializing with reference frame, point >>> camera1 = PerspectiveCamera('frame1', I, O) >>> Ixx, Iyy, Izz, mass = symbols('Ixx Iyy Izz mass') >>> i = inertia(I, Ixx, Iyy, Izz) >>> rbody = RigidBody('rbody', O, I, mass, (inertia, O)) >>> # Initializing with a rigidbody .. >>> camera2 = PerspectiveCamera('frame2', rbody) >>> Pa = Particle('Pa', O, mass) >>> # initializing with Particle, reference_frame ... >>> camera3 = PerspectiveCamera('frame3', I, Pa) """ msg = ("Rotation of Perspective Camera does not work " "properly in the visualiser.") warnings.warn(msg, PyDyUserWarning) try: self._fov = kwargs['fov'] except KeyError: self._fov = 45.0 try: self._near = kwargs['near'] except KeyError: self._near = 1.0 try: self._far = kwargs['far'] except KeyError: self._far = 1000.0 # Now we use same approach as in VisualizationFrame for setting # reference_frame and origin i = 0 # If first arg is not str, name the visualization frame 'unnamed' if isinstance(args[i], str): self._name = args[i] i += 1 else: self._name = 'unnamed' try: self._reference_frame = args[i].get_frame() self._origin = args[i].get_masscenter() except AttributeError: # It is not a rigidbody, hence this arg should be a reference # frame try: # TODO : dcm is never used. dcm = args[i]._dcm_dict self._reference_frame = args[i] i += 1 except AttributeError: raise TypeError('A ReferenceFrame is to be supplied ' 'before a Particle/Point.') # Now next arg can either be a Particle or point try: self._origin = args[i].get_point() except AttributeError: self._origin = args[i] # basic thing required, transform matrix self._transform = Identity(4).as_mutable() def __str__(self): return 'PerspectiveCamera: ' + self._name def __repr__(self): return 'PerspectiveCamera' @property def fov(self): """ attribute for Field Of view of a PerspectiveCamera. Default value is 45 degrees """ return self._fov @fov.setter def fov(self, new_fov): if not isinstance(new_fov, (int, str)): raise TypeError('fov should be supplied in int or float') else: self._fov = new_fov @property def near(self): """ attribute for Near Plane distance of a PerspectiveCamera. Default value is 1 """ return self._near @near.setter def near(self, new_near): if not isinstance(new_near, (int, str)): raise TypeError('near should be supplied in int or float') else: self._near = new_near @property def far(self): """ Attribute for Far Plane distance of a PerspectiveCamera. The default value is ``1000.0``. """ return self._far @far.setter def far(self, new_far): if not isinstance(new_far, (int, str)): raise TypeError('far should be supplied in int or float') else: self._far = new_far
[docs] def generate_scene_dict(self): """This method generates information for a static visualization in the initial conditions, in the form of dictionary. This contains camera parameters followed by an init_orientation Key. Before calling this method, all the transformation matrix generation methods should be called, or it will give an error. Returns ======= A dict with following Keys: 1. name: name for the camera 2. fov: Field of View value of the camera 3. near: near value of the camera 4. far: far value of the camera 5. init_orientation: Initial orientation of the camera """ scene_dict = {id(self): {}} scene_dict[id(self)]['name'] = self.name scene_dict[id(self)]['type'] = self.__repr__() scene_dict[id(self)]['fov'] = self.fov scene_dict[id(self)]['near'] = self.near scene_dict[id(self)]['far'] = self.far scene_dict[id(self)]["simulation_id"] = id(self) scene_dict[id(self)]["init_orientation"] = self._visualization_matrix[0] return scene_dict
[docs] def generate_simulation_dict(self): """Generates the simulation information for this visualization frame. It maps the simulation data information to the scene information via a unique id. Before calling this method, all the transformation matrix generation methods should be called, or it will give an error. Returns ======= simulation_dict : dictionary A dictionary containing list of 4x4 matrices mapped to the unique id as the key. """ simulation_dict = {} try: simulation_dict[id(self)] = self._visualization_matrix except: raise RuntimeError("Please call the numerical " "transformation methods, " "before generating visualization dict.") return simulation_dict
[docs]class OrthoGraphicCamera(VisualizationFrame): """Creates a OrthoGraphic Camera for visualization. The camera is inherited from ``VisualizationFrame``. It can be attached to dynamics objects, hence we can get a moving camera. All the transformation matrix generation methods are applicable to a Perspective Camera. Like VisualizationFrame, it can also be initialized using: 1. :role:`Rigidbody` 2. ReferenceFrame, Point 3. ReferenceFrame, Particle Either one of these must be supplied during initialization. Unlike VisualizationFrame, it doesnt require a Shape argument. Parameters ========== name : str, optional, default='unnamed' A name for the PerspectiveCamera. near : float, optional, default= The distance of near plane of the PerspectiveCamera. All objects closer to this distance are not displayed. far : float, optional, default= The distance of far plane of the PerspectiveCamera. All objects farther than this distance are not displayed. """ def __init__(self, *args, **kwargs): """ Initialises an OrthoGraphicCamera object. To initialize a visualization frame, we need to supply a name (optional), a reference frame, a point, near plane distance (optional) and far plane distance (optional). Examples ======== >>> from pydy.viz import OrthoGraphicCamera >>> from sympy.physics.mechanics import (ReferenceFrame, Point, ... RigidBody, Particle, ... inertia) >>> from sympy import symbols >>> I = ReferenceFrame('I') >>> O = Point('O') >>> shape = Shape() >>> # Initializing with ReferenceFrame, Point >>> camera1 = OrthoGraphicCamera('frame1', I, O) >>> Ixx, Iyy, Izz, mass = symbols('Ixx Iyy Izz mass') >>> i = inertia(I, Ixx, Iyy, Izz) >>> rbody = RigidBody('rbody', O, I, mass, (inertia, O)) >>> # Initializing with a Rigidbody >>> camera2 = OrthoGraphicCamera('frame2', rbody) >>> Pa = Particle('Pa', O, mass) >>> # Initializing with Particle, ReferenceFrame >>> camera3 = OrthoGraphicCamera('frame3', I, Pa) """ try: self._near = kwargs['near'] except KeyError: self._near = 1 try: self._far = kwargs['far'] except KeyError: self._far = 1000 # Now we use same approach as in VisualizationFrame for setting # reference_frame and origin i = 0 # If first arg is not str, name the visualization frame 'unnamed' if isinstance(args[i], str): self._name = args[i] i += 1 else: self._name = 'unnamed' try: self._reference_frame = args[i].get_frame() self._origin = args[i].get_masscenter() except AttributeError: # It is not a rigidbody, hence this arg should be a reference # frame. self._reference_frame = args[i] i += 1 # Now next arg can either be a Particle or point try: self._origin = args[i].get_point() except AttributeError: self._origin = args[i] # basic thing required, transform matrix self._transform = Identity(4).as_mutable() def __str__(self): return 'OrthoGraphicCamera: ' + self._name def __repr__(self): return 'OrthoGraphicCamera' @property def near(self): """Attribute for Near Plane distance of an OrthoGraphicCamera. Default value is 1.0 """ return self._near @near.setter def near(self, new_near): if not isinstance(new_near, (int, str)): raise TypeError('near should be supplied in int or float') else: self._near = new_near @property def far(self): """Attribute for Far Plane distance of an OrthoGraphicCamera. Default value is 1000.0. """ return self._far @far.setter def far(self, new_far): if not isinstance(new_far, (int, str)): raise TypeError('far should be supplied in int or float') else: self._far = new_far
[docs] def generate_scene_dict(self): """ This method generates information for a static visualization in the initial conditions, in the form of dictionary. This contains camera parameters followed by an init_orientation Key. Returns ======= scene_dict : dictionary A dict with following Keys: 1. name: name for the camera 2. near: near value of the camera 3. far: far value of the camera 4. init_orientation: Initial orientation of the camera """ scene_dict = {id(self): {}} scene_dict[id(self)]['name'] = self.name scene_dict[id(self)]['type'] = self.__repr__() scene_dict[id(self)]['near'] = self.near scene_dict[id(self)]['far'] = self.far scene_dict[id(self)]["simulation_id"] = id(self) scene_dict[id(self)]["init_orientation"] = self._visualization_matrix[0] return scene_dict
[docs] def generate_simulation_dict(self): """Generates the simulation information for this visualization frame. It maps the simulation data information to the scene information via a unique id. Returns ======= A dictionary containing list of 4x4 matrices mapped to the unique id as the key. """ simulation_dict = {} try: simulation_dict[id(self)] = self._visualization_matrix except: raise RuntimeError("Please call the numerical ", "transformation methods, ", "before generating visualization dict") return simulation_dict