Added spheres union (#6879)

* Spheres union

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update volume.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update volume.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* f-strings

* Update maths/volume.py

Co-authored-by: Christian Clauss <cclauss@me.com>

* more tests

* fix non negative

* fix 0 radius

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix tests

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix tests

* fix print

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix comment

* fix comment

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Update volume.py

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Christian Clauss <cclauss@me.com>
This commit is contained in:
Matteo Messmer 2022-10-27 19:45:58 +02:00 committed by GitHub
parent 9bba42eca8
commit 71e8ed81ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -108,6 +108,51 @@ def vol_spheres_intersect(
return vol_spherical_cap(h1, radius_2) + vol_spherical_cap(h2, radius_1)
def vol_spheres_union(
radius_1: float, radius_2: float, centers_distance: float
) -> float:
"""
Calculate the volume of the union of two spheres that possibly intersect.
It is the sum of sphere A and sphere B minus their intersection.
First, it calculates the volumes (v1, v2) of the spheres,
then the volume of the intersection (i) and it returns the sum v1+v2-i.
If centers_distance is 0 then it returns the volume of the larger sphere
:return vol_sphere(radius_1) + vol_sphere(radius_2)
- vol_spheres_intersect(radius_1, radius_2, centers_distance)
>>> vol_spheres_union(2, 2, 1)
45.814892864851146
>>> vol_spheres_union(1.56, 2.2, 1.4)
48.77802773671288
>>> vol_spheres_union(0, 2, 1)
Traceback (most recent call last):
...
ValueError: vol_spheres_union() only accepts non-negative values, non-zero radius
>>> vol_spheres_union('1.56', '2.2', '1.4')
Traceback (most recent call last):
...
TypeError: '<=' not supported between instances of 'str' and 'int'
>>> vol_spheres_union(1, None, 1)
Traceback (most recent call last):
...
TypeError: '<=' not supported between instances of 'NoneType' and 'int'
"""
if radius_1 <= 0 or radius_2 <= 0 or centers_distance < 0:
raise ValueError(
"vol_spheres_union() only accepts non-negative values, non-zero radius"
)
if centers_distance == 0:
return vol_sphere(max(radius_1, radius_2))
return (
vol_sphere(radius_1)
+ vol_sphere(radius_2)
- vol_spheres_intersect(radius_1, radius_2, centers_distance)
)
def vol_cuboid(width: float, height: float, length: float) -> float:
"""
Calculate the Volume of a Cuboid.
@ -408,12 +453,13 @@ def main():
print(f"Sphere: {vol_sphere(2) = }") # ~= 33.5
print(f"Hemisphere: {vol_hemisphere(2) = }") # ~= 16.75
print(f"Circular Cylinder: {vol_circular_cylinder(2, 2) = }") # ~= 25.1
print(
f"Hollow Circular Cylinder: {vol_hollow_circular_cylinder(1, 2, 3) = }"
) # ~= 28.3
print(f"Conical Frustum: {vol_conical_frustum(2, 2, 4) = }") # ~= 58.6
print(f"Spherical cap: {vol_spherical_cap(1, 2) = }") # ~= 5.24
print(f"Spheres intersetion: {vol_spheres_intersect(2, 2, 1) = }") # ~= 21.21
print(f"Spheres union: {vol_spheres_union(2, 2, 1) = }") # ~= 45.81
print(
f"Hollow Circular Cylinder: {vol_hollow_circular_cylinder(1, 2, 3) = }"
) # ~= 28.3
if __name__ == "__main__":