Source code for blueprints.tube

import numpy as np
import blueprints as blue



[docs] class BaseTube(blue.TubeType): """ BaseTube is a base class for sites and geoms that can be defined by two points forming a tube like object. """
[docs] @blue.restrict @classmethod def from_points(cls, head: np.ndarray|list[int|float], tail: np.ndarray|list[int|float], radius: int|float = 1, **kwargs) -> blue.TubeType: """ Constructs a Tube like object from point head to point tail. Euler angles are set such that the resulting orientation has pitch and yaw but no roll. Therefore the floors horizon is always parallel to the orientation. Args: head (np.ndarray | list[int | float]): Description tail (np.ndarray | list[int | float]): Description radius (int | float, optional): Description **kwargs: Description Returns: blue.Thing: Description """ head = np.array(head) tail = np.array(tail) path = tail - head pos = (head + tail)/2 length = np.linalg.norm(path) # RECONSTRUCT REFERENCE FRAME R_z = path/length R_z1, R_z2, R_z3 = R_z if R_z1 == R_z2 == 0: alpha = 0 if R_z3 > 0 else blue.geometry.PI beta = 0 gamma = 0 else: R_x = blue.geometry.Vector.normalize(np.array([R_z2, -R_z1, 0])) R_y = np.cross(R_z, R_x) R = np.stack([R_x, R_y, R_z], axis=1) # RECONSTRUCT ANGLES alpha, beta, gamma = blue.geometry.Rotation.reference_frame_to_euler(R) kwargs['pos'] = pos kwargs['alpha'] = alpha kwargs['beta'] = beta kwargs['gamma'] = gamma if issubclass(cls, (blue.BoxGeomType, blue.BoxSiteType)): kwargs['x_length'] = radius kwargs['y_length'] = radius kwargs['z_length'] = length else: kwargs['length'] = length kwargs['radius'] = radius return cls(**kwargs)
@property def head(self) -> np.ndarray: """ Returns the head position of the tube like object. The positions are derived even if the object was not constructed with the from points method. Returns: np.ndarray: The head position. """ R = self.rotation_matrix length = self.z_length if isinstance(self, (blue.BoxGeomType, blue.BoxSiteType)) else self.length Z = blue.geometry.Rotation.Z * length / 2 return self.pos - R @ Z @property def tail(self) -> np.ndarray: """ Returns the tail position of the tube like object. The positions are derived even if the object was not constructed with the from points method. Returns: np.ndarray: The tail position. """ R = self.rotation_matrix length = self.z_length if isinstance(self, (blue.BoxGeomType, blue.BoxSiteType)) else self.length Z = blue.geometry.Rotation.Z * length / 2 return self.pos + R @ Z @head.setter @blue.restrict def head(self, head: np.ndarray|list[int|float]) -> None: """ Setter for the head parameter. The position and orientation of the object is adjusted accordingly. Args: head (np.ndarray | list[int | float]): Description Returns: blue.Thing: The new Geom or Site with the adjusted position and orientation. """ tube = self.from_points(head, self.tail, **self._blueprint_specs()) self.pos = tube.pos self.euler = tube.euler self.length = tube.length @tail.setter @blue.restrict def tail(self, tail: np.ndarray|list[int|float]) -> None: """ Setter for the tail parameter. The position and orientation of the object is adjusted accordingly. Args: tail (np.ndarray | list[int | float]): Description Returns: blue.Thing: The new Geom or Site with the adjusted position and orientation. """ tube = self.from_points(self.head, tail, **self._blueprint_specs()) self.pos = tube.pos self.euler = tube.euler self.length = tube.length