Source code for microstructpy.geometry.sphere

"""Sphere

This module contains the Sphere class.
"""
# --------------------------------------------------------------------------- #
#                                                                             #
# Import Modules                                                              #
#                                                                             #
# --------------------------------------------------------------------------- #

from __future__ import division

import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

from microstructpy.geometry.n_sphere import NSphere

__author__ = 'Kenneth (Kip) Hart'


# --------------------------------------------------------------------------- #
#                                                                             #
# Sphere Class                                                                #
#                                                                             #
# --------------------------------------------------------------------------- #
[docs]class Sphere(NSphere): """A 3D sphere. This class represents a three-dimensional circle. It is defined by a center point and size parameter, which can be either radius or diameter. Without input parameters, this defaults to a unit sphere centered at the origin. Args: r (float): *(optional)* The radius of the sphere. Defaults to 1. radius (float): *(optional)* Same as ``r``. d (float): *(optional)* Alias for ``2*r``. diameter (float): *(optional)* Alias for ``2*r``. size (float): *(optional)* Alias for ``2*r``. center (list, float, numpy.ndarray): *(optional)* The coordinates of the center. Defaults to ``[0, 0, 0]``. position (list, float, numpy.ndarray): *(optional)* Alias for ``center``. """ # ----------------------------------------------------------------------- # # Constructor # # ----------------------------------------------------------------------- # def __init__(self, **kwargs): if 'volume' in kwargs: v = kwargs['volume'] r = np.cbrt(3 * v / (4 * np.pi)) kwargs['r'] = r NSphere.__init__(self, **kwargs) if len(self.center) == 0: self.center = tuple(self.n_dim * [0]) # ----------------------------------------------------------------------- # # Representation Function # # ----------------------------------------------------------------------- # def __repr__(self): repr_str = 'Sphere(' repr_str += 'center=' + repr(tuple(self.center)) repr_str += ', radius=' + repr(self.r) repr_str += ')' return repr_str # ----------------------------------------------------------------------- # # Number of Dimensions # # ----------------------------------------------------------------------- # @property def n_dim(self): """int: number of dimensions, 3""" return 3 # ----------------------------------------------------------------------- # # Volume # # ----------------------------------------------------------------------- # @property def volume(self): """float: volume of sphere""" return 4 * np.pi * self.r * self.r * self.r / 3
[docs] @classmethod def volume_expectation(cls, **kwargs): r"""Expected value of volume. This function computes the expected value for the volume of a sphere. The keyword arguments are identical to the :class:`.Sphere` function. The values for these keywords can be either constants or :mod:`scipy.stats` distributions. The expected value is computed by the following formula: .. math:: \mathbb{E}[V] &= \mathbb{E}[\frac{4}{3}\pi R^3] \\ &= \frac{4}{3}\pi \mathbb{E}[R^3] \\ &= \frac{4}{3}\pi (\mu_R^3 + 3 \mu_R \sigma_R^2 + \gamma_{1, R} \sigma_R^3) Args: **kwargs: Keyword arguments, see :class:`microstructpy.geometry.Sphere`. Returns: float: Expected value of the volume of the sphere. """ # NOQA: E501 # Check for radius distribution r_dist = None if 'radius' in kwargs: r_dist = kwargs['radius'] elif 'r' in kwargs: r_dist = kwargs['r'] if type(r_dist) in (float, int): return 4 * np.pi * r_dist * r_dist * r_dist / 3 elif r_dist is not None: return 4 * np.pi * r_dist.moment(3) / 3 # Check for diameter distribution d_dist = None for d_kw in ('d', 'diameter', 'size'): if d_kw in kwargs: d_dist = kwargs[d_kw] break if type(d_dist) in (float, int): return 0.5 * np.pi * d_dist * d_dist * d_dist / 3 elif d_dist is not None: return 0.5 * np.pi * d_dist.moment(3) / 3 if 'volume' in kwargs: v_dist = kwargs['volume'] try: v_exp = v_dist.moment(1) except AttributeError: v_exp = v_dist return v_exp # Raise error e_str = 'Could not find one of the following keywords in the inputs: ' e_str += 'r, radius, d, diameter, volume.' raise KeyError(e_str)
# ----------------------------------------------------------------------- # # Plot Function # # ----------------------------------------------------------------------- #
[docs] def plot(self, **kwargs): """Plot the sphere. This function uses the :meth:`mpl_toolkits.mplot3d.Axes3D.plot_surface` method to add the sphere to the current axes. The keyword arguments are passed through to plot_surface. Args: **kwargs (dict): Keyword arguments for plot_surface. """ # NOQA: E501 if len(plt.gcf().axes) == 0: ax = plt.axes(projection=Axes3D.name) else: ax = plt.gca() u = np.linspace(0, 2 * np.pi, 11) cv = np.linspace(-1, 1, 12) uu, cvv = np.meshgrid(u, cv) svv = np.sin(np.arccos(cvv)) xc, yc, zc = self.center r = self.r xx = xc + r * np.cos(uu) * svv yy = yc + r * np.sin(uu) * svv zz = zc + r * cvv mod_kwargs = {} for key, val in kwargs.items(): if key == 'facecolors' and type(val) != list: mod_kwargs['color'] = val else: mod_kwargs[key] = val ax.plot_surface(xx, yy, zz, **mod_kwargs)