Reputation: 1
I have a model formed by Contour lines in X,Y coordinates and forms an irregular model with constant height of 3 in Z axis? I would like to find the volume of this model in python probably using Scipy module I have points of all the contour slices
The image as shown below
Upvotes: 0
Views: 2078
Reputation: 33
You can use the convex hull method for calculating the volume of any solid formed by a cloud of points.
Scipy has a class for calculating the ConvexHull.
According to Eaton (2013), "a convex hull is defined as the smallest convex set containing all of the points from a point cloud. The volume is formed from triplets of points and thus creates a tessellated convex volume comprised of triangular surface elements. Informally, a convex hull can be viewed as a shrink-wrapped surface around the exterior of the point cloud. The method characteristics are 1) the hull is unique for a given point cloud, and 2) it is a conservative estimate of the volume, since it is the smallest convex volume that contains the points" (p.307).
To calculate the volume of your solid, you have to create a numpy array with dimentions [n_samples,3], calculate the hull using the scipy class, then check the hull volume attribute. Example:
import numpy as np
from scipy.spatial import ConvexHull
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# Using spherical coordinates to generate points on the surface
def sphere_points(samples,radius=1):
# Random samples in the ranges 0<=theta<=2pi, 0<=phi<=pi
theta = 2*np.pi*np.random.rand(samples,)
phi = np.pi*np.random.rand(samples,)
# Making retangular coordinates from the spherical coordinates
x=radius*np.cos(theta)*np.sin(phi)
y=radius*np.sin(theta)*np.sin(phi)
z=radius*np.cos(phi)
return(np.transpose(np.array([x,y,z])))
# Calculating N=10000 points in a spherical surface
sph_array=sphere_points(10000)
# Calculate the Hull
hull = ConvexHull(sph_array)
# Once the hull is calculated, you can consult the volume attribute
hull.volume
Following is an example to calculate the volume of a sphere using different number of points. As described before, the calculation is always conservative, meaning the volume will converge from below the exact answer (4/3)PiR^3:
samples=[10,25,50,75,100,250,500,750,1000,2500,5000,7500,10000]
volume=[]
for sample in samples:
sph_array=sphere_points(sample)
hull = ConvexHull(sph_array)
volume.append(hull.volume)
fig = plt.figure(figsize=(6,6))
ax = fig.add_subplot(111)
ax.scatter(samples,volume,label=('ConvexHull volume'))
ax.set_xscale('log')
ax.axhline(y=(4/3)*np.pi,c='r',label=('Sphere volume (4/3)Pi R^3'))
ax.set_xlabel('Samples')
ax.set_ylabel('Volume (m^3)')
ax.set_title('Convergence of sphere volume')
ax.legend(loc='lower right')
plt.show()
References:
Eaton, Maulianda, et al. (2013). “Estimation of stimulated reservoir volume (SRV) using microseismic observations”. In: MIC - Annual Research Report. Vol. 3. Calgary AB.
Upvotes: 2