Source code for sisl.shape.base

import numpy as np

__all__ = ['Shape']


[docs]class Shape(object): """ Baseclass for shapes This class should always be sub-classed. There are a few routines that are *always* necessary to implement in a inherited class: `center` return the geometric center of the shape origo return the lowest left point in the shape volume return the volume of the shape. displacement return a vector that is the largest displacement vector such that a grid of the Shape will fully contian all space within Enables to check if coordinates, or other things are contained in this shape iwithin Returns only the indices of elements that are within enlarge Creates a new shape with a only the indices of elements that are within A `Shape` allows interaction with outside elements to check if geometric points are within the shapes. For instance to assert that a given point `x`, `y`, `z` is within a sphere of radius `r` with center `cx`, `cy`, `cz` on may do: This makes it very efficient to enable arbitrary shapes to be passed and used as determinations of regions of space. """ def __init__(self, center): """ Initialize the Shape with a center """ if center is None: self._center = np.zeros(3, np.float64) else: self._center = np.array(center, np.float64) def __call__(self, *args, **kwargs): """ Re-initialize the Shape """ return self.__class__(*args, **kwargs) @property def origo(self): """ The geometric origo of the shape An origo should *always* be the lowest left coordinate of the shape. Notes ----- Not all shapes have an origo. For instance a sphere only have a center, but an origo cannot be defined. """ return None @property def center(self): """ The geometric center of the shape """ return self._center @property def displacement(self): """ Return a displacement vector for full containment """ raise NotImplementedError('displacement has not been implemented in: '+self.__class__.__name__) @property def volume(self): raise NotImplementedError('volume has not been implemented in: '+self.__class__.__name__)
[docs] def enlarge(self, length): """ Return a new Shape with an increased size length """ raise NotImplementedError('enlarge has not been implemented in: '+self.__class__.__name__)
[docs] def within(self, other): """ Returns `True` if `other` is fully within `self` """ raise NotImplementedError('__contains__ has not been implemented in: '+self.__class__.__name__)
[docs] def iwithin(self, other): """ Returns indices of the elements of `other` that are within the shape """ return self.within(other).nonzero()[0]
def __contains__(self, other): return self.within(other) def __repr__(self): return self.__class__.__name__ + ' c({} {} {})'.format(*self.center)