<jupyter_start><jupyter_text>Penkit provides tools for making pseudo-3D projections of textures onto **surfaces**. A surface in penkit is a 2D matrix that is treated as an elevation map. These can either come from real-world data (e.g. topographic data), or be generated. Penkit's `surfaces` module provides a few surface generators to get you started.<jupyter_code>%matplotlib inline
from penkit import surfaces
import matplotlib.pyplot as plt<jupyter_output><empty_output><jupyter_text>Since surfaces are just matrices, we can use `matplotlib.imshow` to see what they look like.<jupyter_code>fig, (a1, a2, a3) = plt.subplots(1, 3)
a1.imshow(surfaces.make_bubble_surface(), cmap='gray')
a2.imshow(surfaces.make_noise_surface(), cmap='gray')
a3.imshow(surfaces.make_sine_surface(), cmap='gray');<jupyter_output><empty_output><jupyter_text>With penkit, we can combine a surface, a texture, and an angle to produce a new layer through **projection**.<jupyter_code>from penkit.textures import make_grid_texture
from penkit.textures.util import rotate_texture
from penkit.surfaces import make_noise_surface
from penkit.projection import project_and_occlude_texture
from penkit.preview import show_layer
# create a texture
grid_density = 40
texture = make_grid_texture(grid_density, grid_density, 100)

# rotate the texture
texture = rotate_texture(texture, 50)

# create the surface
surface = make_noise_surface(blur=30, seed=12345) * 5

# project the texture onto the surface
proj = project_and_occlude_texture(texture, surface, angle=45)

# plot the result
show_layer(proj)<jupyter_output><empty_output><jupyter_text>All textures are layers, but not all layers are textures (remember, textures are a special case of layers that fit within `(0, 1)` on both axes.) We can use `penkit.textures.util.fit_texture` to convert any layer into a texture by scaling both axes. This allows us to, for example, use a generated fractal as a texture.<jupyter_code>from penkit.fractal import hilbert_curve
from penkit.textures.util import fit_texture
# create a texture
texture = hilbert_curve(7)
# rotate the texture
texture = rotate_texture(texture, 30)
texture = fit_texture(texture)
# create the surface
surface = make_noise_surface(blur=30) * 5
# project the texture onto the surface
proj = project_and_occlude_texture(texture, surface, 50)
# plot the result
show_layer(proj, height=600, width=800)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.08153973509933775, 'fraction_numerical': 0.017798013245033113, 'mean_word_length': 6.697452229299363, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '576188', 'license': 'MIT', 'n_tokens_mistral': 794, 'n_tokens_neox': 738, 'n_words': 253, 'path': 'tutorial/03-Surface Projections.ipynb', 'repo_name': 'djma/penkit', 'size': '2416'}