scikit-image
107 строк · 3.2 Кб
1import numpy as np2from scipy.special import elliprg3
4
5def ellipsoid(a, b, c, spacing=(1.0, 1.0, 1.0), levelset=False):6"""Generate ellipsoid for given semi-axis lengths.7
8The respective semi-axis lengths are given along three dimensions in
9Cartesian coordinates. Each dimension may use a different grid spacing.
10
11Parameters
12----------
13a : float
14Length of semi-axis along x-axis.
15b : float
16Length of semi-axis along y-axis.
17c : float
18Length of semi-axis along z-axis.
19spacing : 3-tuple of floats
20Grid spacing in three spatial dimensions.
21levelset : bool
22If True, returns the level set for this ellipsoid (signed level
23set about zero, with positive denoting interior) as np.float64.
24False returns a binarized version of said level set.
25
26Returns
27-------
28ellipsoid : (M, N, P) array
29Ellipsoid centered in a correctly sized array for given `spacing`.
30Boolean dtype unless `levelset=True`, in which case a float array is
31returned with the level set above 0.0 representing the ellipsoid.
32
33"""
34if (a <= 0) or (b <= 0) or (c <= 0):35raise ValueError('Parameters a, b, and c must all be > 0')36
37offset = np.r_[1, 1, 1] * np.r_[spacing]38
39# Calculate limits, and ensure output volume is odd & symmetric40low = np.ceil(-np.r_[a, b, c] - offset)41high = np.floor(np.r_[a, b, c] + offset + 1)42
43for dim in range(3):44if (high[dim] - low[dim]) % 2 == 0:45low[dim] -= 146num = np.arange(low[dim], high[dim], spacing[dim])47if 0 not in num:48low[dim] -= np.max(num[num < 0])49
50# Generate (anisotropic) spatial grid51x, y, z = np.mgrid[52low[0] : high[0] : spacing[0],53low[1] : high[1] : spacing[1],54low[2] : high[2] : spacing[2],55]56
57if not levelset:58arr = ((x / float(a)) ** 2 + (y / float(b)) ** 2 + (z / float(c)) ** 2) <= 159else:60arr = ((x / float(a)) ** 2 + (y / float(b)) ** 2 + (z / float(c)) ** 2) - 161
62return arr63
64
65def ellipsoid_stats(a, b, c):66"""Calculate analytical volume and surface area of an ellipsoid.67
68The surface area of an ellipsoid is given by
69
70.. math:: S=4\\pi b c R_G\\!\\left(1, \\frac{a^2}{b^2}, \\frac{a^2}{c^2}\\right)
71
72where :math:`R_G` is Carlson's completely symmetric elliptic integral of
73the second kind [1]_. The latter is implemented as
74:py:func:`scipy.special.elliprg`.
75
76Parameters
77----------
78a : float
79Length of semi-axis along x-axis.
80b : float
81Length of semi-axis along y-axis.
82c : float
83Length of semi-axis along z-axis.
84
85Returns
86-------
87vol : float
88Calculated volume of ellipsoid.
89surf : float
90Calculated surface area of ellipsoid.
91
92References
93----------
94.. [1] Paul Masson (2020). Surface Area of an Ellipsoid.
95https://analyticphysics.com/Mathematical%20Methods/Surface%20Area%20of%20an%20Ellipsoid.htm
96
97"""
98if (a <= 0) or (b <= 0) or (c <= 0):99raise ValueError('Parameters a, b, and c must all be > 0')100
101# Volume102vol = 4 / 3.0 * np.pi * a * b * c103
104# Surface area105surf = 3 * vol * elliprg(1 / a**2, 1 / b**2, 1 / c**2)106
107return vol, surf108