Link_tester
Link_tester

Reputation: 1081

how to calculate volume of irregular shapes in python

I have an irregular shape and want to calculate its volume in python. I have seen this solution but I could not figure out how to code it in python. I also uploaded a figure showing my irregular box. Black lines are parallel and figure is in 3d. I have the cordinates of 8 points of the corners as numpy array.

import numpy as np
corners = np.array([[0.,0.,0.], [0.,1.,0.1], [1.,1.,0.1], [0.,1.,0.], # lower rectangle
                    [0.,0.,1.], [0.,1.,1.1], [1.,1.,1.1], [0.,1.,1.]]# upper rectangle

For this simple point the volume should be 1 m^3 but in reality my shapes are much more irregular. I very much apperiate if anyone can help me to calculate the volume of such shapes in python.

enter image description here

Upvotes: 0

Views: 1492

Answers (1)

Stéphane Laurent
Stéphane Laurent

Reputation: 84719

If your object is convex, you can split it into tetrahedra with the help of a Delaunay triangulation.

import numpy as np
from scipy.spatial import Delaunay

corners = np.array([
    [0.,0.,0.], [0.,1.,0.1], [1.,1.,0.1], [0.,1.,0.], # lower rectangle
    [0.,0.,1.], [0.,1.,1.1], [1.,1.,1.1], [0.,1.,1.]  # upper rectangle
])

tri = Delaunay(corners)

Here are the Delaunay tetrahedra:

>>> tetrahedra = corners[tri.simplices]
array([[[0. , 1. , 0. ],
        [0. , 1. , 0.1],
        [1. , 1. , 0.1],
        [0. , 0. , 0. ]],

       [[0. , 0. , 1. ],
        [0. , 1. , 0.1],
        [1. , 1. , 0.1],
        [0. , 0. , 0. ]],

       [[0. , 1. , 1. ],
        [0. , 0. , 1. ],
        [0. , 1. , 0.1],
        [1. , 1. , 0.1]],

       [[0. , 1. , 1. ],
        [0. , 0. , 1. ],
        [1. , 1. , 1.1],
        [1. , 1. , 0.1]],

       [[0. , 1. , 1. ],
        [0. , 0. , 1. ],
        [1. , 1. , 1.1],
        [0. , 1. , 1.1]]])

The way to get the volume of a tetrahedron is well known:

def volume_tetrahedron(tetrahedron):
    matrix = np.array([
        tetrahedron[0] - tetrahedron[3],
        tetrahedron[1] - tetrahedron[3],
        tetrahedron[2] - tetrahedron[3]
    ])
    return abs(np.linalg.det(matrix))/6

So, calculate the volumes of the Delaunay tetrahedra:

volumes = np.array([volume_tetrahedron(t) for t in tetrahedra])

and sum them:

>>> volume = np.sum(volumes)
0.5166666666666667

I insist on one point: your object must be convex. Otherwise the Delaunay algorithm triangulates the convex hull of your object.

Upvotes: 2

Related Questions