Source code for porespy.generators._fractals
import numpy as np
import scipy.ndimage as spim
from porespy.tools import get_tqdm
from porespy import settings
from loguru import logger
tqdm = get_tqdm()
[docs]def random_cantor_dust(shape, n, p=2, f=0.8):
r"""
Generates an image of random cantor dust
Parameters
----------
shape : array_like
The shape of the final image. If not evenly divisible by $p**n$
it will be increased to the nearest size that is.
n : int
The number of times to iteratively divide the image.
p : int (default = 2)
The number of divisions to make on each iteration.
f : float (default = 0.8)
The fraction of the set to keep on each iteration.
Returns
-------
dust : ndarray
A boolean image of a random Cantor dust
Examples
--------
`Click here
<https://porespy.org/examples/generators/reference/randon_cantor_dust.html>`_
to view online example.
"""
# Parse the given shape and adjust if necessary
shape = np.array(shape)
trim = np.mod(shape, (p**n))
if np.any(trim > 0):
shape = shape - trim + p**n
logger.warning(f"Requested shape being changed to {shape}")
im = np.ones(shape, dtype=bool)
divs = []
if isinstance(n, int):
for i in range(1, n):
divs.append(p**i)
else:
for i in n:
divs.append(p**i)
for i in tqdm(divs, **settings.tqdm):
sh = (np.array(im.shape)/i).astype(int)
mask = np.random.rand(*sh) < f
mask = spim.zoom(mask, zoom=i, order=0)
im = im*mask
return im
[docs]def sierpinski_foam(dmin, n, ndim=2, max_size=1e9):
r"""
Generates an image of a Sierpinski carpet or foam
Parameters
----------
dmin : int
The size of the smallest square in the final image
n : int
The number of times to iteratively tile the image
ndim : int
The number of dimensions of the desired image, can be 2 or 3. The
default value is 2.
Returns
-------
foam : ndarray
A boolean image of a Sierpinski gasket or foam
Examples
--------
`Click here
<https://porespy.org/examples/generators/reference/sierpinski_foam.html>`_
to view online example.
"""
def _insert_cubes(im, n):
if n > 0:
n -= 1
shape = np.asarray(np.shape(im))
im = np.tile(im, (3, 3, 3))
im[shape[0]:2*shape[0], shape[1]:2*shape[1], shape[2]:2*shape[2]] = 0
if im.size < max_size:
im = _insert_cubes(im, n)
return im
def _insert_squares(im, n):
if n > 0:
n -= 1
shape = np.asarray(np.shape(im))
im = np.tile(im, (3, 3))
im[shape[0]:2*shape[0], shape[1]:2*shape[1]] = 0
if im.size < max_size:
im = _insert_squares(im, n)
return im
im = np.ones([dmin]*ndim, dtype=int)
if ndim == 2:
im = _insert_squares(im, n)
elif ndim == 3:
im = _insert_cubes(im, n)
return im