Skip to content

Noise field from street

Pseudocode

# initialization
import packages such as topogenesis, trimesh, numpy...

load envelope as lattices
load noise sources as point clouds

# Create noise field

extract voice_centroids and put in lattice
add noise volume to point clouds noise sources

for each noise source:
    for each centroid:
        distance_lattice = sp.spatial.distance.euclidean(centroid, noise source)

    noise_lattice = noise_base - 20 * np.log10(dist_lattice) - 8

    sum_noise += np.power(10, noise_lattice / 10)

# Repeat for each noise source

aggregate_noise_lattices = 10 * np.log10(sum_noise)

# visualize the aggregated noise lattice

p.show()
</div>
</div>
</div>
<div class="cell border-box-sizing text_cell rendered" markdown="1">
<div class="inner_cell" markdown="1">
<div class="text_cell_render border-box-sizing rendered_html" markdown="1">
### 0. Initialization
#### 0.1 Load required libraries
</div>
</div>
</div>
<div class="cell border-box-sizing code_cell rendered" markdown="1">
<div class="input">

```python
import os
import topogenesis as tg
import pyvista as pv
import trimesh as tm
import numpy as np
import scipy as sp

def tri_to_pv(tri_mesh):
    faces = np.pad(tri_mesh.faces, ((0, 0),(1,0)), 'constant', constant_values=3)
    pv_mesh = pv.PolyData(tri_mesh.vertices, faces)
    return pv_mesh

0.2 Load the envelope as availability lattice

# loading the lattice from csv
lattice_path = os.path.relpath('../Data/dynamic output/voxelized_envelope_highres.csv')
context_path = os.path.relpath('../data/raw data/immediate_context.obj')
avail_lattice = tg.lattice_from_csv(lattice_path)
init_avail_lattice = tg.to_lattice(np.copy(avail_lattice), avail_lattice)
context_mesh = tm.load(context_path)

0.3 Load noise sources

# loading program from CSV
noise_source_path = os.path.relpath('../Data/raw data/Boekhorststraat_60dB.csv')
noise_sources = np.genfromtxt(noise_source_path, delimiter=',')

noise_sources[:,[1, 2]] = noise_sources[:,[2, 1]]
noise_sources[:, 1]  = noise_sources[:, 1]  * -1

noise_source_path1 = os.path.relpath('../Data/raw data/VanBokelweg_70dB.csv')
noise_sources1= np.genfromtxt(noise_source_path1, delimiter=',')

noise_sources1[:,[1, 2]] = noise_sources1[:,[2, 1]]
noise_sources1[:, 1]  = noise_sources1[:, 1]  * -1

noise_source_path2 = os.path.relpath('../Data/raw data/Schoterbosstraat_50dB.csv')
noise_sources2 = np.genfromtxt(noise_source_path2, delimiter=',')

noise_sources2[:,[1, 2]] = noise_sources2[:,[2, 1]]
noise_sources2[:, 1]  = noise_sources2[:, 1]  * -1

0.4. Visualize noise source points

p = pv.Plotter(notebook=True)


# adding the avilability lattice
init_avail_lattice.fast_vis(p)

# adding axes
p.add_axes()

p.add_mesh(noise_sources, point_size=10)
p.add_mesh(noise_sources1, point_size=10)
p.add_mesh(noise_sources2, point_size=10)
p.add_mesh(tri_to_pv(context_mesh), color='#aaaaaa')

# p.show()

1. Creation noise field

1.1 computing noise lattices

# create full lattice
full_lattice = avail_lattice * 0 + 1

# extract the coordinates of the centroid of all voxel
vox_centroids = full_lattice.centroids

# extract voxel indices of all voxels
vox_indices = np.array(np.where(full_lattice==1)).T

# setting the noise base pressure level 
noise_base = 60.0
noise_base1 = 70.0
noise_base2 = 50.0
# initializing the sum lattice of noise
sum_noise_lats = avail_lattice * 0.0

# for each source of noise
for noise_src in noise_sources:
    # initialize the occupation lattice
    dist_latice = avail_lattice * 0.0

    for cen, ind in zip(vox_centroids, vox_indices):
        # compute the euclidian distance
        dist_latice[tuple(ind)] = sp.spatial.distance.euclidean(cen, noise_src)

    # computing the noise lattice from dist lattice
    noise_latice = noise_base - 20 * np.log10(dist_latice) - 8

    # summing
    sum_noise_lats += np.power(10, noise_latice / 10.0)

# for each source of noise
for noise_src1 in noise_sources1:
    # initialize the occupation lattice
    dist_latice = avail_lattice * 0.0

    for cen, ind in zip(vox_centroids, vox_indices):
        # compute the euclidian distance
        dist_latice[tuple(ind)] = sp.spatial.distance.euclidean(cen, noise_src1)

    # computing the noise lattice from dist lattice
    noise_latice = noise_base1 - 20 * np.log10(dist_latice) - 8

    # summing
    sum_noise_lats += np.power(10, noise_latice / 10.0)

# for each source of noise
for noise_src2 in noise_sources2:
    # initialize the occupation lattice
    dist_latice = avail_lattice * 0.0

    for cen, ind in zip(vox_centroids, vox_indices):
        # compute the euclidian distance
        dist_latice[tuple(ind)] = sp.spatial.distance.euclidean(cen, noise_src2)

    # computing the noise lattice from dist lattice
    noise_latice = noise_base2 - 20 * np.log10(dist_latice) - 8

    # summing
    sum_noise_lats += np.power(10, noise_latice / 10.0)


# computing the final aggregation
agg_noise_lats = 10 * np.log10(sum_noise_lats)

1.2. Visualizing the noise lattices

# initiating the plotter
p = pv.Plotter(notebook=True)

vis_lattice = agg_noise_lats

# Create the spatial reference
grid = pv.UniformGrid()

# Set the grid dimensions: shape because we want to inject our values
grid.dimensions = vis_lattice.shape
# The bottom left corner of the data set
grid.origin = vis_lattice.minbound
# These are the cell sizes along each axis
grid.spacing = vis_lattice.unit

# Add the data values to the cell data
grid.point_arrays["Noise"] = vis_lattice.flatten(order="F")  # Flatten the Lattice


# adding the volume
opacity = np.array([0,0.6,0.6,0.6,0.6,0.6,0.6])*1.5
p.add_volume(grid, cmap="coolwarm" ,opacity=opacity, shade=True)
p.add_mesh(noise_sources, point_size=10)
p.add_mesh(noise_sources1, point_size=10)
p.add_mesh(noise_sources2, point_size=10)

p.add_mesh(tri_to_pv(context_mesh), color='#aaaaaa')

# plotting
p.show(use_ipyvtk=True)
# initiating the plotter
p = pv.Plotter()

l = agg_noise_lats

# Create the spatial reference
grid = pv.UniformGrid()

# Set the grid dimensions: shape because we want to inject our values
grid.dimensions = l.shape
# The bottom left corner of the data set
grid.origin = l.minbound
# These are the cell sizes along each axis
grid.spacing = l.unit

# Add the data values to the cell data
grid.point_arrays["Noice field"] = l.flatten(order="F")  # Flatten the Lattice

# adding the volume
p.add_volume(grid, cmap="cividis", shade=False, show_scalar_bar=True)

# plotting
p.show()

Saving to csv

csv_path = os.path.relpath('../Data/dynamic output/noise_field.csv')
agg_noise_lats.to_csv(csv_path)

Credits

__author__ = "Shervin Azadi"
__license__ = "MIT"
__version__ = "1.0"
__url__ = "https://github.com/shervinazadi/spatial_computing_workshops"
__summary__ = "Spatial Computing Design Studio Workshop on Noise Fields"