Shapes Module#
Overview
Define shape classes.
This subpackage is the core of coxeter and defines various shapes in two and three dimensions. Shapes support standard calculations like volume and area, and they take care of various conveniences such as orienting polyhedron faces and automatically identifying convex hulls of points.
Classes:
|
A circle with the given radius. |
|
A convex polygon. |
|
A convex polyhedron. |
|
A convex spheropolygon. |
|
A convex spheropolyhedron. |
|
An ellipse with principal axes a and b. |
|
An ellipsoid with principal axes a, b, and c. |
|
A simple (non-self-overlapping) polygon. |
|
A three-dimensional polytope. |
|
An abstract representation of a shape in N dimensions. |
|
An abstract representation of a shape in 2 dimensions. |
|
An abstract representation of a shape in 3 dimensions. |
|
A sphere with the given radius. |
- class coxeter.shapes.Circle(radius, center=(0, 0, 0))#
Bases:
Shape2D
A circle with the given radius.
- Parameters:
Example
>>> circle = coxeter.shapes.circle.Circle(radius=1.0, center=(1, 1, 1)) >>> import numpy as np >>> assert np.isclose(circle.area, np.pi) >>> circle.centroid array([1, 1, 1]) >>> assert np.isclose(circle.circumference, 2 * np.pi) >>> circle.eccentricity 0 >>> circle.gsd_shape_spec {'type': 'Sphere', 'diameter': 2.0} >>> circle.iq 1 >>> assert np.isclose(circle.perimeter, 2 * np.pi) >>> assert np.allclose( ... circle.planar_moments_inertia, ... (5. / 4. * np.pi, 5. / 4. * np.pi, np.pi)) >>> assert np.isclose(circle.polar_moment_inertia, 5. / 2. * np.pi) >>> circle.radius 1.0
Attributes:
Get the area of the circle.
Alias for
centroid
.Get or set the centroid of the shape.
Get the circumference, alias for
Circle.perimeter
.Get the eccentricity of the circle.
Get a complete GSD specification.
Get the inertia tensor.
The isoperimetric quotient.
Get the largest bounded circle.
Get or set the radius of the maximal bounded circle.
Get the largest bounded circle.
Get the largest bounded concentric circle.
Get or set the radius of the maximal centered bounded circle.
Get the smallest bounding circle.
Get or set the radius of the minimal bounding circle.
Get the smallest bounding concentric circle.
Get or set the radius of the minimal centered bounding circle.
Get the perimeter of the circle.
Get the planar and product moments of inertia.
Get the polar moment of inertia.
Get the radius of the circle.
Methods:
Calculate the form factor intensity.
distance_to_surface
(angles)Compute the distance to the surface of the shape at the given angles.
is_inside
(points)Determine whether a set of points are contained in this circle.
plot
()Plot the shape.
to_json
(attributes)Get a JSON-serializable subset of shape properties.
to_plato_scene
([backend, scene, scene_kwargs])Add this shape to a new or existing
plato.draw.Scene
.- property center#
Alias for
centroid
.- Type:
\((3, )\)
numpy.ndarray
of float
- property centroid#
Get or set the centroid of the shape.
- Type:
\((3, )\)
numpy.ndarray
of float
- property circumference#
Get the circumference, alias for
Circle.perimeter
.- Type:
- compute_form_factor_amplitude(q)#
Calculate the form factor intensity.
In solid state physics, scattering theory is concerned with understanding the ways in which radiation is scattered from a sample. For a single point particle at position P, the the amplitude of a scattered wave observed at position Q is the product of the incoming wave amplitude (which follows the standard equation for a traveling wave) and the scattering density at P. For a crystal composed of many point particles, the intensity of the resulting superposition of waves can be identified as the Fourier transform of the total scattering density. When the particles are not point particles, the scattering density of the particles in their local coordinate systems are no longer identical. Conveniently, this component is separable in the Fourier transform of the total density; as a result, the scattering scattering intensity can be decomposed into two terms, the Fourier transform of the distribution of scatterers and the Fourier transform of each scatterer in its local coordinate system. The first term is known as the static structure factor \(S(\vec{q})\) and describes the spatial distribution of scatterers, while the second term is called the form factor \(f(\vec{q})\) and describes the local scattering profile.
While the form factor (the scattering intensity) can be measured from diffraction experiments, the Fourier transform of a single particle cannot. However, it can be computed theoretically for a known scattering volume and can be inserted directly into the expression for the total scattering intensity. This local profile directly describes the wave emitted from a single scatterer (in reciprocal space) and is known as the form factor amplitude. This function computes the form factor amplitude for a given wavevector \(q\).
- distance_to_surface(angles)#
Compute the distance to the surface of the shape at the given angles.
Gets the distance to the surface at each of the angles provided, where the definition of the angles depends on the dimensionality of the shape (a single angle in 2D, or the phi/theta angles in 3D). All angles are relative to the x axis. In general, the distance is computed from the centroid of the shape unless stated otherwise.
- Parameters:
angles (\((N, d-1)\)
numpy.ndarray
) – Angles between \(0\) and \(2 \pi\) over which to calculate the distances. \(d\) is the number of dimensions.- Returns:
An array of distances from the center of the shape to its surface at each of the given angles.
- Return type:
\((N,)\)
numpy.ndarray
- property eccentricity#
Get the eccentricity of the circle.
This is 0 by definition for circles.
- Type:
- property gsd_shape_spec#
Get a complete GSD specification.
- Type:
- property inertia_tensor#
Get the inertia tensor.
For non-orientable 2D shapes, the inertia tensor can be trivially constructed from the polar moment of inertia. This calculation assumes that the shape lies in the \(xy\)-plane. Shapes that can be rotated relative to this plane must define their own methods.
- Type:
\((3, 3)\)
numpy.ndarray
- is_inside(points)#
Determine whether a set of points are contained in this circle.
Note
Points on the boundary of the shape will return
True
.- Parameters:
points (\((N, 3)\)
numpy.ndarray
) – The points to test.- Returns:
Boolean array indicating which points are contained in the circle.
- Return type:
\((N, )\)
numpy.ndarray
Example
>>> circle = coxeter.shapes.Circle(1.0) >>> circle.is_inside([[0, 0, 0], [20, 20, 20]]) array([ True, False])
- property maximal_bounded_circle#
Get the largest bounded circle.
The largest circle contained in a shape is referred to by a range of ambiguous names. To avoid conflicts with the most common naming choices of other properties in the literature (particularly the
incircle
of a polygon), this property is named as an explicit analog tominimal_bounding_circle
.- Type:
- property maximal_bounded_circle_radius#
Get or set the radius of the maximal bounded circle.
See
maximal_bounded_circle()
for more information.- Type:
- property maximal_centered_bounded_circle_radius#
Get or set the radius of the maximal centered bounded circle.
See
maximal_centered_bounded_circle()
for more information.- Type:
- property minimal_bounding_circle_radius#
Get or set the radius of the minimal bounding circle.
See
minimal_bounding_circle()
for more information.- Type:
- property minimal_centered_bounding_circle#
Get the smallest bounding concentric circle.
- Type:
- property minimal_centered_bounding_circle_radius#
Get or set the radius of the minimal centered bounding circle.
See
minimal_centered_bounding_circle()
for more information.- Type:
- property planar_moments_inertia#
Get the planar and product moments of inertia.
Moments are computed with respect to the \(x\) and \(y\) axes. In addition to the two planar moments, this property also provides the product of inertia.
The planar moments and the product of inertia are defined by the formulas:
\[\begin{split}\begin{align} I_x &= {\int \int}_A y^2 dA = \frac{\pi}{4} r^4 = \frac{Ar^2}{4} \\ I_y &= {\int \int}_A x^2 dA = \frac{\pi}{4} r^4 = \frac{Ar^2}{4} \\ I_{xy} &= {\int \int}_A xy dA = 0 \\ \end{align}\end{split}\]These formulas are given here. Note that the product moment is zero by symmetry.
- plot()#
Plot the shape.
- property polar_moment_inertia#
Get the polar moment of inertia.
The polar moment of inertia is always calculated about an axis perpendicular to the shape (i.e. the normal vector).
The polar moment is computed as the sum of the two planar moments of inertia.
- Type:
- to_plato_scene(backend='matplotlib', scene=None, scene_kwargs=None)#
Add this shape to a new or existing
plato.draw.Scene
.The plato visualization package provides support for several backends, including matplotlib, fresnel, povray, pythreejs, and vispy. The backend package must be separately installed by the user. Each backend supports different primitives (geometry objects) and may not support the primitive corresponding to a specific shape class in coxeter. Please refer to the plato documentation for more information about supported primitives for each backend.
- Parameters:
backend (str) – Name of backend to use from plato. The backend must support the primitive corresponding to this shape (Default value:
"matplotlib"
). Supported values include"matplotlib"
,"fresnel"
,"povray"
,"pythreejs"
,"vispy"
, and"zdog"
. See plato documentation for more information about each backend.scene (
plato.draw.Scene
) – Scene object to render into. If not provided or None, a new scene is created (Default value: None).scene_kwargs (dict) – Keyword arguments forwarded to the
plato.draw.Scene
(Default value: None). Only used ifscene
is not provided or None.
- Returns:
A scene containing this shape.
- Return type:
- Raises:
NotImplementedError: – If no plato primitive corresponds to this coxeter shape class.
AttributeError: – If the selected plato backend does not support the primitive for this coxeter shape class.
- class coxeter.shapes.ConvexPolygon(vertices, normal=None, planar_tolerance=1e-05)#
Bases:
Polygon
A convex polygon.
The polygon is embedded in 3-dimensions, so the normal vector determines which way is “up”.
- Parameters:
vertices (\((N, 3)\) or \((N, 2)\)
numpy.ndarray
) – The vertices of the polygon. They need not be sorted since the order will be determined by the hull.normal (sequence of length 3 or None) – The normal vector to the polygon. If
None
, the normal is computed by taking the cross product of the vectors formed by the first three verticesnp.cross(vertices[2, :] - vertices[1, :], vertices[0, :] - vertices[1, :])
. This choice is made so that if the provided vertices are in the \(xy\) plane and are specified in counterclockwise order, the resulting normal is the \(z\) axis. Since this arbitrary choice may not preserve the orientation of the provided vertices, users may provide a normal instead (Default value: None).planar_tolerance (float) – The tolerance to use to verify that the vertices are planar. Providing this argument may be necessary if you have a large number of vertices and are rotated significantly out of the plane.
Example
>>> square = coxeter.shapes.ConvexPolygon( ... [[1, 1], [-1, -1], [1, -1], [-1, 1]]) >>> import numpy as np >>> assert np.isclose(square.area, 4.0) >>> assert np.isclose( ... square.minimal_bounding_circle.radius, ... np.sqrt(2.)) >>> square.center array([0., 0., 0.]) >>> assert np.isclose( ... square.circumcircle.radius, ... np.sqrt(2.)) >>> square.gsd_shape_spec {'type': 'Polygon', 'vertices': [[1.0, 1.0, 0.0], [-1.0, 1.0, 0.0], [-1.0, -1.0, 0.0], [1.0, -1.0, 0.0]]} >>> assert np.isclose(square.maximal_centered_bounded_circle.radius, 1.0) >>> assert np.allclose( ... square.inertia_tensor, ... [[0., 0., 0.], ... [0., 0., 0.], ... [0., 0., 8. / 3.]]) >>> square.normal array([0., 0., 1.]) >>> assert np.allclose( ... square.planar_moments_inertia, ... (4. / 3., 4. / 3., 0.)) >>> assert np.isclose(square.polar_moment_inertia, 8. / 3.) >>> assert np.isclose(square.signed_area, 4.0) >>> square.vertices array([[ 1., 1., 0.], [-1., 1., 0.], [-1., -1., 0.], [ 1., -1., 0.]])
Attributes:
Get or set the polygon's area.
Get the minimal bounding circle.
Alias for
centroid
.Get or set the centroid of the shape.
Get the polygon's circumcircle.
Get the radius of the polygon's circumcircle.
Get a complete GSD specification.
Get the polygon's incircle.
Get the largest concentric inscribed circle.
Get the radius of the polygon's incircle.
Get the inertia tensor.
The isoperimetric quotient.
Get the largest bounded circle.
Get or set the radius of the maximal bounded circle.
Get the largest bounded concentric circle.
Get or set the radius of the maximal centered bounded circle.
Get the minimal bounding circle.
Get or set the radius of the minimal bounding circle.
Get the smallest bounding concentric circle.
Get or set the radius of the minimal centered bounding circle.
Get the normal vector.
Get the number of vertices.
Get the perimeter of the polygon.
Get the planar and product moments of inertia.
Get the polar moment of inertia.
Get the polygon's area.
Get the vertices of the polygon.
Methods:
compute_form_factor_amplitude
(q[, density])Calculate the form factor intensity.
distance_to_surface
(angles)Compute the distance to the surface of the shape at the given angles.
is_inside
(points)Implement a simple point-in-polygon algorithm based on winding number.
plot
([ax, center, plot_verts, label_verts])Plot the polygon.
to_hoomd
()Get a JSON-serializable subset of Polygon properties.
to_json
(attributes)Get a JSON-serializable subset of shape properties.
to_plato_scene
([backend, scene, scene_kwargs])Add this shape to a new or existing
plato.draw.Scene
.- property area#
Get or set the polygon’s area.
To get the area, we simply compute the signed area and take the absolute value.
- Type:
- property center#
Alias for
centroid
.- Type:
\((3, )\)
numpy.ndarray
of float
- property centroid#
Get or set the centroid of the shape.
The centroid of a polygon is calculated according to this formula.
- Type:
\((3, )\)
numpy.ndarray
of float
- property circumcircle#
Get the polygon’s circumcircle.
A circumcircle must touch all the points of the polygon. A circumcircle exists if and only if there is a point equidistant from all the vertices. The circumcircle is found by finding the least squares solution of the overdetermined system of linear equations defined by this constraint, and the circumcircle only exists if the resulting solution has no residual.
- Raises:
RuntimeError – If no circumcircle exists for this polygon.:
- Type:
- compute_form_factor_amplitude(q, density=1.0)#
Calculate the form factor intensity.
The form factor amplitude of a polygon is computed according to the derivation provided in this dissertation: https://deepblue.lib.umich.edu/handle/2027.42/120906. The Kelvin-Stokes theorem allows reducing the surface integral to a line integral around the boundary.
For more generic information about form factors, see
Shape.compute_form_factor_amplitude
.
- distance_to_surface(angles)#
Compute the distance to the surface of the shape at the given angles.
Gets the distance to the surface at each of the angles provided, where the definition of the angles depends on the dimensionality of the shape (a single angle in 2D, or the phi/theta angles in 3D). All angles are relative to the x axis. In general, the distance is computed from the centroid of the shape unless stated otherwise.
- Parameters:
angles (\((N, d-1)\)
numpy.ndarray
) – Angles between \(0\) and \(2 \pi\) over which to calculate the distances. \(d\) is the number of dimensions.- Returns:
An array of distances from the center of the shape to its surface at each of the given angles.
- Return type:
\((N,)\)
numpy.ndarray
- property gsd_shape_spec#
Get a complete GSD specification.
- Type:
- property incircle#
Get the polygon’s incircle.
Note
The incircle of a polygon is defined as the circle contained within the polygon that is tangent to all its faces. This condition uniquely defines the circle, if it exists. The set of equations defined by this equation is solved using a least squares approach, with the magnitude of the residual used to determine whether or not the incircle exists.
- Type:
- property inertia_tensor#
Get the inertia tensor.
The inertia tensor is computed for the polygon embedded in \(\mathbb{R}^3\). This computation proceeds by first computing the polar moment of inertia for the polygon in the \(xy\)-plane relative to its centroid. The tensor is then rotated back to the orientation of the polygon and shifted to the original centroid.
- Type:
\((3, 3)\)
numpy.ndarray
- property iq#
The isoperimetric quotient.
The isoperimetric quotient is the ratio of the area of a shape to the area of a circle with the same perimeter. Given a shape of area \(A\) and perimeter \(p\), the circle with the same perimeter has radius \(r_p = \frac{p}{2\pi}\) and therefore has an area \(A_{circle} = \pi r_p^2 = \frac{p^2}{4\pi}\). Therefore, we have that:
\[\begin{split}\begin{align} IQ &= \frac{A}{A_{circle}} \\ &= \frac{4\pi A}{p^2} \end{align}\end{split}\]- Type:
- is_inside(points)#
Implement a simple point-in-polygon algorithm based on winding number.
The code in this function is based on implementation in [Dic19] which is licensed under the BSD-3 license.
Given a closed, possibly non-simple polygon described as a list of vertices in \(\mathbb{R}^2\) and a point that doesn’t lie directly on the path of the polygon, we’d like to compute the winding number of the polygon around the point. To achieve this, we place the point at the origin. Divide the remainder of the plane (i.e., \(\mathbb{R}^2\) minus the origin) into two halves, \(L\) and \(R\), defined as follows:
\[ \begin{align}\begin{aligned}L = {(x, y) | x < 0 \lor x = 0 \land y < 0}\\R = {(x, y) | x > 0 \lor x = 0 \land y > 0}\end{aligned}\end{align} \]That is, \(R\) contains all points with argument in the half-closed interval \(\left[-\frac{\pi}{2},\frac{\pi}{2}\right)\), and \(L\) contains all others. Note that with these definitions, \(L\) and \(R\) are both convex: a line segment between two points in \(R\) lies entirely in \(R\), and similarly for \(L\). In particular, a line segment between two points can only pass through the origin if one of those points is in \(L\) and the other in \(R\). Now, we follow the edges of the polygon, keeping track of how many times we move between \(L\) and \(R\). For each move from \(L\) to \(R\) (or vice versa), we also need to compute whether the edge passes above or below the origin, to compute its contribution to the total winding number. From the comment above, we can safely ignore all edges that lie entirely within either \(L\) or \(R\).
Note
Points on the boundary of the shape will return
False
.- Parameters:
points (\((N, 3)\) or \((N, 2)\)
numpy.ndarray
) – The points to test.- Returns:
Boolean array indicating which points are contained in the polyhedron.
- Return type:
\((N, )\)
numpy.ndarray
- property maximal_bounded_circle#
Get the largest bounded circle.
The largest circle contained in a shape is referred to by a range of ambiguous names. To avoid conflicts with the most common naming choices of other properties in the literature (particularly the
incircle
of a polygon), this property is named as an explicit analog tominimal_bounding_circle
.- Type:
- property maximal_bounded_circle_radius#
Get or set the radius of the maximal bounded circle.
See
maximal_bounded_circle()
for more information.- Type:
- property maximal_centered_bounded_circle_radius#
Get or set the radius of the maximal centered bounded circle.
See
maximal_centered_bounded_circle()
for more information.- Type:
- property minimal_bounding_circle_radius#
Get or set the radius of the minimal bounding circle.
See
minimal_bounding_circle()
for more information.- Type:
- property minimal_centered_bounding_circle#
Get the smallest bounding concentric circle.
- Type:
- property minimal_centered_bounding_circle_radius#
Get or set the radius of the minimal centered bounding circle.
See
minimal_centered_bounding_circle()
for more information.- Type:
- property normal#
Get the normal vector.
- Type:
\((3, )\)
numpy.ndarray
of float
- property planar_moments_inertia#
Get the planar and product moments of inertia.
Moments are computed with respect to the \(x\) and \(y\) axes. In addition to the two planar moments, this property also provides the product of inertia.
The planar moments and the product of inertia are defined by the formulas:
\[\begin{split}\begin{align} I_x &= {\int \int}_A y^2 dA \\ I_y &= {\int \int}_A x^2 dA \\ I_{xy} &= {\int \int}_A xy dA \\ \end{align}\end{split}\]To compute this for a polygon, we discretize the sum:
\[\begin{split}\begin{align} I_x &= \frac{1}{12} \sum_{i=1}^N (x_i y_{i+1} - x_{i+1} y_i) (y_i^2 + y_i*y_{i+1} + y_{i+1}^2) \\ I_y &= \frac{1}{12} \sum_{i=1}^N (x_i y_{i+1} - x_{i+1} y_i) (x_i^2 + x_i*x_{i+1} + x_{i+1}^2) \\ I_{xy} &= \frac{1}{12} \sum_{i=1}^N (x_i y_{i+1} - x_{i+1} y_i) (x_i y_{i+1} + 2 x_i y_i + 2 x_{i+1} y_{i+1} + x_{i+1} y_i) \\ \end{align}\end{split}\]These formulas can be derived as described here.
Note that the moments are always calculated about an axis perpendicular to the polygon, i.e. the normal vector is aligned with the \(z\) axis before the moments are calculated. This alignment should be considered when computing the moments for polygons embedded in three-dimensional space that are rotated out of the \(xy\) plane, since the planar moments are invariant to this orientation. The exact rotation used for this computation (i.e. changes in the \(x\) and \(y\) position) should not be relied upon.
- plot(ax=None, center=False, plot_verts=False, label_verts=False)#
Plot the polygon.
Note that the polygon is always rotated into the \(xy\) plane and plotted in two dimensions.
- Parameters:
ax (
matplotlib.axes.Axes
) – The axes on which to draw the polygon. Axes will be created if this is None (Default value: None).center (bool) – If True, the polygon vertices are plotted relative to its center (Default value: False).
plot_verts (bool) – If True, scatter points will be added at the vertices (Default value: False).
label_verts (bool) – If True, vertex indices will be added next to the vertices (Default value: False).
- property polar_moment_inertia#
Get the polar moment of inertia.
The polar moment of inertia is always calculated about an axis perpendicular to the shape (i.e. the normal vector).
The polar moment is computed as the sum of the two planar moments of inertia.
- Type:
- property signed_area#
Get the polygon’s area.
To support polygons embedded in 3 dimensional space, we employ a projection- and rescaling-based algorithm described here. Specifically, the polygon is projected onto the plane it is “most parallel” to, the area of the projected polygon is computed, then the area is rescaled by the component of the normal in the projected dimension.
- Type:
- to_hoomd()#
Get a JSON-serializable subset of Polygon properties.
The JSON-serializable output of the to_hoomd method can be directly imported into data management tools like signac. This data can then be queried for use in HOOMD simulations. Key naming matches HOOMD integrators: for example, the moment_inertia key links to data from coxeter’s inertia_tensor. Stored values are based on the shape with its centroid at the origin.
For a Polygon or ConvexPolygon, the following properties are stored:
- vertices (list(list)):
The vertices of the shape.
- centroid (list(float))
The centroid of the shape. This is set to [0,0,0] per HOOMD’s spec.
- sweep_radius (float):
The rounding radius of the shape (0.0).
- area (float)
The area of the shape.
- moment_inertia (list(list))
The shape’s inertia tensor.
- Returns:
Dict containing a subset of shape properties required for HOOMD function.
- Return type:
- to_plato_scene(backend='matplotlib', scene=None, scene_kwargs=None)#
Add this shape to a new or existing
plato.draw.Scene
.The plato visualization package provides support for several backends, including matplotlib, fresnel, povray, pythreejs, and vispy. The backend package must be separately installed by the user. Each backend supports different primitives (geometry objects) and may not support the primitive corresponding to a specific shape class in coxeter. Please refer to the plato documentation for more information about supported primitives for each backend.
- Parameters:
backend (str) – Name of backend to use from plato. The backend must support the primitive corresponding to this shape (Default value:
"matplotlib"
). Supported values include"matplotlib"
,"fresnel"
,"povray"
,"pythreejs"
,"vispy"
, and"zdog"
. See plato documentation for more information about each backend.scene (
plato.draw.Scene
) – Scene object to render into. If not provided or None, a new scene is created (Default value: None).scene_kwargs (dict) – Keyword arguments forwarded to the
plato.draw.Scene
(Default value: None). Only used ifscene
is not provided or None.
- Returns:
A scene containing this shape.
- Return type:
- Raises:
NotImplementedError: – If no plato primitive corresponds to this coxeter shape class.
AttributeError: – If the selected plato backend does not support the primitive for this coxeter shape class.
- property vertices#
Get the vertices of the polygon.
- Type:
\((N_{verts}, 3)\)
numpy.ndarray
of float
- class coxeter.shapes.ConvexPolyhedron(vertices)#
Bases:
Polyhedron
A convex polyhedron.
A convex polyhedron is defined as the convex hull of its vertices. The class is an extension of
Polyhedron
that builds the faces from the simplices of the convex hull. Simplices are stored and class methods are optimized to make use of the triangulation, as well as special properties of convex solids in three dimensions. This class also includes various additional properties that can be used to characterize geometric features of the polyhedron.- Parameters:
vertices (\((N, 3)\)
numpy.ndarray
) – The vertices of the polyhedron.
Example
>>> cube = coxeter.shapes.ConvexPolyhedron( ... [[-1, -1, -1], [-1, -1, 1], [-1, 1, -1], [-1, 1, 1], ... [1, -1, -1], [1, -1, 1], [1, 1, -1], [1, 1, 1]]) >>> import numpy as np >>> assert np.isclose(cube.asphericity, 1.5) >>> bounding_sphere = cube.minimal_bounding_sphere >>> assert np.isclose(bounding_sphere.radius, np.sqrt(3)) >>> cube.centroid array([0., 0., 0.]) >>> circumsphere = cube.circumsphere >>> assert np.isclose(circumsphere.radius, np.sqrt(3)) >>> cube.faces [array([0, 2, 6, 4], dtype=int32), array([0, 4, 5, 1], dtype=int32), array([4, 6, 7, 5], dtype=int32), array([0, 1, 3, 2], dtype=int32), array([2, 3, 7, 6], dtype=int32), array([1, 5, 7, 3], dtype=int32)] >>> cube.gsd_shape_spec {'type': 'ConvexPolyhedron', 'vertices': [[-1.0, -1.0, -1.0], [-1.0, -1.0, 1.0], [-1.0, 1.0, -1.0], [-1.0, 1.0, 1.0], [1.0, -1.0, -1.0], [1.0, -1.0, 1.0], [1.0, 1.0, -1.0], [1.0, 1.0, 1.0]]} >>> assert np.allclose( ... cube.inertia_tensor, ... np.diag([16. / 3., 16. / 3., 16. / 3.])) >>> sphere = cube.maximal_centered_bounded_sphere >>> sphere.radius 1.0 >>> assert np.isclose(cube.iq, np.pi / 6.) >>> assert np.isclose(cube.mean_curvature, 1.5) >>> cube.neighbors [array([1, 2, 3, 4]), array([0, 2, 3, 5]), array([0, 1, 4, 5]), array([0, 1, 4, 5]), array([0, 2, 3, 5]), array([1, 2, 3, 4])] >>> cube.normals array([[-0., -0., -1.], [ 0., -1., 0.], [ 1., -0., -0.], [-1., -0., -0.], [ 0., 1., -0.], [-0., -0., 1.]]) >>> cube.num_faces 6 >>> cube.num_vertices 8 >>> cube.surface_area 24.0 >>> assert np.isclose(cube.tau, 3. / 8. * np.pi) >>> cube.vertices array([[-1., -1., -1.], [-1., -1., 1.], [-1., 1., -1.], [-1., 1., 1.], [ 1., -1., -1.], [ 1., -1., 1.], [ 1., 1., -1.], [ 1., 1., 1.]]) >>> assert np.isclose(cube.volume, 8.)
Attributes:
Get the asphericity as defined in [IES+17].
Get the polyhedron's bounding sphere.
Alias for
centroid
.Get or set the center of mass.
Get the polyhedron's circumsphere.
Get the smallest circumscribed sphere centered at the centroid.
Get the radius of the polygon's circumsphere.
Get the length of each edge of the polyhedron.
Get the polyhedron's edges as vectors.
Get the polyhedron's edges.
Get plane equations for each face.
Calculate the centroid (center of mass) of each polygonal face.
Get the polyhedron's faces.
Get a complete GSD specification.
Get the inertia tensor.
Get the polyhedron's insphere.
Get the largest concentric inscribed sphere.
Get the radius of the polygon's insphere.
The isoperimetric quotient.
Get the largest bounded sphere.
Get or set the radius of the maximal bounded sphere.
Get the largest bounded concentric sphere.
Get or set the radius of the maximal centered bounded sphere.
The integrated, normalized mean curvature.
Get the polyhedron's bounding sphere.
Get or set the radius of the minimal bounding sphere.
Get the smallest bounding concentric sphere.
Get or set the radius of the minimal concentric bounding sphere.
Get neighboring pairs of faces.
Get normal vectors for each face.
Get the number of edges.
Get the number of faces.
Get the number of vertices.
Output the vertex indices of simplices composing the polyhedron's surface.
Get or set the surface area.
Get the parameter \(\tau = \frac{4\pi R^2}{S}\).
Get the vertices of the polyhedron.
Get or set the polyhedron's volume.
Methods:
compute_form_factor_amplitude
(q[, density])Calculate the form factor intensity.
Orient the shape along its principal axes.
distance_to_surface
(angles)Compute the distance to the surface of the shape at the given angles.
get_dihedral
(a, b)Get the dihedral angle between a pair of faces.
get_face_area
([face])Get the total surface area of a set of faces.
is_inside
(points)Determine whether points are contained in this polyhedron.
merge_faces
([atol, rtol])Merge coplanar faces to a given tolerance.
plot
([ax, plot_verts, label_verts])Plot the polyhedron.
Reorder faces counterclockwise relatative to the plane they lie on.
to_hoomd
()Get a JSON-serializable subset of Polyhedron properties.
to_json
(attributes)Get a JSON-serializable subset of shape properties.
to_plato_scene
([backend, scene, scene_kwargs])Add this shape to a new or existing
plato.draw.Scene
.- property center#
Alias for
centroid
.- Type:
\((3, )\)
numpy.ndarray
of float
- property centroid#
Get or set the center of mass.
The centroid is calculated using the curl theorem over the surface simplices.
- Type:
\((3, )\)
numpy.ndarray
of float
- property circumsphere#
Get the polyhedron’s circumsphere.
A circumsphere must touch all the points of the polyhedron. A circumsphere exists if and only if there is a point equidistant from all the vertices. The circumsphere is found by finding the least squares solution of the overdetermined system of linear equations defined by this constraint, and the circumsphere only exists if the resulting solution has no residual.
- Raises:
RuntimeError – If no circumsphere exists for this polyhedron.:
- Type:
- property circumsphere_from_center#
Get the smallest circumscribed sphere centered at the centroid.
The requirement that the sphere be centered at the centroid of the shape distinguishes this sphere from most typical circumsphere calculations.
- Type:
- compute_form_factor_amplitude(q, density=1.0)#
Calculate the form factor intensity.
The form factor amplitude of a polyhedron is computed according to the derivation provided in this dissertation: https://deepblue.lib.umich.edu/handle/2027.42/120906. In brief, two applications of Stokes theorem (or to use the names more familiar from elementary vector calculus, the application of the divergence theorem followed by the classic Kelvin-Stokes theorem) are used to reduce the volume integral over a polyhedron into a series of line integrals around the boundaries of each polygonal face.
For more generic information about form factors, see
Shape.compute_form_factor_amplitude
.
- diagonalize_inertia()#
Orient the shape along its principal axes.
The principal axes of a shape are defined by the eigenvectors of the inertia tensor. This method computes the inertia tensor of the shape, diagonalizes it, and then rotates the shape by the corresponding orthogonal transformation.
Example
>>> cube = coxeter.shapes.ConvexPolyhedron( ... [[1, 1, 1], [1, -1, 1], [1, 1, -1], [1, -1, -1], ... [-1, 1, 1], [-1, -1, 1], [-1, 1, -1], [-1, -1, -1]]) >>> cube.diagonalize_inertia() >>> cube.vertices array([[ 1., 1., 1.], [ 1., -1., 1.], [ 1., 1., -1.], [ 1., -1., -1.], [-1., 1., 1.], [-1., -1., 1.], [-1., 1., -1.], [-1., -1., -1.]])
- distance_to_surface(angles)#
Compute the distance to the surface of the shape at the given angles.
Gets the distance to the surface at each of the angles provided, where the definition of the angles depends on the dimensionality of the shape (a single angle in 2D, or the phi/theta angles in 3D). All angles are relative to the x axis. In general, the distance is computed from the centroid of the shape unless stated otherwise.
- Parameters:
angles (\((N, d-1)\)
numpy.ndarray
) – Angles between \(0\) and \(2 \pi\) over which to calculate the distances. \(d\) is the number of dimensions.- Returns:
An array of distances from the center of the shape to its surface at each of the given angles.
- Return type:
\((N,)\)
numpy.ndarray
- property edge_lengths#
Get the length of each edge of the polyhedron.
edge_lengths
are returned in the same order as inedges
.- Type:
- property edge_vectors#
Get the polyhedron’s edges as vectors.
edge_vectors
are returned in the same order as inedges
.- Type:
- property edges#
Get the polyhedron’s edges.
Results returned as vertex index pairs, with each edge of the polyhedron included exactly once. Edge (i,j) pairs are ordered by vertex index with i<j.
- Type:
- property equations#
Get plane equations for each face.
Sign convention matches Scipy Convex Hull (ax + by + cz + d = 0).
- Type:
\((N, 4)\)
numpy.ndarray
- property face_centroids#
Calculate the centroid (center of mass) of each polygonal face.
- Returns:
Array of centroids for each face.
- Return type:
\((N,3)\)
numpy.ndarray
- property faces#
Get the polyhedron’s faces.
- Type:
list(
numpy.ndarray
)
- get_dihedral(a, b)#
Get the dihedral angle between a pair of faces.
The dihedral is computed from the dot product of the face normals.
- Parameters:
- Returns:
float
- Return type:
The dihedral angle in radians.
Example
>>> cube = coxeter.shapes.ConvexPolyhedron( ... [[1, 1, 1], [1, -1, 1], [1, 1, -1], [1, -1, -1], ... [-1, 1, 1], [-1, -1, 1], [-1, 1, -1], [-1, -1, -1]]) >>> cube = coxeter.shapes.Polyhedron( ... vertices=cube.vertices, faces=cube.faces) >>> import numpy as np >>> assert np.isclose(cube.get_dihedral(1, 2), np.pi / 2.)
- get_face_area(face=None)#
Get the total surface area of a set of faces.
- Parameters:
faces (int, sequence, or None) – The index of a face or a set of face indices for which to find the area. If None, finds the area of all faces. (Default value: None).
- Returns:
:class:`numpy.ndarray`
- Return type:
The area of each face.
Example
>>> cube = coxeter.shapes.ConvexPolyhedron( ... [[1, 1, 1], [1, -1, 1], [1, 1, -1], [1, -1, -1], ... [-1, 1, 1], [-1, -1, 1], [-1, 1, -1], [-1, -1, -1]]) >>> cube = coxeter.shapes.Polyhedron( ... vertices=cube.vertices,faces=cube.faces) >>> import numpy as np >>> assert np.allclose( ... cube.get_face_area([1, 2, 3]), ... [4., 4., 4.])
- property gsd_shape_spec#
Get a complete GSD specification.
- Type:
- property inertia_tensor#
Get the inertia tensor.
The inertia tensor for convex shapes is computed using the algorithm described in [MT80].
Note
For improved stability, the inertia tensor is computed about the center of mass and then shifted rather than directly computed in the global frame.
- Type:
\((3, 3)\)
numpy.ndarray
- property insphere#
Get the polyhedron’s insphere.
Note
The insphere of a polyhedron is defined as the sphere contained within the polyhedron that is tangent to all its faces. This condition uniquely defines the sphere, if it exists. The set of equations defined by this equation is solved using a least squares approach, with the magnitude of the residual used to determine whether or not the insphere exists.
- Type:
- property iq#
The isoperimetric quotient.
The isoperimetric quotient is the ratio of the volume of a shape to the volume of a sphere with the same perimeter. Given a shape of volume \(A\) and surface \(S\), the sphere with the same surface has radius \(r_S = \sqrt{\frac{S}{4\pi}}\) and therefore has volume \(V_{sphere} = \frac{4}{3} \pi r_S^3 = \frac{S^{3/2}}{\sqrt{4\pi}}\). Taking the ratio of volumes gives:
\[\begin{equation} \frac{V}{V_{sphere}} = \frac{6\sqrt{\pi} V}{S^{3/2}} \end{equation}\]To avoid inconvenient fractional exponents, the isoperimetric quotient is conventionally defined as the square of this quantity:
\[\begin{split}\begin{align} IQ &= \left(\frac{V}{V_{sphere}}\right)^2 \\ &= \frac{36\pi V^2}{S^3} \end{align}\end{split}\]- Type:
- is_inside(points)#
Determine whether points are contained in this polyhedron.
Note
Points on the boundary of the shape will return
True
.- Parameters:
points (\((N, 3)\)
numpy.ndarray
) – The points to test.- Returns:
Boolean array indicating which points are contained in the polyhedron.
- Return type:
\((N, )\)
numpy.ndarray
- property maximal_bounded_sphere#
Get the largest bounded sphere.
The largest sphere contained in a shape is referred to by a range of ambiguous names. To avoid conflicts with the most common naming choices of other properties in the literature (particularly the
insphere
of a polyhedron), this property is named as an explicit analog tominimal_bounding_sphere
.- Type:
- property maximal_bounded_sphere_radius#
Get or set the radius of the maximal bounded sphere.
See
maximal_bounded_sphere()
for more information.- Type:
- property maximal_centered_bounded_sphere_radius#
Get or set the radius of the maximal centered bounded sphere.
See
maximal_centered_bounded_sphere()
for more information.- Type:
- property mean_curvature#
The integrated, normalized mean curvature.
This quantity is calculated by the formula \(R = \sum_i (1/2) L_i (\pi - \phi_i) / (4 \pi)\) with edge lengths \(L_i\) and dihedral angles \(\phi_i\) (see [IES+17] for more information).
- Type:
- merge_faces(atol=1e-08, rtol=1e-05)#
Merge coplanar faces to a given tolerance.
Whether or not faces should be merged is determined using
numpy.allclose()
to compare the plane equations of neighboring faces. Connected components of mergeable faces are then merged into a single face. This method can be safely called many times with different tolerances, however, the operation is destructive in the sense that merged faces cannot be recovered. Users wishing to undo a merge to attempt a less expansive merge must build a new polyhedron.- Parameters:
atol (float) – Absolute tolerance for
numpy.allclose()
.rtol (float) – Relative tolerance for
numpy.allclose()
.
- property minimal_bounding_sphere_radius#
Get or set the radius of the minimal bounding sphere.
See
minimal_bounding_sphere()
for more information.- Type:
- property minimal_centered_bounding_sphere#
Get the smallest bounding concentric sphere.
- Type:
- property minimal_centered_bounding_sphere_radius#
Get or set the radius of the minimal concentric bounding sphere.
See
minimal_centered_bounding_sphere()
for more information.- Type:
- property neighbors#
Get neighboring pairs of faces.
The neighbors are provided as a list where the \(i^{\text{th}}\) element is an array of indices of faces that are neighbors of face \(i\).
- Type:
list(
numpy.ndarray
)
- property normals#
Get normal vectors for each face.
- Type:
\((N, 3)\)
numpy.ndarray
- plot(ax=None, plot_verts=False, label_verts=False)#
Plot the polyhedron.
Note that the
ax
argument should be a 3D axes object; passing in a 2D axes object will result in wrong behavior.- Parameters:
ax (
mpl_toolkits.mplot3d.axes3d.Axes3D
) – The axes on which to draw the polyhedron. Axes will be created if this is None (Default value: None).plot_verts (bool) – If True, scatter points will be added at the vertices (Default value: False).
label_verts (bool) – If True, vertex indices will be added next to the vertices (Default value: False).
- property simplices#
Output the vertex indices of simplices composing the polyhedron’s surface.
- Returns:
Array of vertex indices of simplices making up the polyhedron’s surface.
- Return type:
\((N,3)\)
numpy.ndarray
- sort_faces()#
Reorder faces counterclockwise relatative to the plane they lie on.
This does NOT change the order of faces in the list.
- property tau#
Get the parameter \(\tau = \frac{4\pi R^2}{S}\).
This parameter is defined in [NL84] and is closely related to the Pitzer acentric factor. This quantity appears relevant to the third and fourth virial coefficient for hard polyhedron fluids.
- Type:
- to_hoomd()#
Get a JSON-serializable subset of Polyhedron properties.
The JSON-serializable output of the to_hoomd method can be directly imported into data management tools like signac. This data can then be queried for use in HOOMD simulations. Key naming matches HOOMD integrators: for example, the moment_inertia key links to data from coxeter’s inertia_tensor. Stored values are based on the shape with its centroid at the origin.
For a Polyhedron or ConvexPolyhedron, the following properties are stored:
- vertices (list(list)):
The vertices of the shape.
- faces (list(list)):
The faces of the shape.
- centroid (list(float))
The centroid of the shape. This is set to [0,0,0] per HOOMD’s spec.
- sweep_radius (float):
The rounding radius of the shape (0.0).
- volume (float)
The volume of the shape.
- moment_inertia (list(list))
The shape’s inertia tensor.
- Returns:
Dict containing a subset of shape properties required for HOOMD function.
- Return type:
- to_plato_scene(backend='matplotlib', scene=None, scene_kwargs=None)#
Add this shape to a new or existing
plato.draw.Scene
.The plato visualization package provides support for several backends, including matplotlib, fresnel, povray, pythreejs, and vispy. The backend package must be separately installed by the user. Each backend supports different primitives (geometry objects) and may not support the primitive corresponding to a specific shape class in coxeter. Please refer to the plato documentation for more information about supported primitives for each backend.
- Parameters:
backend (str) – Name of backend to use from plato. The backend must support the primitive corresponding to this shape (Default value:
"matplotlib"
). Supported values include"matplotlib"
,"fresnel"
,"povray"
,"pythreejs"
,"vispy"
, and"zdog"
. See plato documentation for more information about each backend.scene (
plato.draw.Scene
) – Scene object to render into. If not provided or None, a new scene is created (Default value: None).scene_kwargs (dict) – Keyword arguments forwarded to the
plato.draw.Scene
(Default value: None). Only used ifscene
is not provided or None.
- Returns:
A scene containing this shape.
- Return type:
- Raises:
NotImplementedError: – If no plato primitive corresponds to this coxeter shape class.
AttributeError: – If the selected plato backend does not support the primitive for this coxeter shape class.
- property vertices#
Get the vertices of the polyhedron.
- Type:
\((N, 3)\)
numpy.ndarray
- class coxeter.shapes.ConvexSpheropolygon(vertices, radius, normal=None)#
Bases:
Shape2D
A convex spheropolygon.
- Parameters:
vertices (\((N, 3)\) or \((N, 2)\)
numpy.ndarray
) – The vertices of the polygon.radius (float) – The rounding radius of the spheropolygon.
normal (sequence of length 3 or None) – The normal vector to the polygon. If
None
, the normal is computed by taking the cross product of the vectors formed by the first three verticesnp.cross(vertices[2, :] - vertices[1, :], vertices[0, :] - vertices[1, :])
. Since this arbitrary choice may not preserve the orientation of the provided vertices, users may provide a normal instead (Default value: None).
Example
>>> rounded_tri = coxeter.shapes.ConvexSpheropolygon( ... [[-1, 0], [0, 1], [1, 0]], radius=.1) >>> rounded_tri.area 1.5142... >>> rounded_tri.gsd_shape_spec {'type': 'Polygon', 'vertices': [[-1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [1.0, 0.0, 0.0]], 'rounding_radius': 0.1} >>> rounded_tri.radius 0.1 >>> rounded_tri.signed_area 1.5142... >>> rounded_tri.vertices array([[-1., 0., 0.], [ 0., 1., 0.], [ 1., 0., 0.]])
Attributes:
Get or set the polygon's area.
Alias for
centroid
.Get or set the centroid of the shape.
Get a complete GSD specification.
Get the inertia tensor.
The isoperimetric quotient.
Get the largest bounded circle.
Get or set the radius of the maximal bounded circle.
Get the largest concentric bounded circle.
Get or set the radius of the maximal centered bounded circle.
Get the smallest bounding circle.
Get or set the radius of the minimal bounding circle.
Get the smallest bounding concentric circle.
Get or set the radius of the minimal centered bounding circle.
Get the normal vector.
Get the number of vertices.
Get the perimeter of the spheropolygon.
Get the planar and product moments of inertia.
Get the polar moment of inertia.
The underlying polygon.
Get or set the rounding radius.
Get the signed area of the spheropolygon.
Get the vertices of the spheropolygon.
Methods:
Calculate the form factor intensity.
distance_to_surface
(angles)Distance to the surface of this shape.
is_inside
(points)Determine whether points are contained in this shape.
plot
()Plot the shape.
to_hoomd
()Get a JSON-serializable subset of ConvexSpheropolygon properties.
to_json
(attributes)Get a JSON-serializable subset of shape properties.
to_plato_scene
([backend, scene, scene_kwargs])Add this shape to a new or existing
plato.draw.Scene
.- property area#
Get or set the polygon’s area.
To get the area, we simply compute the signed area and take the absolute value.
- property center#
Alias for
centroid
.- Type:
\((3, )\)
numpy.ndarray
of float
- property centroid#
Get or set the centroid of the shape.
- Type:
\((3, )\)
numpy.ndarray
of float
- compute_form_factor_amplitude(q)#
Calculate the form factor intensity.
In solid state physics, scattering theory is concerned with understanding the ways in which radiation is scattered from a sample. For a single point particle at position P, the the amplitude of a scattered wave observed at position Q is the product of the incoming wave amplitude (which follows the standard equation for a traveling wave) and the scattering density at P. For a crystal composed of many point particles, the intensity of the resulting superposition of waves can be identified as the Fourier transform of the total scattering density. When the particles are not point particles, the scattering density of the particles in their local coordinate systems are no longer identical. Conveniently, this component is separable in the Fourier transform of the total density; as a result, the scattering scattering intensity can be decomposed into two terms, the Fourier transform of the distribution of scatterers and the Fourier transform of each scatterer in its local coordinate system. The first term is known as the static structure factor \(S(\vec{q})\) and describes the spatial distribution of scatterers, while the second term is called the form factor \(f(\vec{q})\) and describes the local scattering profile.
While the form factor (the scattering intensity) can be measured from diffraction experiments, the Fourier transform of a single particle cannot. However, it can be computed theoretically for a known scattering volume and can be inserted directly into the expression for the total scattering intensity. This local profile directly describes the wave emitted from a single scatterer (in reciprocal space) and is known as the form factor amplitude. This function computes the form factor amplitude for a given wavevector \(q\).
- distance_to_surface(angles)#
Distance to the surface of this shape.
Since the centroid of a spheropolygon is difficult to compute in general, the distance is calculated relative to the centroid of the core polygon. For more general information about this calculation, see
Shape.distance_to_surface
.
- property gsd_shape_spec#
Get a complete GSD specification.
- Type:
- property inertia_tensor#
Get the inertia tensor.
For non-orientable 2D shapes, the inertia tensor can be trivially constructed from the polar moment of inertia. This calculation assumes that the shape lies in the \(xy\)-plane. Shapes that can be rotated relative to this plane must define their own methods.
- Type:
\((3, 3)\)
numpy.ndarray
- property iq#
The isoperimetric quotient.
The isoperimetric quotient is the ratio of the area of a shape to the area of a circle with the same perimeter. Given a shape of area \(A\) and perimeter \(p\), the circle with the same perimeter has radius \(r_p = \frac{p}{2\pi}\) and therefore has an area \(A_{circle} = \pi r_p^2 = \frac{p^2}{4\pi}\). Therefore, we have that:
\[\begin{split}\begin{align} IQ &= \frac{A}{A_{circle}} \\ &= \frac{4\pi A}{p^2} \end{align}\end{split}\]- Type:
- is_inside(points)#
Determine whether points are contained in this shape.
Note
Points on the boundary of the shape will return
True
.- Parameters:
points (\((N, 3)\)
numpy.ndarray
) – The points to test.- Returns:
Boolean array indicating which points are contained in the shape.
- Return type:
\((N, )\)
numpy.ndarray
- property maximal_bounded_circle#
Get the largest bounded circle.
The largest circle contained in a shape is referred to by a range of ambiguous names. To avoid conflicts with the most common naming choices of other properties in the literature (particularly the
incircle
of a polygon), this property is named as an explicit analog tominimal_bounding_circle
.- Type:
- property maximal_bounded_circle_radius#
Get or set the radius of the maximal bounded circle.
See
maximal_bounded_circle()
for more information.- Type:
- property maximal_centered_bounded_circle#
Get the largest concentric bounded circle.
This property gives the largest circle that fits in the shape whose center also coincides with the center of the shape.
- Type:
- property maximal_centered_bounded_circle_radius#
Get or set the radius of the maximal centered bounded circle.
See
maximal_centered_bounded_circle()
for more information.- Type:
- property minimal_bounding_circle#
Get the smallest bounding circle.
A bounding circle in two dimensions is a circle containing all of the points. There are an infinite set of possible bounding circles for a shape (since any circle that entirely contains a bounding circle is also a bounding circle), so additional constraints must be imposed to define a unique circle. This property provides the smallest bounding circle of a shape.
- Type:
- property minimal_bounding_circle_radius#
Get or set the radius of the minimal bounding circle.
See
minimal_bounding_circle()
for more information.- Type:
- property minimal_centered_bounding_circle#
Get the smallest bounding concentric circle.
This property gives the smallest bounding circle whose center coincides with the center of the shape.
- Type:
- property minimal_centered_bounding_circle_radius#
Get or set the radius of the minimal centered bounding circle.
See
minimal_centered_bounding_circle()
for more information.- Type:
- property normal#
Get the normal vector.
- Type:
\((3, )\)
numpy.ndarray
of float
- property planar_moments_inertia#
Get the planar and product moments of inertia.
Moments are computed with respect to the \(x\) and \(y\) axes. In addition to the two planar moments, this property also provides the product of inertia.
The planar moments of inertia and the product of inertia define the in-plane area distribution.
- plot()#
Plot the shape.
- property polar_moment_inertia#
Get the polar moment of inertia.
The polar moment of inertia is always calculated about an axis perpendicular to the shape (i.e. the normal vector).
The polar moment is computed as the sum of the two planar moments of inertia.
- Type:
- property polygon#
The underlying polygon.
- Type:
- property signed_area#
Get the signed area of the spheropolygon.
The area is computed as the sum of the underlying polygon area and the area added by the rounding radius.
- to_hoomd()#
Get a JSON-serializable subset of ConvexSpheropolygon properties.
The JSON-serializable output of the to_hoomd method can be directly imported into data management tools like signac. This data can then be queried for use in HOOMD simulations. Key naming matches HOOMD integrators: for example, the moment_inertia key links to data from coxeter’s inertia_tensor. Stored values are based on the shape with its centroid at the origin.
For a ConvexSpheropolygon, the following properties are stored:
- vertices (list(list)):
The vertices of the shape.
- centroid (list(float))
The centroid of the shape. This is set to [0,0,0] per HOOMD’s spec.
- sweep_radius (float):
The rounding radius of the shape.
- area (float)
The area of the shape.
- Returns:
Dict containing a subset of shape properties required for HOOMD function.
- Return type:
- to_plato_scene(backend='matplotlib', scene=None, scene_kwargs=None)#
Add this shape to a new or existing
plato.draw.Scene
.The plato visualization package provides support for several backends, including matplotlib, fresnel, povray, pythreejs, and vispy. The backend package must be separately installed by the user. Each backend supports different primitives (geometry objects) and may not support the primitive corresponding to a specific shape class in coxeter. Please refer to the plato documentation for more information about supported primitives for each backend.
- Parameters:
backend (str) – Name of backend to use from plato. The backend must support the primitive corresponding to this shape (Default value:
"matplotlib"
). Supported values include"matplotlib"
,"fresnel"
,"povray"
,"pythreejs"
,"vispy"
, and"zdog"
. See plato documentation for more information about each backend.scene (
plato.draw.Scene
) – Scene object to render into. If not provided or None, a new scene is created (Default value: None).scene_kwargs (dict) – Keyword arguments forwarded to the
plato.draw.Scene
(Default value: None). Only used ifscene
is not provided or None.
- Returns:
A scene containing this shape.
- Return type:
- Raises:
NotImplementedError: – If no plato primitive corresponds to this coxeter shape class.
AttributeError: – If the selected plato backend does not support the primitive for this coxeter shape class.
- property vertices#
Get the vertices of the spheropolygon.
- Type:
\((N_{verts}, 3)\)
numpy.ndarray
of float
- class coxeter.shapes.ConvexSpheropolyhedron(vertices, radius)#
Bases:
Shape3D
A convex spheropolyhedron.
A convex spheropolyhedron is defined as a convex polyhedron plus a rounding radius. All properties of the underlying polyhedron (the vertices, the faces and their neighbors, etc.) can be accessed directly through
polyhedron
.- Parameters:
vertices (\((N, 3)\)
numpy.ndarray
) – The vertices of the underlying polyhedron.radius (float) – The rounding radius of the spheropolyhedron.
Example
>>> spherocube = coxeter.shapes.ConvexSpheropolyhedron( ... [[1, 1, 1], [1, -1, 1], [1, 1, -1], [1, -1, -1], ... [-1, 1, 1], [-1, -1, 1], [-1, 1, -1], [-1, -1, -1]], ... radius=0.5) >>> spherocube.gsd_shape_spec {'type': 'ConvexPolyhedron', 'vertices': [[1.0, 1.0, 1.0], [1.0, -1.0, 1.0], [1.0, 1.0, -1.0], [1.0, -1.0, -1.0], [-1.0, 1.0, 1.0], [-1.0, -1.0, 1.0], [-1.0, 1.0, -1.0], [-1.0, -1.0, -1.0]], 'rounding_radius': 0.5} >>> cube = spherocube.polyhedron >>> cube.vertices array([[ 1., 1., 1.], [ 1., -1., 1.], [ 1., 1., -1.], [ 1., -1., -1.], [-1., 1., 1.], [-1., -1., 1.], [-1., 1., -1.], [-1., -1., -1.]]) >>> spherocube.radius 0.5 >>> spherocube.surface_area 45.991... >>> spherocube.vertices array([[ 1., 1., 1.], [ 1., -1., 1.], [ 1., 1., -1.], [ 1., -1., -1.], [-1., 1., 1.], [-1., -1., 1.], [-1., 1., -1.], [-1., -1., -1.]]) >>> spherocube.volume 25.235...
Attributes:
Alias for
centroid
.Get or set the centroid of the shape.
Get a complete GSD specification.
The isoperimetric quotient.
Get the largest bounded sphere.
Get or set the radius of the maximal bounded sphere.
Get the largest concentric bounded sphere.
Get or set the radius of the maximal centered bounded sphere.
Get the mean curvature.
Get a bounding sphere sharing the center of this shape.
Get or set the radius of the minimal bounding sphere.
Get a bounding sphere sharing the center of this shape.
Get or set the radius of the minimal concentric bounding sphere.
The underlying polyhedron.
The rounding radius.
Get the surface area.
Get the vertices of the spheropolyhedron.
The volume.
Methods:
Calculate the form factor intensity.
distance_to_surface
(angles)Compute the distance to the surface of the shape at the given angles.
\((3, 3)\)
numpy.ndarray
: Get the inertia tensor.is_inside
(points)Determine whether points are contained in this spheropolyhedron.
plot
()Plot the shape.
to_hoomd
()Get a JSON-serializable subset of ConvexSpheropolyhedron properties.
to_json
(attributes)Get a JSON-serializable subset of shape properties.
to_plato_scene
([backend, scene, scene_kwargs])Add this shape to a new or existing
plato.draw.Scene
.- property center#
Alias for
centroid
.- Type:
\((3, )\)
numpy.ndarray
of float
- property centroid#
Get or set the centroid of the shape.
- Type:
\((3, )\)
numpy.ndarray
of float
- compute_form_factor_amplitude(q)#
Calculate the form factor intensity.
In solid state physics, scattering theory is concerned with understanding the ways in which radiation is scattered from a sample. For a single point particle at position P, the the amplitude of a scattered wave observed at position Q is the product of the incoming wave amplitude (which follows the standard equation for a traveling wave) and the scattering density at P. For a crystal composed of many point particles, the intensity of the resulting superposition of waves can be identified as the Fourier transform of the total scattering density. When the particles are not point particles, the scattering density of the particles in their local coordinate systems are no longer identical. Conveniently, this component is separable in the Fourier transform of the total density; as a result, the scattering scattering intensity can be decomposed into two terms, the Fourier transform of the distribution of scatterers and the Fourier transform of each scatterer in its local coordinate system. The first term is known as the static structure factor \(S(\vec{q})\) and describes the spatial distribution of scatterers, while the second term is called the form factor \(f(\vec{q})\) and describes the local scattering profile.
While the form factor (the scattering intensity) can be measured from diffraction experiments, the Fourier transform of a single particle cannot. However, it can be computed theoretically for a known scattering volume and can be inserted directly into the expression for the total scattering intensity. This local profile directly describes the wave emitted from a single scatterer (in reciprocal space) and is known as the form factor amplitude. This function computes the form factor amplitude for a given wavevector \(q\).
- distance_to_surface(angles)#
Compute the distance to the surface of the shape at the given angles.
Gets the distance to the surface at each of the angles provided, where the definition of the angles depends on the dimensionality of the shape (a single angle in 2D, or the phi/theta angles in 3D). All angles are relative to the x axis. In general, the distance is computed from the centroid of the shape unless stated otherwise.
- Parameters:
angles (\((N, d-1)\)
numpy.ndarray
) – Angles between \(0\) and \(2 \pi\) over which to calculate the distances. \(d\) is the number of dimensions.- Returns:
An array of distances from the center of the shape to its surface at each of the given angles.
- Return type:
\((N,)\)
numpy.ndarray
- property gsd_shape_spec#
Get a complete GSD specification.
- Type:
- inertia_tensor()#
\((3, 3)\)
numpy.ndarray
: Get the inertia tensor.
- property iq#
The isoperimetric quotient.
The isoperimetric quotient is the ratio of the volume of a shape to the volume of a sphere with the same perimeter. Given a shape of volume \(A\) and surface \(S\), the sphere with the same surface has radius \(r_S = \sqrt{\frac{S}{4\pi}}\) and therefore has volume \(V_{sphere} = \frac{4}{3} \pi r_S^3 = \frac{S^{3/2}}{\sqrt{4\pi}}\). Taking the ratio of volumes gives:
\[\begin{equation} \frac{V}{V_{sphere}} = \frac{6\sqrt{\pi} V}{S^{3/2}} \end{equation}\]To avoid inconvenient fractional exponents, the isoperimetric quotient is conventionally defined as the square of this quantity:
\[\begin{split}\begin{align} IQ &= \left(\frac{V}{V_{sphere}}\right)^2 \\ &= \frac{36\pi V^2}{S^3} \end{align}\end{split}\]- Type:
- is_inside(points)#
Determine whether points are contained in this spheropolyhedron.
Note
Points on the boundary of the shape will return
True
.- Parameters:
points (\((N, 3)\)
numpy.ndarray
) – The points to test.- Returns:
Boolean array indicating which points are contained in the spheropolyhedron.
- Return type:
\((N, )\)
numpy.ndarray
Example
>>> sphero = coxeter.shapes.ConvexSpheropolyhedron( ... [[1, 1, 1], [1, -1, 1], [1, 1, -1], [1, -1, -1], ... [-1, 1, 1], [-1, -1, 1], [-1, 1, -1], [-1, -1, -1]], ... radius=0.5) >>> sphero.is_inside([[0, 0, 0], [10, 10, 10]]) array([ True, False])
- property maximal_bounded_sphere#
Get the largest bounded sphere.
The largest sphere contained in a shape is referred to by a range of ambiguous names. To avoid conflicts with the most common naming choices of other properties in the literature (particularly the
insphere
of a polyhedron), this property is named as an explicit analog tominimal_bounding_sphere
.- Type:
- property maximal_bounded_sphere_radius#
Get or set the radius of the maximal bounded sphere.
See
maximal_bounded_sphere()
for more information.- Type:
- property maximal_centered_bounded_sphere#
Get the largest concentric bounded sphere.
This property gives the largest sphere that fits in the shape whose center also coincides with the center of the shape.
- Type:
- property maximal_centered_bounded_sphere_radius#
Get or set the radius of the maximal centered bounded sphere.
See
maximal_centered_bounded_sphere()
for more information.- Type:
- property minimal_bounding_sphere#
Get a bounding sphere sharing the center of this shape.
A bounding sphere of a collection of points in dimensions is a sphere containing all of the points. There are an infinite set of possible bounding spheres for a shape (since any sphere that entirely contains a bounding sphere is also a bounding sphere), so additional constraints must be imposed to define a unique sphere. This property provides the smallest bounding sphere of a shape.
- Type:
- property minimal_bounding_sphere_radius#
Get or set the radius of the minimal bounding sphere.
See
minimal_bounding_sphere()
for more information.- Type:
- property minimal_centered_bounding_sphere#
Get a bounding sphere sharing the center of this shape.
A bounding sphere of a collection of points in is a sphere containing all of the points. There are an infinite set of possible bounding spheres for a shape (since any sphere that entirely contains a bounding sphere is also a bounding sphere), so additional constraints must be imposed to define a unique sphere. This property provides the smallest bounding sphere of a shape whose center coincides with the center of the shape.
- Type:
- property minimal_centered_bounding_sphere_radius#
Get or set the radius of the minimal concentric bounding sphere.
See
minimal_centered_bounding_sphere()
for more information.- Type:
- plot()#
Plot the shape.
- property polyhedron#
The underlying polyhedron.
- Type:
- to_hoomd()#
Get a JSON-serializable subset of ConvexSpheropolyhedron properties.
The JSON-serializable output of the to_hoomd method can be directly imported into data management tools like signac. This data can then be queried for use in HOOMD simulations. Key naming matches HOOMD integrators: for example, the moment_inertia key links to data from coxeter’s inertia_tensor. Stored values are based on the shape with its centroid at the origin.
For a ConvexSpheropolyhedron, the following properties are stored:
- vertices (list(list)):
The vertices of the shape.
- centroid (list(float))
The centroid of the shape. This is set to [0,0,0] per HOOMD’s spec.
- sweep_radius (float):
The rounding radius of the shape.
- volume (float)
The volume of the shape.
- Returns:
Dict containing a subset of shape properties required for HOOMD function.
- Return type:
- to_plato_scene(backend='matplotlib', scene=None, scene_kwargs=None)#
Add this shape to a new or existing
plato.draw.Scene
.The plato visualization package provides support for several backends, including matplotlib, fresnel, povray, pythreejs, and vispy. The backend package must be separately installed by the user. Each backend supports different primitives (geometry objects) and may not support the primitive corresponding to a specific shape class in coxeter. Please refer to the plato documentation for more information about supported primitives for each backend.
- Parameters:
backend (str) – Name of backend to use from plato. The backend must support the primitive corresponding to this shape (Default value:
"matplotlib"
). Supported values include"matplotlib"
,"fresnel"
,"povray"
,"pythreejs"
,"vispy"
, and"zdog"
. See plato documentation for more information about each backend.scene (
plato.draw.Scene
) – Scene object to render into. If not provided or None, a new scene is created (Default value: None).scene_kwargs (dict) – Keyword arguments forwarded to the
plato.draw.Scene
(Default value: None). Only used ifscene
is not provided or None.
- Returns:
A scene containing this shape.
- Return type:
- Raises:
NotImplementedError: – If no plato primitive corresponds to this coxeter shape class.
AttributeError: – If the selected plato backend does not support the primitive for this coxeter shape class.
- property vertices#
Get the vertices of the spheropolyhedron.
- class coxeter.shapes.Ellipse(a, b, center=(0, 0, 0))#
Bases:
Shape2D
An ellipse with principal axes a and b.
- Parameters:
Example
>>> ellipse = coxeter.shapes.Ellipse(1.0, 2.0) >>> ellipse.a 1.0 >>> ellipse.b 2.0 >>> ellipse.area 6.28318... >>> ellipse.centroid array([0, 0, 0]) >>> ellipse.circumference 9.68844... >>> ellipse.eccentricity 0.86602... >>> ellipse.gsd_shape_spec {'type': 'Ellipsoid', 'a': 1.0, 'b': 2.0} >>> ellipse.iq 0.84116... >>> ellipse.perimeter 9.68844... >>> ellipse.polar_moment_inertia 7.85398...
Attributes:
Length of principal axis a (radius in the \(x\) direction).
Get or set the area.
Length of principal axis b (radius in the \(y\) direction).
Alias for
centroid
.Get or set the centroid of the shape.
Alias for
Ellipse.perimeter
.The eccentricity.
Get a complete GSD specification.
Get the inertia tensor.
The isoperimetric quotient.
Get the largest bounded circle.
Get or set the radius of the maximal bounded circle.
Get the largest bounded concentric circle.
Get or set the radius of the maximal centered bounded circle.
Get the smallest bounding circle.
Get or set the radius of the minimal bounding circle.
Get the smallest bounding concentric circle.
Get or set the radius of the minimal centered bounding circle.
The perimeter.
Get the planar and product moments of inertia.
Get the polar moment of inertia.
Methods:
Calculate the form factor intensity.
distance_to_surface
(angles)Compute the distance to the surface of the shape at the given angles.
is_inside
(points)Determine whether a set of points are contained in this ellipse.
plot
()Plot the shape.
to_json
(attributes)Get a JSON-serializable subset of shape properties.
to_plato_scene
([backend, scene, scene_kwargs])Add this shape to a new or existing
plato.draw.Scene
.- property center#
Alias for
centroid
.- Type:
\((3, )\)
numpy.ndarray
of float
- property centroid#
Get or set the centroid of the shape.
- Type:
\((3, )\)
numpy.ndarray
of float
- property circumference#
Alias for
Ellipse.perimeter
.- Type:
- compute_form_factor_amplitude(q)#
Calculate the form factor intensity.
In solid state physics, scattering theory is concerned with understanding the ways in which radiation is scattered from a sample. For a single point particle at position P, the the amplitude of a scattered wave observed at position Q is the product of the incoming wave amplitude (which follows the standard equation for a traveling wave) and the scattering density at P. For a crystal composed of many point particles, the intensity of the resulting superposition of waves can be identified as the Fourier transform of the total scattering density. When the particles are not point particles, the scattering density of the particles in their local coordinate systems are no longer identical. Conveniently, this component is separable in the Fourier transform of the total density; as a result, the scattering scattering intensity can be decomposed into two terms, the Fourier transform of the distribution of scatterers and the Fourier transform of each scatterer in its local coordinate system. The first term is known as the static structure factor \(S(\vec{q})\) and describes the spatial distribution of scatterers, while the second term is called the form factor \(f(\vec{q})\) and describes the local scattering profile.
While the form factor (the scattering intensity) can be measured from diffraction experiments, the Fourier transform of a single particle cannot. However, it can be computed theoretically for a known scattering volume and can be inserted directly into the expression for the total scattering intensity. This local profile directly describes the wave emitted from a single scatterer (in reciprocal space) and is known as the form factor amplitude. This function computes the form factor amplitude for a given wavevector \(q\).
- distance_to_surface(angles)#
Compute the distance to the surface of the shape at the given angles.
Gets the distance to the surface at each of the angles provided, where the definition of the angles depends on the dimensionality of the shape (a single angle in 2D, or the phi/theta angles in 3D). All angles are relative to the x axis. In general, the distance is computed from the centroid of the shape unless stated otherwise.
- Parameters:
angles (\((N, d-1)\)
numpy.ndarray
) – Angles between \(0\) and \(2 \pi\) over which to calculate the distances. \(d\) is the number of dimensions.- Returns:
An array of distances from the center of the shape to its surface at each of the given angles.
- Return type:
\((N,)\)
numpy.ndarray
- property eccentricity#
The eccentricity.
An ellipse’s eccentricity is defined as \(e = \sqrt{1 - \frac{b^2}{a^2}}\) where \(b\) is the length of the smaller semi-axis and \(a\) is the length of the larger semi-axis.
- Type:
- property gsd_shape_spec#
Get a complete GSD specification.
- Type:
- property inertia_tensor#
Get the inertia tensor.
For non-orientable 2D shapes, the inertia tensor can be trivially constructed from the polar moment of inertia. This calculation assumes that the shape lies in the \(xy\)-plane. Shapes that can be rotated relative to this plane must define their own methods.
- Type:
\((3, 3)\)
numpy.ndarray
- is_inside(points)#
Determine whether a set of points are contained in this ellipse.
Note
Points on the boundary of the shape will return
True
.- Parameters:
points (\((N, 3)\)
numpy.ndarray
) – The points to test.- Returns:
Boolean array indicating which points are contained in the ellipsoid.
- Return type:
\((N, )\)
numpy.ndarray
Example
>>> ellipse = coxeter.shapes.Ellipse(1.0, 2.0) >>> ellipse.is_inside([[0, 0, 0], [100, 1, 1]]) array([ True, False])
- property maximal_bounded_circle_radius#
Get or set the radius of the maximal bounded circle.
See
maximal_bounded_circle()
for more information.- Type:
- property maximal_centered_bounded_circle_radius#
Get or set the radius of the maximal centered bounded circle.
See
maximal_centered_bounded_circle()
for more information.- Type:
- property minimal_bounding_circle_radius#
Get or set the radius of the minimal bounding circle.
See
minimal_bounding_circle()
for more information.- Type:
- property minimal_centered_bounding_circle#
Get the smallest bounding concentric circle.
- Type:
- property minimal_centered_bounding_circle_radius#
Get or set the radius of the minimal centered bounding circle.
See
minimal_centered_bounding_circle()
for more information.- Type:
- property planar_moments_inertia#
Get the planar and product moments of inertia.
Moments are computed with respect to the \(x\) and \(y\) axes. In addition to the two planar moments, this property also provides the product of inertia.
The planar moments and the product of inertia are defined by the formulas:
\[\begin{split}\begin{align} I_x &= {\int \int}_A y^2 dA = \frac{\pi}{4} a b^3 = \frac{Ab^2}{4} \\ I_y &= {\int \int}_A x^2 dA = \frac{\pi}{4} a^3 b = \frac{Aa^2}{4} \\ I_{xy} &= {\int \int}_A xy dA = 0 \\ \end{align}\end{split}\]These formulas are given here. Note that the product moment is zero by symmetry.
- plot()#
Plot the shape.
- property polar_moment_inertia#
Get the polar moment of inertia.
The polar moment of inertia is always calculated about an axis perpendicular to the shape (i.e. the normal vector).
The polar moment is computed as the sum of the two planar moments of inertia.
- Type:
- to_plato_scene(backend='matplotlib', scene=None, scene_kwargs=None)#
Add this shape to a new or existing
plato.draw.Scene
.The plato visualization package provides support for several backends, including matplotlib, fresnel, povray, pythreejs, and vispy. The backend package must be separately installed by the user. Each backend supports different primitives (geometry objects) and may not support the primitive corresponding to a specific shape class in coxeter. Please refer to the plato documentation for more information about supported primitives for each backend.
- Parameters:
backend (str) – Name of backend to use from plato. The backend must support the primitive corresponding to this shape (Default value:
"matplotlib"
). Supported values include"matplotlib"
,"fresnel"
,"povray"
,"pythreejs"
,"vispy"
, and"zdog"
. See plato documentation for more information about each backend.scene (
plato.draw.Scene
) – Scene object to render into. If not provided or None, a new scene is created (Default value: None).scene_kwargs (dict) – Keyword arguments forwarded to the
plato.draw.Scene
(Default value: None). Only used ifscene
is not provided or None.
- Returns:
A scene containing this shape.
- Return type:
- Raises:
NotImplementedError: – If no plato primitive corresponds to this coxeter shape class.
AttributeError: – If the selected plato backend does not support the primitive for this coxeter shape class.
- class coxeter.shapes.Ellipsoid(a, b, c, center=(0, 0, 0))#
Bases:
Shape3D
An ellipsoid with principal axes a, b, and c.
- Parameters:
a (float) – Length of the principal semi-axis of the ellipsoid in the \(x\) direction.
b (float) – Length of the principal semi-axis of the ellipsoid in the \(y\) direction.
c (float) – Length of the principal semi-axis of the ellipsoid in the \(z\) direction.
center (Sequence[float]) – The coordinates of the centroid of the ellipsoid (Default value: (0, 0, 0)).
Example
>>> ellipsoid = coxeter.shapes.Ellipsoid(1.0, 3.0, 2.0) >>> ellipsoid.a 1.0 >>> ellipsoid.b 3.0 >>> ellipsoid.c 2.0 >>> ellipsoid.centroid array([0, 0, 0]) >>> ellipsoid.gsd_shape_spec {'type': 'Ellipsoid', 'a': 1.0, 'b': 3.0, 'c': 2.0} >>> ellipsoid.inertia_tensor array([[65.34512..., 0. , 0. ], [ 0. , 25.13274..., 0. ], [ 0. , 0. , 50.26548...]]) >>> ellipsoid.iq 0.61161... >>> ellipsoid.surface_area 48.88214... >>> ellipsoid.volume 25.13274...
Attributes:
Get or set the length of principal axis a (the \(x\) radius).
Get or set the length of principal axis b (the \(y\) radius).
Get or set the length of principal axis c (the \(z\) radius).
Alias for
centroid
.Get or set the centroid of the shape.
Get a complete GSD specification.
Get the inertia tensor.
The isoperimetric quotient.
Get the largest bounded sphere.
Get or set the radius of the maximal bounded sphere.
Get the largest bounded concentric sphere.
Get or set the radius of the maximal centered bounded sphere.
Get the smallest bounding sphere.
Get or set the radius of the minimal bounding sphere.
Get the smallest bounding concentric sphere.
Get or set the radius of the minimal concentric bounding sphere.
Get the surface area.
Get or set the volume.
Methods:
Calculate the form factor intensity.
distance_to_surface
(angles)Compute the distance to the surface of the shape at the given angles.
is_inside
(points)Determine whether a set of points are contained in this ellipsoid.
plot
()Plot the shape.
to_hoomd
()Get a JSON-serializable subset of Ellipsoid properties.
to_json
(attributes)Get a JSON-serializable subset of shape properties.
to_plato_scene
([backend, scene, scene_kwargs])Add this shape to a new or existing
plato.draw.Scene
.- property center#
Alias for
centroid
.- Type:
\((3, )\)
numpy.ndarray
of float
- property centroid#
Get or set the centroid of the shape.
- Type:
\((3, )\)
numpy.ndarray
of float
- compute_form_factor_amplitude(q)#
Calculate the form factor intensity.
In solid state physics, scattering theory is concerned with understanding the ways in which radiation is scattered from a sample. For a single point particle at position P, the the amplitude of a scattered wave observed at position Q is the product of the incoming wave amplitude (which follows the standard equation for a traveling wave) and the scattering density at P. For a crystal composed of many point particles, the intensity of the resulting superposition of waves can be identified as the Fourier transform of the total scattering density. When the particles are not point particles, the scattering density of the particles in their local coordinate systems are no longer identical. Conveniently, this component is separable in the Fourier transform of the total density; as a result, the scattering scattering intensity can be decomposed into two terms, the Fourier transform of the distribution of scatterers and the Fourier transform of each scatterer in its local coordinate system. The first term is known as the static structure factor \(S(\vec{q})\) and describes the spatial distribution of scatterers, while the second term is called the form factor \(f(\vec{q})\) and describes the local scattering profile.
While the form factor (the scattering intensity) can be measured from diffraction experiments, the Fourier transform of a single particle cannot. However, it can be computed theoretically for a known scattering volume and can be inserted directly into the expression for the total scattering intensity. This local profile directly describes the wave emitted from a single scatterer (in reciprocal space) and is known as the form factor amplitude. This function computes the form factor amplitude for a given wavevector \(q\).
- distance_to_surface(angles)#
Compute the distance to the surface of the shape at the given angles.
Gets the distance to the surface at each of the angles provided, where the definition of the angles depends on the dimensionality of the shape (a single angle in 2D, or the phi/theta angles in 3D). All angles are relative to the x axis. In general, the distance is computed from the centroid of the shape unless stated otherwise.
- Parameters:
angles (\((N, d-1)\)
numpy.ndarray
) – Angles between \(0\) and \(2 \pi\) over which to calculate the distances. \(d\) is the number of dimensions.- Returns:
An array of distances from the center of the shape to its surface at each of the given angles.
- Return type:
\((N,)\)
numpy.ndarray
- property gsd_shape_spec#
Get a complete GSD specification.
- Type:
- property inertia_tensor#
Get the inertia tensor.
Assumes a constant density of 1.
- Type:
\((3, 3)\)
numpy.ndarray
- property iq#
The isoperimetric quotient.
The isoperimetric quotient is the ratio of the volume of a shape to the volume of a sphere with the same perimeter. Given a shape of volume \(A\) and surface \(S\), the sphere with the same surface has radius \(r_S = \sqrt{\frac{S}{4\pi}}\) and therefore has volume \(V_{sphere} = \frac{4}{3} \pi r_S^3 = \frac{S^{3/2}}{\sqrt{4\pi}}\). Taking the ratio of volumes gives:
\[\begin{equation} \frac{V}{V_{sphere}} = \frac{6\sqrt{\pi} V}{S^{3/2}} \end{equation}\]To avoid inconvenient fractional exponents, the isoperimetric quotient is conventionally defined as the square of this quantity:
\[\begin{split}\begin{align} IQ &= \left(\frac{V}{V_{sphere}}\right)^2 \\ &= \frac{36\pi V^2}{S^3} \end{align}\end{split}\]- Type:
- is_inside(points)#
Determine whether a set of points are contained in this ellipsoid.
Note
Points on the boundary of the shape will return
True
.- Parameters:
points (\((N, 3)\)
numpy.ndarray
) – The points to test.- Returns:
Boolean array indicating which points are contained in the ellipsoid.
- Return type:
\((N, )\)
numpy.ndarray
Example
>>> ellipsoid = coxeter.shapes.Ellipsoid(1.0, 2.0, 3.0) >>> ellipsoid.is_inside([[0, 0, 0], [100, 1, 1]]) array([ True, False])
- property maximal_bounded_sphere_radius#
Get or set the radius of the maximal bounded sphere.
See
maximal_bounded_sphere()
for more information.- Type:
- property maximal_centered_bounded_sphere_radius#
Get or set the radius of the maximal centered bounded sphere.
See
maximal_centered_bounded_sphere()
for more information.- Type:
- property minimal_bounding_sphere_radius#
Get or set the radius of the minimal bounding sphere.
See
minimal_bounding_sphere()
for more information.- Type:
- property minimal_centered_bounding_sphere#
Get the smallest bounding concentric sphere.
- Type:
- property minimal_centered_bounding_sphere_radius#
Get or set the radius of the minimal concentric bounding sphere.
See
minimal_centered_bounding_sphere()
for more information.- Type:
- plot()#
Plot the shape.
- to_hoomd()#
Get a JSON-serializable subset of Ellipsoid properties.
The JSON-serializable output of the to_hoomd method can be directly imported into data management tools like signac. This data can then be queried for use in HOOMD simulations. Key naming matches HOOMD integrators: for example, the moment_inertia key links to data from coxeter’s inertia_tensor. Stored values are based on the shape with its centroid at the origin.
For an Ellipsoid, the following properties are stored:
- a (float):
half axis of ellipsoid in the x direction
- b (float):
half axis of ellipsoid in the y direction
- c (float):
half axis of ellipsoid in the z direction
- centroid (list(float))
The centroid of the shape. This is set to [0,0,0] per HOOMD’s spec.
- volume (float)
The volume of the shape.
- moment_inertia (list(list))
The shape’s inertia tensor.
- Returns:
Dict containing a subset of shape properties required for HOOMD function.
- Return type:
- to_plato_scene(backend='matplotlib', scene=None, scene_kwargs=None)#
Add this shape to a new or existing
plato.draw.Scene
.The plato visualization package provides support for several backends, including matplotlib, fresnel, povray, pythreejs, and vispy. The backend package must be separately installed by the user. Each backend supports different primitives (geometry objects) and may not support the primitive corresponding to a specific shape class in coxeter. Please refer to the plato documentation for more information about supported primitives for each backend.
- Parameters:
backend (str) – Name of backend to use from plato. The backend must support the primitive corresponding to this shape (Default value:
"matplotlib"
). Supported values include"matplotlib"
,"fresnel"
,"povray"
,"pythreejs"
,"vispy"
, and"zdog"
. See plato documentation for more information about each backend.scene (
plato.draw.Scene
) – Scene object to render into. If not provided or None, a new scene is created (Default value: None).scene_kwargs (dict) – Keyword arguments forwarded to the
plato.draw.Scene
(Default value: None). Only used ifscene
is not provided or None.
- Returns:
A scene containing this shape.
- Return type:
- Raises:
NotImplementedError: – If no plato primitive corresponds to this coxeter shape class.
AttributeError: – If the selected plato backend does not support the primitive for this coxeter shape class.
- class coxeter.shapes.Polygon(vertices, normal=None, planar_tolerance=1e-05, test_simple=True)#
Bases:
Shape2D
A simple (non-self-overlapping) polygon.
The polygon is embedded in 3-dimensions, so the normal vector determines which way is “up”.
Note
This class is designed for polygons without self-intersections, so the internal sorting will automatically result in such intersections being removed.
- Parameters:
vertices (\((N, 3)\) or \((N, 2)\)
numpy.ndarray
) – The vertices of the polygon.normal (sequence of length 3 or None) – The normal vector to the polygon. If
None
, the normal is computed by taking the cross product of the vectors formed by the first three verticesnp.cross(vertices[2, :] - vertices[1, :], vertices[0, :] - vertices[1, :])
. This choice is made so that if the provided vertices are in the \(xy\) plane and are specified in counterclockwise order, the resulting normal is the \(z\) axis. Since this arbitrary choice may not preserve the orientation of the provided vertices, users may provide a normal instead (Default value: None).planar_tolerance (float) – The tolerance to use to verify that the vertices are planar. Providing this argument may be necessary if you have a large number of vertices and are rotated significantly out of the plane.
test_simple (bool) – If
True
, perform a sanity check on construction that the provided vertices constitute a simple polygon. If this check is omitted, the class may produce invalid results if the user inputs incorrect coordinates, so this flag should be set toFalse
with care.
Example
>>> triangle = coxeter.shapes.Polygon([[-1, 0], [0, 1], [1, 0]]) >>> import numpy as np >>> assert np.isclose(triangle.area, 1.0) >>> bounding_circle = triangle.minimal_bounding_circle >>> assert np.isclose(bounding_circle.radius, 1.0) >>> assert np.allclose(triangle.center, [0., 1. / 3., 0.]) >>> circumcircle = triangle.circumcircle >>> assert np.isclose(circumcircle.radius, 1.0) >>> triangle.gsd_shape_spec {'type': 'Polygon', 'vertices': [[-1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [1.0, 0.0, 0.0]]} >>> assert np.allclose( ... triangle.inertia_tensor, ... np.diag([1. / 9., 0., 1. / 3.])) >>> triangle.normal array([ 0., -0., -1.]) >>> assert np.allclose( ... triangle.planar_moments_inertia, ... (1. / 6., 1. / 6., 0.)) >>> assert np.isclose(triangle.polar_moment_inertia, 1. / 3.) >>> assert np.isclose(triangle.signed_area, 1.0)
Attributes:
Get or set the polygon's area.
Get the minimal bounding circle.
Alias for
centroid
.Get or set the centroid of the shape.
Get the polygon's circumcircle.
Get the radius of the polygon's circumcircle.
Get a complete GSD specification.
Get the polygon's incircle.
Get the radius of the polygon's incircle.
Get the inertia tensor.
The isoperimetric quotient.
Get the largest bounded circle.
Get or set the radius of the maximal bounded circle.
Get the largest concentric bounded circle.
Get or set the radius of the maximal centered bounded circle.
Get the minimal bounding circle.
Get or set the radius of the minimal bounding circle.
Get the smallest bounding concentric circle.
Get or set the radius of the minimal centered bounding circle.
Get the normal vector.
Get the number of vertices.
Get the perimeter of the polygon.
Get the planar and product moments of inertia.
Get the polar moment of inertia.
Get the polygon's area.
Get the vertices of the polygon.
Methods:
compute_form_factor_amplitude
(q[, density])Calculate the form factor intensity.
distance_to_surface
(angles)Compute the distance to the surface of the shape at the given angles.
is_inside
(points)Implement a simple point-in-polygon algorithm based on winding number.
plot
([ax, center, plot_verts, label_verts])Plot the polygon.
to_hoomd
()Get a JSON-serializable subset of Polygon properties.
to_json
(attributes)Get a JSON-serializable subset of shape properties.
to_plato_scene
([backend, scene, scene_kwargs])Add this shape to a new or existing
plato.draw.Scene
.- property area#
Get or set the polygon’s area.
To get the area, we simply compute the signed area and take the absolute value.
- Type:
- property center#
Alias for
centroid
.- Type:
\((3, )\)
numpy.ndarray
of float
- property centroid#
Get or set the centroid of the shape.
The centroid of a polygon is calculated according to this formula.
- Type:
\((3, )\)
numpy.ndarray
of float
- property circumcircle#
Get the polygon’s circumcircle.
A circumcircle must touch all the points of the polygon. A circumcircle exists if and only if there is a point equidistant from all the vertices. The circumcircle is found by finding the least squares solution of the overdetermined system of linear equations defined by this constraint, and the circumcircle only exists if the resulting solution has no residual.
- Raises:
RuntimeError – If no circumcircle exists for this polygon.:
- Type:
- compute_form_factor_amplitude(q, density=1.0)#
Calculate the form factor intensity.
The form factor amplitude of a polygon is computed according to the derivation provided in this dissertation: https://deepblue.lib.umich.edu/handle/2027.42/120906. The Kelvin-Stokes theorem allows reducing the surface integral to a line integral around the boundary.
For more generic information about form factors, see
Shape.compute_form_factor_amplitude
.
- distance_to_surface(angles)#
Compute the distance to the surface of the shape at the given angles.
Gets the distance to the surface at each of the angles provided, where the definition of the angles depends on the dimensionality of the shape (a single angle in 2D, or the phi/theta angles in 3D). All angles are relative to the x axis. In general, the distance is computed from the centroid of the shape unless stated otherwise.
- Parameters:
angles (\((N, d-1)\)
numpy.ndarray
) – Angles between \(0\) and \(2 \pi\) over which to calculate the distances. \(d\) is the number of dimensions.- Returns:
An array of distances from the center of the shape to its surface at each of the given angles.
- Return type:
\((N,)\)
numpy.ndarray
- property gsd_shape_spec#
Get a complete GSD specification.
- Type:
- property incircle#
Get the polygon’s incircle.
Note
The incircle of a polygon is defined as the circle contained within the polygon that is tangent to all its faces. This condition uniquely defines the circle, if it exists. The set of equations defined by this equation is solved using a least squares approach, with the magnitude of the residual used to determine whether or not the incircle exists.
- Type:
- property inertia_tensor#
Get the inertia tensor.
The inertia tensor is computed for the polygon embedded in \(\mathbb{R}^3\). This computation proceeds by first computing the polar moment of inertia for the polygon in the \(xy\)-plane relative to its centroid. The tensor is then rotated back to the orientation of the polygon and shifted to the original centroid.
- Type:
\((3, 3)\)
numpy.ndarray
- property iq#
The isoperimetric quotient.
The isoperimetric quotient is the ratio of the area of a shape to the area of a circle with the same perimeter. Given a shape of area \(A\) and perimeter \(p\), the circle with the same perimeter has radius \(r_p = \frac{p}{2\pi}\) and therefore has an area \(A_{circle} = \pi r_p^2 = \frac{p^2}{4\pi}\). Therefore, we have that:
\[\begin{split}\begin{align} IQ &= \frac{A}{A_{circle}} \\ &= \frac{4\pi A}{p^2} \end{align}\end{split}\]- Type:
- is_inside(points)#
Implement a simple point-in-polygon algorithm based on winding number.
The code in this function is based on implementation in [Dic19] which is licensed under the BSD-3 license.
Given a closed, possibly non-simple polygon described as a list of vertices in \(\mathbb{R}^2\) and a point that doesn’t lie directly on the path of the polygon, we’d like to compute the winding number of the polygon around the point. To achieve this, we place the point at the origin. Divide the remainder of the plane (i.e., \(\mathbb{R}^2\) minus the origin) into two halves, \(L\) and \(R\), defined as follows:
\[ \begin{align}\begin{aligned}L = {(x, y) | x < 0 \lor x = 0 \land y < 0}\\R = {(x, y) | x > 0 \lor x = 0 \land y > 0}\end{aligned}\end{align} \]That is, \(R\) contains all points with argument in the half-closed interval \(\left[-\frac{\pi}{2},\frac{\pi}{2}\right)\), and \(L\) contains all others. Note that with these definitions, \(L\) and \(R\) are both convex: a line segment between two points in \(R\) lies entirely in \(R\), and similarly for \(L\). In particular, a line segment between two points can only pass through the origin if one of those points is in \(L\) and the other in \(R\). Now, we follow the edges of the polygon, keeping track of how many times we move between \(L\) and \(R\). For each move from \(L\) to \(R\) (or vice versa), we also need to compute whether the edge passes above or below the origin, to compute its contribution to the total winding number. From the comment above, we can safely ignore all edges that lie entirely within either \(L\) or \(R\).
Note
Points on the boundary of the shape will return
False
.- Parameters:
points (\((N, 3)\) or \((N, 2)\)
numpy.ndarray
) – The points to test.- Returns:
Boolean array indicating which points are contained in the polyhedron.
- Return type:
\((N, )\)
numpy.ndarray
- property maximal_bounded_circle#
Get the largest bounded circle.
The largest circle contained in a shape is referred to by a range of ambiguous names. To avoid conflicts with the most common naming choices of other properties in the literature (particularly the
incircle
of a polygon), this property is named as an explicit analog tominimal_bounding_circle
.- Type:
- property maximal_bounded_circle_radius#
Get or set the radius of the maximal bounded circle.
See
maximal_bounded_circle()
for more information.- Type:
- property maximal_centered_bounded_circle#
Get the largest concentric bounded circle.
This property gives the largest circle that fits in the shape whose center also coincides with the center of the shape.
- Type:
- property maximal_centered_bounded_circle_radius#
Get or set the radius of the maximal centered bounded circle.
See
maximal_centered_bounded_circle()
for more information.- Type:
- property minimal_bounding_circle_radius#
Get or set the radius of the minimal bounding circle.
See
minimal_bounding_circle()
for more information.- Type:
- property minimal_centered_bounding_circle#
Get the smallest bounding concentric circle.
This property gives the smallest bounding circle whose center coincides with the center of the shape.
- Type:
- property minimal_centered_bounding_circle_radius#
Get or set the radius of the minimal centered bounding circle.
See
minimal_centered_bounding_circle()
for more information.- Type:
- property normal#
Get the normal vector.
- Type:
\((3, )\)
numpy.ndarray
of float
- property planar_moments_inertia#
Get the planar and product moments of inertia.
Moments are computed with respect to the \(x\) and \(y\) axes. In addition to the two planar moments, this property also provides the product of inertia.
The planar moments and the product of inertia are defined by the formulas:
\[\begin{split}\begin{align} I_x &= {\int \int}_A y^2 dA \\ I_y &= {\int \int}_A x^2 dA \\ I_{xy} &= {\int \int}_A xy dA \\ \end{align}\end{split}\]To compute this for a polygon, we discretize the sum:
\[\begin{split}\begin{align} I_x &= \frac{1}{12} \sum_{i=1}^N (x_i y_{i+1} - x_{i+1} y_i) (y_i^2 + y_i*y_{i+1} + y_{i+1}^2) \\ I_y &= \frac{1}{12} \sum_{i=1}^N (x_i y_{i+1} - x_{i+1} y_i) (x_i^2 + x_i*x_{i+1} + x_{i+1}^2) \\ I_{xy} &= \frac{1}{12} \sum_{i=1}^N (x_i y_{i+1} - x_{i+1} y_i) (x_i y_{i+1} + 2 x_i y_i + 2 x_{i+1} y_{i+1} + x_{i+1} y_i) \\ \end{align}\end{split}\]These formulas can be derived as described here.
Note that the moments are always calculated about an axis perpendicular to the polygon, i.e. the normal vector is aligned with the \(z\) axis before the moments are calculated. This alignment should be considered when computing the moments for polygons embedded in three-dimensional space that are rotated out of the \(xy\) plane, since the planar moments are invariant to this orientation. The exact rotation used for this computation (i.e. changes in the \(x\) and \(y\) position) should not be relied upon.
- plot(ax=None, center=False, plot_verts=False, label_verts=False)#
Plot the polygon.
Note that the polygon is always rotated into the \(xy\) plane and plotted in two dimensions.
- Parameters:
ax (
matplotlib.axes.Axes
) – The axes on which to draw the polygon. Axes will be created if this is None (Default value: None).center (bool) – If True, the polygon vertices are plotted relative to its center (Default value: False).
plot_verts (bool) – If True, scatter points will be added at the vertices (Default value: False).
label_verts (bool) – If True, vertex indices will be added next to the vertices (Default value: False).
- property polar_moment_inertia#
Get the polar moment of inertia.
The polar moment of inertia is always calculated about an axis perpendicular to the shape (i.e. the normal vector).
The polar moment is computed as the sum of the two planar moments of inertia.
- Type:
- property signed_area#
Get the polygon’s area.
To support polygons embedded in 3 dimensional space, we employ a projection- and rescaling-based algorithm described here. Specifically, the polygon is projected onto the plane it is “most parallel” to, the area of the projected polygon is computed, then the area is rescaled by the component of the normal in the projected dimension.
- Type:
- to_hoomd()#
Get a JSON-serializable subset of Polygon properties.
The JSON-serializable output of the to_hoomd method can be directly imported into data management tools like signac. This data can then be queried for use in HOOMD simulations. Key naming matches HOOMD integrators: for example, the moment_inertia key links to data from coxeter’s inertia_tensor. Stored values are based on the shape with its centroid at the origin.
For a Polygon or ConvexPolygon, the following properties are stored:
- vertices (list(list)):
The vertices of the shape.
- centroid (list(float))
The centroid of the shape. This is set to [0,0,0] per HOOMD’s spec.
- sweep_radius (float):
The rounding radius of the shape (0.0).
- area (float)
The area of the shape.
- moment_inertia (list(list))
The shape’s inertia tensor.
- Returns:
Dict containing a subset of shape properties required for HOOMD function.
- Return type:
- to_plato_scene(backend='matplotlib', scene=None, scene_kwargs=None)#
Add this shape to a new or existing
plato.draw.Scene
.The plato visualization package provides support for several backends, including matplotlib, fresnel, povray, pythreejs, and vispy. The backend package must be separately installed by the user. Each backend supports different primitives (geometry objects) and may not support the primitive corresponding to a specific shape class in coxeter. Please refer to the plato documentation for more information about supported primitives for each backend.
- Parameters:
backend (str) – Name of backend to use from plato. The backend must support the primitive corresponding to this shape (Default value:
"matplotlib"
). Supported values include"matplotlib"
,"fresnel"
,"povray"
,"pythreejs"
,"vispy"
, and"zdog"
. See plato documentation for more information about each backend.scene (
plato.draw.Scene
) – Scene object to render into. If not provided or None, a new scene is created (Default value: None).scene_kwargs (dict) – Keyword arguments forwarded to the
plato.draw.Scene
(Default value: None). Only used ifscene
is not provided or None.
- Returns:
A scene containing this shape.
- Return type:
- Raises:
NotImplementedError: – If no plato primitive corresponds to this coxeter shape class.
AttributeError: – If the selected plato backend does not support the primitive for this coxeter shape class.
- property vertices#
Get the vertices of the polygon.
- Type:
\((N_{verts}, 3)\)
numpy.ndarray
of float
- class coxeter.shapes.Polyhedron(vertices, faces, faces_are_convex=None)#
Bases:
Shape3D
A three-dimensional polytope.
A polyhedron is defined by a set of vertices and a set of faces composed of the vertices. On construction, the faces are reordered counterclockwise with respect to an outward normal. The polyhedron provides various standard geometric calculations, such as volume and surface area. Most features of the polyhedron can be accessed via properties, including the plane equations defining the faces and the neighbors of each face.
Note
For the purposes of calculations like moments of inertia, the polyhedron is assumed to be of constant, unit density.
- Parameters:
vertices (\((N, 3)\)
numpy.ndarray
) – The vertices of the polyhedron.faces_are_convex (bool, optional) – Whether or not the faces of the polyhedron are all convex. This is used to determine whether certain operations like coplanar face merging are allowed (Default value: False).
Example
>>> cube = coxeter.shapes.ConvexPolyhedron( ... [[-1, -1, -1], [-1, -1, 1], [-1, 1, -1], [-1, 1, 1], ... [1, -1, -1], [1, -1, 1], [1, 1, -1], [1, 1, 1]]) >>> cube = coxeter.shapes.Polyhedron( ... vertices=cube.vertices, faces=cube.faces) >>> bounding_sphere = cube.minimal_bounding_sphere >>> import numpy as np >>> assert np.isclose(bounding_sphere.radius, np.sqrt(3)) >>> cube.center array([0., 0., 0.]) >>> cube.faces [array([0, 2, 6, 4], dtype=int32), array([0, 4, 5, 1], dtype=int32), array([4, 6, 7, 5], dtype=int32), array([0, 1, 3, 2], dtype=int32), array([2, 3, 7, 6], dtype=int32), array([1, 5, 7, 3], dtype=int32)] >>> cube.gsd_shape_spec {'type': 'Mesh', 'vertices': [[-1.0, -1.0, -1.0], [-1.0, -1.0, 1.0], [-1.0, 1.0, -1.0], [-1.0, 1.0, 1.0], [1.0, -1.0, -1.0], [1.0, -1.0, 1.0], [1.0, 1.0, -1.0], [1.0, 1.0, 1.0]], 'indices': [array([0, 2, 6, 4], dtype=int32), array([0, 4, 5, 1], dtype=int32), array([4, 6, 7, 5], dtype=int32), array([0, 1, 3, 2], dtype=int32), array([2, 3, 7, 6], dtype=int32), array([1, 5, 7, 3], dtype=int32)]} >>> assert np.allclose( ... cube.inertia_tensor, ... np.diag([16. / 3., 16. / 3., 16. / 3.])) >>> assert np.isclose(cube.iq, np.pi / 6.) >>> cube.neighbors [array([1, 2, 3, 4]), array([0, 2, 3, 5]), array([0, 1, 4, 5]), array([0, 1, 4, 5]), array([0, 2, 3, 5]), array([1, 2, 3, 4])] >>> cube.normals array([[ 0., 0., -1.], [ 0., -1., 0.], [ 1., 0., -0.], [-1., 0., 0.], [-0., 1., 0.], [ 0., -0., 1.]]) >>> cube.num_faces 6 >>> cube.num_vertices 8 >>> assert np.isclose(cube.surface_area, 24.0) >>> cube.vertices array([[-1., -1., -1.], [-1., -1., 1.], [-1., 1., -1.], [-1., 1., 1.], [ 1., -1., -1.], [ 1., -1., 1.], [ 1., 1., -1.], [ 1., 1., 1.]]) >>> assert np.isclose(cube.volume, 8.0)
Attributes:
Get the polyhedron's bounding sphere.
Alias for
centroid
.Get or set the centroid of the shape.
Get the polyhedron's circumsphere.
Get the radius of the polygon's circumsphere.
Get the length of each edge of the polyhedron.
Get the polyhedron's edges as vectors.
Get the polyhedron's edges.
Get the polyhedron's faces.
Get a complete GSD specification.
Get the inertia tensor.
Get the polyhedron's insphere.
Get the radius of the polygon's insphere.
The isoperimetric quotient.
Get the largest bounded sphere.
Get or set the radius of the maximal bounded sphere.
Get the largest concentric bounded sphere.
Get or set the radius of the maximal centered bounded sphere.
Get the polyhedron's bounding sphere.
Get or set the radius of the minimal bounding sphere.
Get a bounding sphere sharing the center of this shape.
Get or set the radius of the minimal concentric bounding sphere.
Get neighboring pairs of faces.
Get the face normals.
Get the number of edges.
Get the number of faces.
Get the number of vertices.
Get the surface area.
Get the vertices of the polyhedron.
Get or set the polyhedron's volume.
Methods:
compute_form_factor_amplitude
(q[, density])Calculate the form factor intensity.
Orient the shape along its principal axes.
distance_to_surface
(angles)Compute the distance to the surface of the shape at the given angles.
get_dihedral
(a, b)Get the dihedral angle between a pair of faces.
get_face_area
([faces])Get the total surface area of a set of faces.
is_inside
(points)Determine whether points are contained in this polyhedron.
merge_faces
([atol, rtol])Merge coplanar faces to a given tolerance.
plot
([ax, plot_verts, label_verts])Plot the polyhedron.
Sort faces of the polyhedron.
to_hoomd
()Get a JSON-serializable subset of Polyhedron properties.
to_json
(attributes)Get a JSON-serializable subset of shape properties.
to_plato_scene
([backend, scene, scene_kwargs])Add this shape to a new or existing
plato.draw.Scene
.- property center#
Alias for
centroid
.- Type:
\((3, )\)
numpy.ndarray
of float
- property centroid#
Get or set the centroid of the shape.
The centroid is computed using the algorithm described in [Ebe02].
- Type:
\((3, )\)
numpy.ndarray
of float
- property circumsphere#
Get the polyhedron’s circumsphere.
A circumsphere must touch all the points of the polyhedron. A circumsphere exists if and only if there is a point equidistant from all the vertices. The circumsphere is found by finding the least squares solution of the overdetermined system of linear equations defined by this constraint, and the circumsphere only exists if the resulting solution has no residual.
- Raises:
RuntimeError – If no circumsphere exists for this polyhedron.:
- Type:
- compute_form_factor_amplitude(q, density=1.0)#
Calculate the form factor intensity.
The form factor amplitude of a polyhedron is computed according to the derivation provided in this dissertation: https://deepblue.lib.umich.edu/handle/2027.42/120906. In brief, two applications of Stokes theorem (or to use the names more familiar from elementary vector calculus, the application of the divergence theorem followed by the classic Kelvin-Stokes theorem) are used to reduce the volume integral over a polyhedron into a series of line integrals around the boundaries of each polygonal face.
For more generic information about form factors, see
Shape.compute_form_factor_amplitude
.
- diagonalize_inertia()#
Orient the shape along its principal axes.
The principal axes of a shape are defined by the eigenvectors of the inertia tensor. This method computes the inertia tensor of the shape, diagonalizes it, and then rotates the shape by the corresponding orthogonal transformation.
Example
>>> cube = coxeter.shapes.ConvexPolyhedron( ... [[1, 1, 1], [1, -1, 1], [1, 1, -1], [1, -1, -1], ... [-1, 1, 1], [-1, -1, 1], [-1, 1, -1], [-1, -1, -1]]) >>> cube = coxeter.shapes.Polyhedron( ... vertices=cube.vertices, faces=cube.faces) >>> cube.diagonalize_inertia() >>> cube.vertices array([[ 1., 1., 1.], [ 1., -1., 1.], [ 1., 1., -1.], [ 1., -1., -1.], [-1., 1., 1.], [-1., -1., 1.], [-1., 1., -1.], [-1., -1., -1.]])
- distance_to_surface(angles)#
Compute the distance to the surface of the shape at the given angles.
Gets the distance to the surface at each of the angles provided, where the definition of the angles depends on the dimensionality of the shape (a single angle in 2D, or the phi/theta angles in 3D). All angles are relative to the x axis. In general, the distance is computed from the centroid of the shape unless stated otherwise.
- Parameters:
angles (\((N, d-1)\)
numpy.ndarray
) – Angles between \(0\) and \(2 \pi\) over which to calculate the distances. \(d\) is the number of dimensions.- Returns:
An array of distances from the center of the shape to its surface at each of the given angles.
- Return type:
\((N,)\)
numpy.ndarray
- property edge_lengths#
Get the length of each edge of the polyhedron.
edge_lengths
are returned in the same order as inedges
.- Type:
- property edge_vectors#
Get the polyhedron’s edges as vectors.
edge_vectors
are returned in the same order as inedges
.- Type:
- property edges#
Get the polyhedron’s edges.
Results returned as vertex index pairs, with each edge of the polyhedron included exactly once. Edge (i,j) pairs are ordered by vertex index with i<j.
- Type:
- property faces#
Get the polyhedron’s faces.
Results returned as vertex index lists.
- Type:
list(
numpy.ndarray
)
- get_dihedral(a, b)#
Get the dihedral angle between a pair of faces.
The dihedral is computed from the dot product of the face normals.
- Parameters:
- Returns:
float
- Return type:
The dihedral angle in radians.
Example
>>> cube = coxeter.shapes.ConvexPolyhedron( ... [[1, 1, 1], [1, -1, 1], [1, 1, -1], [1, -1, -1], ... [-1, 1, 1], [-1, -1, 1], [-1, 1, -1], [-1, -1, -1]]) >>> cube = coxeter.shapes.Polyhedron( ... vertices=cube.vertices, faces=cube.faces) >>> import numpy as np >>> assert np.isclose(cube.get_dihedral(1, 2), np.pi / 2.)
- get_face_area(faces=None)#
Get the total surface area of a set of faces.
- Parameters:
faces (int, sequence, or None) – The index of a face or a set of face indices for which to find the area. If None, finds the area of all faces (Default value: None).
- Returns:
:class:`numpy.ndarray`
- Return type:
The area of each face.
Example
>>> cube = coxeter.shapes.ConvexPolyhedron( ... [[1, 1, 1], [1, -1, 1], [1, 1, -1], [1, -1, -1], ... [-1, 1, 1], [-1, -1, 1], [-1, 1, -1], [-1, -1, -1]]) >>> cube = coxeter.shapes.Polyhedron( ... vertices=cube.vertices,faces=cube.faces) >>> import numpy as np >>> assert np.allclose( ... cube.get_face_area([1, 2, 3]), ... [4., 4., 4.])
- property gsd_shape_spec#
Get a complete GSD specification.
- Type:
- property inertia_tensor#
Get the inertia tensor.
The inertia tensor is computed using the algorithm described in [Kal06].
Note
For improved stability, the inertia tensor is computed about the center of mass and then shifted rather than directly computed in the global frame.
- Type:
\((3, 3)\)
numpy.ndarray
- property insphere#
Get the polyhedron’s insphere.
Note
The insphere of a polyhedron is defined as the sphere contained within the polyhedron that is tangent to all its faces. This condition uniquely defines the sphere, if it exists. The set of equations defined by this equation is solved using a least squares approach, with the magnitude of the residual used to determine whether or not the insphere exists.
- Type:
- property iq#
The isoperimetric quotient.
The isoperimetric quotient is the ratio of the volume of a shape to the volume of a sphere with the same perimeter. Given a shape of volume \(A\) and surface \(S\), the sphere with the same surface has radius \(r_S = \sqrt{\frac{S}{4\pi}}\) and therefore has volume \(V_{sphere} = \frac{4}{3} \pi r_S^3 = \frac{S^{3/2}}{\sqrt{4\pi}}\). Taking the ratio of volumes gives:
\[\begin{equation} \frac{V}{V_{sphere}} = \frac{6\sqrt{\pi} V}{S^{3/2}} \end{equation}\]To avoid inconvenient fractional exponents, the isoperimetric quotient is conventionally defined as the square of this quantity:
\[\begin{split}\begin{align} IQ &= \left(\frac{V}{V_{sphere}}\right)^2 \\ &= \frac{36\pi V^2}{S^3} \end{align}\end{split}\]- Type:
- is_inside(points)#
Determine whether points are contained in this polyhedron.
The code in this function is based on implementation in [Dic19] which is licensed under the BSD-3 license. The computation is based on calculation of winding number.
Note
Points on the boundary of the shape will return
False
.- Parameters:
points (\((N, 3)\)
numpy.ndarray
) – The points to test.- Returns:
Boolean array indicating which points are contained in the polyhedron.
- Return type:
\((N, )\)
numpy.ndarray
- property maximal_bounded_sphere#
Get the largest bounded sphere.
The largest sphere contained in a shape is referred to by a range of ambiguous names. To avoid conflicts with the most common naming choices of other properties in the literature (particularly the
insphere
of a polyhedron), this property is named as an explicit analog tominimal_bounding_sphere
.- Type:
- property maximal_bounded_sphere_radius#
Get or set the radius of the maximal bounded sphere.
See
maximal_bounded_sphere()
for more information.- Type:
- property maximal_centered_bounded_sphere#
Get the largest concentric bounded sphere.
This property gives the largest sphere that fits in the shape whose center also coincides with the center of the shape.
- Type:
- property maximal_centered_bounded_sphere_radius#
Get or set the radius of the maximal centered bounded sphere.
See
maximal_centered_bounded_sphere()
for more information.- Type:
- merge_faces(atol=1e-08, rtol=1e-05)#
Merge coplanar faces to a given tolerance.
Whether or not faces should be merged is determined using
numpy.allclose()
to compare the plane equations of neighboring faces. Connected components of mergeable faces are then merged into a single face. This method can be safely called many times with different tolerances, however, the operation is destructive in the sense that merged faces cannot be recovered. Users wishing to undo a merge to attempt a less expansive merge must build a new polyhedron.- Parameters:
atol (float) – Absolute tolerance for
numpy.allclose()
.rtol (float) – Relative tolerance for
numpy.allclose()
.
- property minimal_bounding_sphere_radius#
Get or set the radius of the minimal bounding sphere.
See
minimal_bounding_sphere()
for more information.- Type:
- property minimal_centered_bounding_sphere#
Get a bounding sphere sharing the center of this shape.
A bounding sphere of a collection of points in is a sphere containing all of the points. There are an infinite set of possible bounding spheres for a shape (since any sphere that entirely contains a bounding sphere is also a bounding sphere), so additional constraints must be imposed to define a unique sphere. This property provides the smallest bounding sphere of a shape whose center coincides with the center of the shape.
- Type:
- property minimal_centered_bounding_sphere_radius#
Get or set the radius of the minimal concentric bounding sphere.
See
minimal_centered_bounding_sphere()
for more information.- Type:
- property neighbors#
Get neighboring pairs of faces.
The neighbors are provided as a list where the \(i^{\text{th}}\) element is an array of indices of faces that are neighbors of face \(i\).
- Type:
list(
numpy.ndarray
)
- property normals#
Get the face normals.
- Type:
\((N, 3)\)
numpy.ndarray
- plot(ax=None, plot_verts=False, label_verts=False)#
Plot the polyhedron.
Note that the
ax
argument should be a 3D axes object; passing in a 2D axes object will result in wrong behavior.- Parameters:
ax (
mpl_toolkits.mplot3d.axes3d.Axes3D
) – The axes on which to draw the polyhedron. Axes will be created if this is None (Default value: None).plot_verts (bool) – If True, scatter points will be added at the vertices (Default value: False).
label_verts (bool) – If True, vertex indices will be added next to the vertices (Default value: False).
- sort_faces()#
Sort faces of the polyhedron.
This method ensures that all faces are ordered such that the normals are counterclockwise and point outwards. This algorithm proceeds in four steps. First, it ensures that each face is ordered in either clockwise or counterclockwise order such that edges can be found from the sequence of the vertices in each face. Next, it calls the neighbor finding routine to establish with faces are neighbors. Then, it performs a breadth-first search, reorienting faces to match the orientation of the first face. Finally, it computes the signed volume to determine whether or not all the normals need to be flipped.
Note
This method can only be called for polyhedra whose faces are all convex (i.e. constructed with
faces_are_convex=True
).
- to_hoomd()#
Get a JSON-serializable subset of Polyhedron properties.
The JSON-serializable output of the to_hoomd method can be directly imported into data management tools like signac. This data can then be queried for use in HOOMD simulations. Key naming matches HOOMD integrators: for example, the moment_inertia key links to data from coxeter’s inertia_tensor. Stored values are based on the shape with its centroid at the origin.
For a Polyhedron or ConvexPolyhedron, the following properties are stored:
- vertices (list(list)):
The vertices of the shape.
- faces (list(list)):
The faces of the shape.
- centroid (list(float))
The centroid of the shape. This is set to [0,0,0] per HOOMD’s spec.
- sweep_radius (float):
The rounding radius of the shape (0.0).
- volume (float)
The volume of the shape.
- moment_inertia (list(list))
The shape’s inertia tensor.
- Returns:
Dict containing a subset of shape properties required for HOOMD function.
- Return type:
- to_plato_scene(backend='matplotlib', scene=None, scene_kwargs=None)#
Add this shape to a new or existing
plato.draw.Scene
.The plato visualization package provides support for several backends, including matplotlib, fresnel, povray, pythreejs, and vispy. The backend package must be separately installed by the user. Each backend supports different primitives (geometry objects) and may not support the primitive corresponding to a specific shape class in coxeter. Please refer to the plato documentation for more information about supported primitives for each backend.
- Parameters:
backend (str) – Name of backend to use from plato. The backend must support the primitive corresponding to this shape (Default value:
"matplotlib"
). Supported values include"matplotlib"
,"fresnel"
,"povray"
,"pythreejs"
,"vispy"
, and"zdog"
. See plato documentation for more information about each backend.scene (
plato.draw.Scene
) – Scene object to render into. If not provided or None, a new scene is created (Default value: None).scene_kwargs (dict) – Keyword arguments forwarded to the
plato.draw.Scene
(Default value: None). Only used ifscene
is not provided or None.
- Returns:
A scene containing this shape.
- Return type:
- Raises:
NotImplementedError: – If no plato primitive corresponds to this coxeter shape class.
AttributeError: – If the selected plato backend does not support the primitive for this coxeter shape class.
- property vertices#
Get the vertices of the polyhedron.
- Type:
\((N, 3)\)
numpy.ndarray
- class coxeter.shapes.Shape#
Bases:
ABC
An abstract representation of a shape in N dimensions.
Attributes:
Alias for
centroid
.Get or set the centroid of the shape.
Get a complete GSD specification.
Methods:
Calculate the form factor intensity.
distance_to_surface
(angles)Compute the distance to the surface of the shape at the given angles.
\((3, 3)\)
numpy.ndarray
: Get the inertia tensor.is_inside
(points)Determine whether points are contained in this shape.
plot
()Plot the shape.
to_json
(attributes)Get a JSON-serializable subset of shape properties.
to_plato_scene
([backend, scene, scene_kwargs])Add this shape to a new or existing
plato.draw.Scene
.- property center#
Alias for
centroid
.- Type:
\((3, )\)
numpy.ndarray
of float
- property centroid#
Get or set the centroid of the shape.
- Type:
\((3, )\)
numpy.ndarray
of float
- compute_form_factor_amplitude(q)#
Calculate the form factor intensity.
In solid state physics, scattering theory is concerned with understanding the ways in which radiation is scattered from a sample. For a single point particle at position P, the the amplitude of a scattered wave observed at position Q is the product of the incoming wave amplitude (which follows the standard equation for a traveling wave) and the scattering density at P. For a crystal composed of many point particles, the intensity of the resulting superposition of waves can be identified as the Fourier transform of the total scattering density. When the particles are not point particles, the scattering density of the particles in their local coordinate systems are no longer identical. Conveniently, this component is separable in the Fourier transform of the total density; as a result, the scattering scattering intensity can be decomposed into two terms, the Fourier transform of the distribution of scatterers and the Fourier transform of each scatterer in its local coordinate system. The first term is known as the static structure factor \(S(\vec{q})\) and describes the spatial distribution of scatterers, while the second term is called the form factor \(f(\vec{q})\) and describes the local scattering profile.
While the form factor (the scattering intensity) can be measured from diffraction experiments, the Fourier transform of a single particle cannot. However, it can be computed theoretically for a known scattering volume and can be inserted directly into the expression for the total scattering intensity. This local profile directly describes the wave emitted from a single scatterer (in reciprocal space) and is known as the form factor amplitude. This function computes the form factor amplitude for a given wavevector \(q\).
- distance_to_surface(angles)#
Compute the distance to the surface of the shape at the given angles.
Gets the distance to the surface at each of the angles provided, where the definition of the angles depends on the dimensionality of the shape (a single angle in 2D, or the phi/theta angles in 3D). All angles are relative to the x axis. In general, the distance is computed from the centroid of the shape unless stated otherwise.
- Parameters:
angles (\((N, d-1)\)
numpy.ndarray
) – Angles between \(0\) and \(2 \pi\) over which to calculate the distances. \(d\) is the number of dimensions.- Returns:
An array of distances from the center of the shape to its surface at each of the given angles.
- Return type:
\((N,)\)
numpy.ndarray
- property gsd_shape_spec#
Get a complete GSD specification.
- Type:
- inertia_tensor()#
\((3, 3)\)
numpy.ndarray
: Get the inertia tensor.
- is_inside(points)#
Determine whether points are contained in this shape.
Note
Points on the boundary of the shape will return
True
.- Parameters:
points (\((N, 3)\)
numpy.ndarray
) – The points to test.- Returns:
Boolean array indicating which points are contained in the shape.
- Return type:
\((N, )\)
numpy.ndarray
- plot()#
Plot the shape.
- to_plato_scene(backend='matplotlib', scene=None, scene_kwargs=None)#
Add this shape to a new or existing
plato.draw.Scene
.The plato visualization package provides support for several backends, including matplotlib, fresnel, povray, pythreejs, and vispy. The backend package must be separately installed by the user. Each backend supports different primitives (geometry objects) and may not support the primitive corresponding to a specific shape class in coxeter. Please refer to the plato documentation for more information about supported primitives for each backend.
- Parameters:
backend (str) – Name of backend to use from plato. The backend must support the primitive corresponding to this shape (Default value:
"matplotlib"
). Supported values include"matplotlib"
,"fresnel"
,"povray"
,"pythreejs"
,"vispy"
, and"zdog"
. See plato documentation for more information about each backend.scene (
plato.draw.Scene
) – Scene object to render into. If not provided or None, a new scene is created (Default value: None).scene_kwargs (dict) – Keyword arguments forwarded to the
plato.draw.Scene
(Default value: None). Only used ifscene
is not provided or None.
- Returns:
A scene containing this shape.
- Return type:
- Raises:
NotImplementedError: – If no plato primitive corresponds to this coxeter shape class.
AttributeError: – If the selected plato backend does not support the primitive for this coxeter shape class.
- class coxeter.shapes.Shape2D#
Bases:
Shape
An abstract representation of a shape in 2 dimensions.
Attributes:
Get or set the area of the shape.
Alias for
centroid
.Get or set the centroid of the shape.
Get a complete GSD specification.
Get the inertia tensor.
The isoperimetric quotient.
Get the largest bounded circle.
Get or set the radius of the maximal bounded circle.
Get the largest concentric bounded circle.
Get or set the radius of the maximal centered bounded circle.
Get the smallest bounding circle.
Get or set the radius of the minimal bounding circle.
Get the smallest bounding concentric circle.
Get or set the radius of the minimal centered bounding circle.
Get the perimeter of the shape.
Get the planar and product moments of inertia.
Get the polar moment of inertia.
Methods:
Calculate the form factor intensity.
distance_to_surface
(angles)Compute the distance to the surface of the shape at the given angles.
is_inside
(points)Determine whether points are contained in this shape.
plot
()Plot the shape.
to_json
(attributes)Get a JSON-serializable subset of shape properties.
to_plato_scene
([backend, scene, scene_kwargs])Add this shape to a new or existing
plato.draw.Scene
.- property center#
Alias for
centroid
.- Type:
\((3, )\)
numpy.ndarray
of float
- property centroid#
Get or set the centroid of the shape.
- Type:
\((3, )\)
numpy.ndarray
of float
- compute_form_factor_amplitude(q)#
Calculate the form factor intensity.
In solid state physics, scattering theory is concerned with understanding the ways in which radiation is scattered from a sample. For a single point particle at position P, the the amplitude of a scattered wave observed at position Q is the product of the incoming wave amplitude (which follows the standard equation for a traveling wave) and the scattering density at P. For a crystal composed of many point particles, the intensity of the resulting superposition of waves can be identified as the Fourier transform of the total scattering density. When the particles are not point particles, the scattering density of the particles in their local coordinate systems are no longer identical. Conveniently, this component is separable in the Fourier transform of the total density; as a result, the scattering scattering intensity can be decomposed into two terms, the Fourier transform of the distribution of scatterers and the Fourier transform of each scatterer in its local coordinate system. The first term is known as the static structure factor \(S(\vec{q})\) and describes the spatial distribution of scatterers, while the second term is called the form factor \(f(\vec{q})\) and describes the local scattering profile.
While the form factor (the scattering intensity) can be measured from diffraction experiments, the Fourier transform of a single particle cannot. However, it can be computed theoretically for a known scattering volume and can be inserted directly into the expression for the total scattering intensity. This local profile directly describes the wave emitted from a single scatterer (in reciprocal space) and is known as the form factor amplitude. This function computes the form factor amplitude for a given wavevector \(q\).
- distance_to_surface(angles)#
Compute the distance to the surface of the shape at the given angles.
Gets the distance to the surface at each of the angles provided, where the definition of the angles depends on the dimensionality of the shape (a single angle in 2D, or the phi/theta angles in 3D). All angles are relative to the x axis. In general, the distance is computed from the centroid of the shape unless stated otherwise.
- Parameters:
angles (\((N, d-1)\)
numpy.ndarray
) – Angles between \(0\) and \(2 \pi\) over which to calculate the distances. \(d\) is the number of dimensions.- Returns:
An array of distances from the center of the shape to its surface at each of the given angles.
- Return type:
\((N,)\)
numpy.ndarray
- property gsd_shape_spec#
Get a complete GSD specification.
- Type:
- property inertia_tensor#
Get the inertia tensor.
For non-orientable 2D shapes, the inertia tensor can be trivially constructed from the polar moment of inertia. This calculation assumes that the shape lies in the \(xy\)-plane. Shapes that can be rotated relative to this plane must define their own methods.
- Type:
\((3, 3)\)
numpy.ndarray
- property iq#
The isoperimetric quotient.
The isoperimetric quotient is the ratio of the area of a shape to the area of a circle with the same perimeter. Given a shape of area \(A\) and perimeter \(p\), the circle with the same perimeter has radius \(r_p = \frac{p}{2\pi}\) and therefore has an area \(A_{circle} = \pi r_p^2 = \frac{p^2}{4\pi}\). Therefore, we have that:
\[\begin{split}\begin{align} IQ &= \frac{A}{A_{circle}} \\ &= \frac{4\pi A}{p^2} \end{align}\end{split}\]- Type:
- is_inside(points)#
Determine whether points are contained in this shape.
Note
Points on the boundary of the shape will return
True
.- Parameters:
points (\((N, 3)\)
numpy.ndarray
) – The points to test.- Returns:
Boolean array indicating which points are contained in the shape.
- Return type:
\((N, )\)
numpy.ndarray
- property maximal_bounded_circle#
Get the largest bounded circle.
The largest circle contained in a shape is referred to by a range of ambiguous names. To avoid conflicts with the most common naming choices of other properties in the literature (particularly the
incircle
of a polygon), this property is named as an explicit analog tominimal_bounding_circle
.- Type:
- property maximal_bounded_circle_radius#
Get or set the radius of the maximal bounded circle.
See
maximal_bounded_circle()
for more information.- Type:
- property maximal_centered_bounded_circle#
Get the largest concentric bounded circle.
This property gives the largest circle that fits in the shape whose center also coincides with the center of the shape.
- Type:
- property maximal_centered_bounded_circle_radius#
Get or set the radius of the maximal centered bounded circle.
See
maximal_centered_bounded_circle()
for more information.- Type:
- property minimal_bounding_circle#
Get the smallest bounding circle.
A bounding circle in two dimensions is a circle containing all of the points. There are an infinite set of possible bounding circles for a shape (since any circle that entirely contains a bounding circle is also a bounding circle), so additional constraints must be imposed to define a unique circle. This property provides the smallest bounding circle of a shape.
- Type:
- property minimal_bounding_circle_radius#
Get or set the radius of the minimal bounding circle.
See
minimal_bounding_circle()
for more information.- Type:
- property minimal_centered_bounding_circle#
Get the smallest bounding concentric circle.
This property gives the smallest bounding circle whose center coincides with the center of the shape.
- Type:
- property minimal_centered_bounding_circle_radius#
Get or set the radius of the minimal centered bounding circle.
See
minimal_centered_bounding_circle()
for more information.- Type:
- property planar_moments_inertia#
Get the planar and product moments of inertia.
Moments are computed with respect to the \(x\) and \(y\) axes. In addition to the two planar moments, this property also provides the product of inertia.
The planar moments of inertia and the product of inertia define the in-plane area distribution.
- plot()#
Plot the shape.
- property polar_moment_inertia#
Get the polar moment of inertia.
The polar moment of inertia is always calculated about an axis perpendicular to the shape (i.e. the normal vector).
The polar moment is computed as the sum of the two planar moments of inertia.
- Type:
- to_plato_scene(backend='matplotlib', scene=None, scene_kwargs=None)#
Add this shape to a new or existing
plato.draw.Scene
.The plato visualization package provides support for several backends, including matplotlib, fresnel, povray, pythreejs, and vispy. The backend package must be separately installed by the user. Each backend supports different primitives (geometry objects) and may not support the primitive corresponding to a specific shape class in coxeter. Please refer to the plato documentation for more information about supported primitives for each backend.
- Parameters:
backend (str) – Name of backend to use from plato. The backend must support the primitive corresponding to this shape (Default value:
"matplotlib"
). Supported values include"matplotlib"
,"fresnel"
,"povray"
,"pythreejs"
,"vispy"
, and"zdog"
. See plato documentation for more information about each backend.scene (
plato.draw.Scene
) – Scene object to render into. If not provided or None, a new scene is created (Default value: None).scene_kwargs (dict) – Keyword arguments forwarded to the
plato.draw.Scene
(Default value: None). Only used ifscene
is not provided or None.
- Returns:
A scene containing this shape.
- Return type:
- Raises:
NotImplementedError: – If no plato primitive corresponds to this coxeter shape class.
AttributeError: – If the selected plato backend does not support the primitive for this coxeter shape class.
- class coxeter.shapes.Shape3D#
Bases:
Shape
An abstract representation of a shape in 3 dimensions.
Attributes:
Alias for
centroid
.Get or set the centroid of the shape.
Get a complete GSD specification.
The isoperimetric quotient.
Get the largest bounded sphere.
Get or set the radius of the maximal bounded sphere.
Get the largest concentric bounded sphere.
Get or set the radius of the maximal centered bounded sphere.
Get a bounding sphere sharing the center of this shape.
Get or set the radius of the minimal bounding sphere.
Get a bounding sphere sharing the center of this shape.
Get or set the radius of the minimal concentric bounding sphere.
Get or set the surface area of the shape.
Get or set the volume of the shape.
Methods:
Calculate the form factor intensity.
distance_to_surface
(angles)Compute the distance to the surface of the shape at the given angles.
\((3, 3)\)
numpy.ndarray
: Get the inertia tensor.is_inside
(points)Determine whether points are contained in this shape.
plot
()Plot the shape.
to_json
(attributes)Get a JSON-serializable subset of shape properties.
to_plato_scene
([backend, scene, scene_kwargs])Add this shape to a new or existing
plato.draw.Scene
.- property center#
Alias for
centroid
.- Type:
\((3, )\)
numpy.ndarray
of float
- property centroid#
Get or set the centroid of the shape.
- Type:
\((3, )\)
numpy.ndarray
of float
- compute_form_factor_amplitude(q)#
Calculate the form factor intensity.
In solid state physics, scattering theory is concerned with understanding the ways in which radiation is scattered from a sample. For a single point particle at position P, the the amplitude of a scattered wave observed at position Q is the product of the incoming wave amplitude (which follows the standard equation for a traveling wave) and the scattering density at P. For a crystal composed of many point particles, the intensity of the resulting superposition of waves can be identified as the Fourier transform of the total scattering density. When the particles are not point particles, the scattering density of the particles in their local coordinate systems are no longer identical. Conveniently, this component is separable in the Fourier transform of the total density; as a result, the scattering scattering intensity can be decomposed into two terms, the Fourier transform of the distribution of scatterers and the Fourier transform of each scatterer in its local coordinate system. The first term is known as the static structure factor \(S(\vec{q})\) and describes the spatial distribution of scatterers, while the second term is called the form factor \(f(\vec{q})\) and describes the local scattering profile.
While the form factor (the scattering intensity) can be measured from diffraction experiments, the Fourier transform of a single particle cannot. However, it can be computed theoretically for a known scattering volume and can be inserted directly into the expression for the total scattering intensity. This local profile directly describes the wave emitted from a single scatterer (in reciprocal space) and is known as the form factor amplitude. This function computes the form factor amplitude for a given wavevector \(q\).
- distance_to_surface(angles)#
Compute the distance to the surface of the shape at the given angles.
Gets the distance to the surface at each of the angles provided, where the definition of the angles depends on the dimensionality of the shape (a single angle in 2D, or the phi/theta angles in 3D). All angles are relative to the x axis. In general, the distance is computed from the centroid of the shape unless stated otherwise.
- Parameters:
angles (\((N, d-1)\)
numpy.ndarray
) – Angles between \(0\) and \(2 \pi\) over which to calculate the distances. \(d\) is the number of dimensions.- Returns:
An array of distances from the center of the shape to its surface at each of the given angles.
- Return type:
\((N,)\)
numpy.ndarray
- property gsd_shape_spec#
Get a complete GSD specification.
- Type:
- inertia_tensor()#
\((3, 3)\)
numpy.ndarray
: Get the inertia tensor.
- property iq#
The isoperimetric quotient.
The isoperimetric quotient is the ratio of the volume of a shape to the volume of a sphere with the same perimeter. Given a shape of volume \(A\) and surface \(S\), the sphere with the same surface has radius \(r_S = \sqrt{\frac{S}{4\pi}}\) and therefore has volume \(V_{sphere} = \frac{4}{3} \pi r_S^3 = \frac{S^{3/2}}{\sqrt{4\pi}}\). Taking the ratio of volumes gives:
\[\begin{equation} \frac{V}{V_{sphere}} = \frac{6\sqrt{\pi} V}{S^{3/2}} \end{equation}\]To avoid inconvenient fractional exponents, the isoperimetric quotient is conventionally defined as the square of this quantity:
\[\begin{split}\begin{align} IQ &= \left(\frac{V}{V_{sphere}}\right)^2 \\ &= \frac{36\pi V^2}{S^3} \end{align}\end{split}\]- Type:
- is_inside(points)#
Determine whether points are contained in this shape.
Note
Points on the boundary of the shape will return
True
.- Parameters:
points (\((N, 3)\)
numpy.ndarray
) – The points to test.- Returns:
Boolean array indicating which points are contained in the shape.
- Return type:
\((N, )\)
numpy.ndarray
- property maximal_bounded_sphere#
Get the largest bounded sphere.
The largest sphere contained in a shape is referred to by a range of ambiguous names. To avoid conflicts with the most common naming choices of other properties in the literature (particularly the
insphere
of a polyhedron), this property is named as an explicit analog tominimal_bounding_sphere
.- Type:
- property maximal_bounded_sphere_radius#
Get or set the radius of the maximal bounded sphere.
See
maximal_bounded_sphere()
for more information.- Type:
- property maximal_centered_bounded_sphere#
Get the largest concentric bounded sphere.
This property gives the largest sphere that fits in the shape whose center also coincides with the center of the shape.
- Type:
- property maximal_centered_bounded_sphere_radius#
Get or set the radius of the maximal centered bounded sphere.
See
maximal_centered_bounded_sphere()
for more information.- Type:
- property minimal_bounding_sphere#
Get a bounding sphere sharing the center of this shape.
A bounding sphere of a collection of points in dimensions is a sphere containing all of the points. There are an infinite set of possible bounding spheres for a shape (since any sphere that entirely contains a bounding sphere is also a bounding sphere), so additional constraints must be imposed to define a unique sphere. This property provides the smallest bounding sphere of a shape.
- Type:
- property minimal_bounding_sphere_radius#
Get or set the radius of the minimal bounding sphere.
See
minimal_bounding_sphere()
for more information.- Type:
- property minimal_centered_bounding_sphere#
Get a bounding sphere sharing the center of this shape.
A bounding sphere of a collection of points in is a sphere containing all of the points. There are an infinite set of possible bounding spheres for a shape (since any sphere that entirely contains a bounding sphere is also a bounding sphere), so additional constraints must be imposed to define a unique sphere. This property provides the smallest bounding sphere of a shape whose center coincides with the center of the shape.
- Type:
- property minimal_centered_bounding_sphere_radius#
Get or set the radius of the minimal concentric bounding sphere.
See
minimal_centered_bounding_sphere()
for more information.- Type:
- plot()#
Plot the shape.
- to_plato_scene(backend='matplotlib', scene=None, scene_kwargs=None)#
Add this shape to a new or existing
plato.draw.Scene
.The plato visualization package provides support for several backends, including matplotlib, fresnel, povray, pythreejs, and vispy. The backend package must be separately installed by the user. Each backend supports different primitives (geometry objects) and may not support the primitive corresponding to a specific shape class in coxeter. Please refer to the plato documentation for more information about supported primitives for each backend.
- Parameters:
backend (str) – Name of backend to use from plato. The backend must support the primitive corresponding to this shape (Default value:
"matplotlib"
). Supported values include"matplotlib"
,"fresnel"
,"povray"
,"pythreejs"
,"vispy"
, and"zdog"
. See plato documentation for more information about each backend.scene (
plato.draw.Scene
) – Scene object to render into. If not provided or None, a new scene is created (Default value: None).scene_kwargs (dict) – Keyword arguments forwarded to the
plato.draw.Scene
(Default value: None). Only used ifscene
is not provided or None.
- Returns:
A scene containing this shape.
- Return type:
- Raises:
NotImplementedError: – If no plato primitive corresponds to this coxeter shape class.
AttributeError: – If the selected plato backend does not support the primitive for this coxeter shape class.
- class coxeter.shapes.Sphere(radius, center=(0, 0, 0))#
Bases:
Shape3D
A sphere with the given radius.
- Parameters:
Example
>>> sphere = coxeter.shapes.Sphere(1.0) >>> assert np.isclose(sphere.radius, 1.0) >>> assert np.allclose(sphere.centroid, [0., 0., 0.]) >>> sphere.gsd_shape_spec {'type': 'Sphere', 'diameter': 2.0} >>> assert np.allclose( ... np.diag(sphere.inertia_tensor), ... 8. / 15. * np.pi) >>> sphere.iq 1 >>> sphere.surface_area 12.56637... >>> sphere.volume 4.18879...
Attributes:
Alias for
centroid
.Get or set the centroid of the shape.
Get or set the radius of the sphere.
Get a complete GSD specification.
Get the inertia tensor.
The isoperimetric quotient.
Get the largest bounded sphere.
Get or set the radius of the maximal bounded sphere.
Get the largest bounded concentric sphere.
Get or set the radius of the maximal centered bounded sphere.
Get the smallest bounding sphere.
Get or set the radius of the minimal bounding sphere.
Get the smallest bounding concentric sphere.
Get or set the radius of the minimal concentric bounding sphere.
Get or set the radius of the sphere.
Get the surface area.
Get the volume of the sphere.
Methods:
compute_form_factor_amplitude
(q[, density])Calculate the form factor intensity.
distance_to_surface
(angles)Compute the distance to the surface of the shape at the given angles.
is_inside
(points)Determine whether a set of points are contained in this sphere.
plot
()Plot the shape.
to_hoomd
()Get a dict of JSON-serializable subset of Sphere properties.
to_json
(attributes)Get a JSON-serializable subset of shape properties.
to_plato_scene
([backend, scene, scene_kwargs])Add this shape to a new or existing
plato.draw.Scene
.- property center#
Alias for
centroid
.- Type:
\((3, )\)
numpy.ndarray
of float
- property centroid#
Get or set the centroid of the shape.
- Type:
\((3, )\)
numpy.ndarray
of float
- compute_form_factor_amplitude(q, density=1.0)#
Calculate the form factor intensity.
In solid state physics, scattering theory is concerned with understanding the ways in which radiation is scattered from a sample. For a single point particle at position P, the the amplitude of a scattered wave observed at position Q is the product of the incoming wave amplitude (which follows the standard equation for a traveling wave) and the scattering density at P. For a crystal composed of many point particles, the intensity of the resulting superposition of waves can be identified as the Fourier transform of the total scattering density. When the particles are not point particles, the scattering density of the particles in their local coordinate systems are no longer identical. Conveniently, this component is separable in the Fourier transform of the total density; as a result, the scattering scattering intensity can be decomposed into two terms, the Fourier transform of the distribution of scatterers and the Fourier transform of each scatterer in its local coordinate system. The first term is known as the static structure factor \(S(\vec{q})\) and describes the spatial distribution of scatterers, while the second term is called the form factor \(f(\vec{q})\) and describes the local scattering profile.
While the form factor (the scattering intensity) can be measured from diffraction experiments, the Fourier transform of a single particle cannot. However, it can be computed theoretically for a known scattering volume and can be inserted directly into the expression for the total scattering intensity. This local profile directly describes the wave emitted from a single scatterer (in reciprocal space) and is known as the form factor amplitude. This function computes the form factor amplitude for a given wavevector \(q\).
- distance_to_surface(angles)#
Compute the distance to the surface of the shape at the given angles.
Gets the distance to the surface at each of the angles provided, where the definition of the angles depends on the dimensionality of the shape (a single angle in 2D, or the phi/theta angles in 3D). All angles are relative to the x axis. In general, the distance is computed from the centroid of the shape unless stated otherwise.
- Parameters:
angles (\((N, d-1)\)
numpy.ndarray
) – Angles between \(0\) and \(2 \pi\) over which to calculate the distances. \(d\) is the number of dimensions.- Returns:
An array of distances from the center of the shape to its surface at each of the given angles.
- Return type:
\((N,)\)
numpy.ndarray
- property gsd_shape_spec#
Get a complete GSD specification.
- Type:
- property inertia_tensor#
Get the inertia tensor.
Assumes a constant density of 1.
- Type:
\((3, 3)\)
numpy.ndarray
- is_inside(points)#
Determine whether a set of points are contained in this sphere.
Note
Points on the boundary of the shape will return
True
.- Parameters:
points (\((N, 3)\)
numpy.ndarray
) – The points to test.- Returns:
Boolean array indicating which points are contained in the sphere.
- Return type:
\((N, )\)
numpy.ndarray
Example
>>> sphere = coxeter.shapes.Sphere(1.0) >>> sphere.is_inside([[0, 0, 0], [20, 20, 20]]) array([ True, False])
- property maximal_bounded_sphere_radius#
Get or set the radius of the maximal bounded sphere.
See
maximal_bounded_sphere()
for more information.- Type:
- property maximal_centered_bounded_sphere_radius#
Get or set the radius of the maximal centered bounded sphere.
See
maximal_centered_bounded_sphere()
for more information.- Type:
- property minimal_bounding_sphere_radius#
Get or set the radius of the minimal bounding sphere.
See
minimal_bounding_sphere()
for more information.- Type:
- property minimal_centered_bounding_sphere#
Get the smallest bounding concentric sphere.
- Type:
- property minimal_centered_bounding_sphere_radius#
Get or set the radius of the minimal concentric bounding sphere.
See
minimal_centered_bounding_sphere()
for more information.- Type:
- plot()#
Plot the shape.
- to_hoomd()#
Get a dict of JSON-serializable subset of Sphere properties.
The JSON-serializable output of the to_hoomd method can be directly imported into data management tools like signac. This data can then be queried for use in HOOMD simulations. Key naming matches HOOMD integrators: for example, the moment_inertia key links to data from coxeter’s inertia_tensor. Stored values are based on the shape with its centroid at the origin.
For a Sphere, the following properties are stored:
- diameter (float):
The diameter of the sphere, equal to twice the radius.
- centroid (list(float))
The centroid of the shape. This is set to [0,0,0] per HOOMD’s spec.
- volume (float)
The volume of the shape.
- moment_inertia (list(list))
The shape’s inertia tensor.
- Returns:
Dict containing a subset of shape properties required for HOOMD function.
- Return type:
- to_plato_scene(backend='matplotlib', scene=None, scene_kwargs=None)#
Add this shape to a new or existing
plato.draw.Scene
.The plato visualization package provides support for several backends, including matplotlib, fresnel, povray, pythreejs, and vispy. The backend package must be separately installed by the user. Each backend supports different primitives (geometry objects) and may not support the primitive corresponding to a specific shape class in coxeter. Please refer to the plato documentation for more information about supported primitives for each backend.
- Parameters:
backend (str) – Name of backend to use from plato. The backend must support the primitive corresponding to this shape (Default value:
"matplotlib"
). Supported values include"matplotlib"
,"fresnel"
,"povray"
,"pythreejs"
,"vispy"
, and"zdog"
. See plato documentation for more information about each backend.scene (
plato.draw.Scene
) – Scene object to render into. If not provided or None, a new scene is created (Default value: None).scene_kwargs (dict) – Keyword arguments forwarded to the
plato.draw.Scene
(Default value: None). Only used ifscene
is not provided or None.
- Returns:
A scene containing this shape.
- Return type:
- Raises:
NotImplementedError: – If no plato primitive corresponds to this coxeter shape class.
AttributeError: – If the selected plato backend does not support the primitive for this coxeter shape class.