1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
|
"""
.. _perlin_noise_2d_example:
Sample Function: Perlin Noise in 2D
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Here we use :func:`pyvista.core.utilities.features.sample_function` to sample
Perlin noise over a region to generate random terrain.
Perlin noise is atype of gradient noise often used by visual effects
artists to increase the appearance of realism in computer graphics.
Source: `Perlin Noise Wikipedia <https://en.wikipedia.org/wiki/Perlin_noise>`_
The development of Perlin Noise has allowed computer graphics artists
to better represent the complexity of natural phenomena in visual
effects for the motion picture industry.
"""
from __future__ import annotations
import pyvista as pv
# %%
# Generate Perlin Noise over a StructuredGrid
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Feel free to change the values of ``freq`` to change the shape of
# the "mountains". For example, lowering the frequency will make the
# terrain seem more like hills rather than mountains.
freq = [0.689, 0.562, 0.683]
noise = pv.perlin_noise(1, freq, (0, 0, 0))
sampled = pv.sample_function(noise, bounds=(-10, 10, -10, 10, -10, 10), dim=(500, 500, 1))
# %%
# Warp by scalar
# ~~~~~~~~~~~~~~
# Here we warp by scalar to give the terrain some height based on the
# value of the Perlin noise. This is necessary to the terrain its shape.
mesh = sampled.warp_by_scalar('scalars')
mesh = mesh.extract_surface()
# clean and smooth a little to reduce Perlin noise artifacts
mesh = mesh.smooth(n_iter=100, inplace=False, relaxation_factor=1)
# This makes the "water" level look flat.
z = mesh.points[:, 2]
diff = z.max() - z.min()
# water level at 70% (change this to change the water level)
water_percent = 0.7
water_level = z.max() - water_percent * diff
mesh.points[z < water_level, 2] = water_level
# %%
# Show the terrain as a contour plot
# make the water blue
rng = z.max() - z.min()
clim = (z.max() - rng * 1.65, z.max())
pl = pv.Plotter()
pl.add_mesh(
mesh,
scalars=z,
cmap='gist_earth',
n_colors=10,
show_scalar_bar=False,
smooth_shading=True,
clim=clim,
)
pl.show()
# %%
# Show the terrain with custom lighting and shadows
pl = pv.Plotter(lighting=None)
pl.add_light(pv.Light((3, 1, 0.5), show_actor=True, positional=True, cone_angle=90, intensity=1.2))
pl.add_mesh(mesh, cmap='gist_earth', show_scalar_bar=False, smooth_shading=True, clim=clim)
pl.enable_shadows = True
pl.show()
|