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"