From 4eb5c12727d7590d17a5cbefe34c6a255f69e670 Mon Sep 17 00:00:00 2001 From: Matteo Messmer <40521259+matteomessmer@users.noreply.github.com> Date: Wed, 27 Oct 2021 00:28:26 +0200 Subject: [PATCH] Sphere intersection and spherical cap volumes (#5579) * sphere intersection + spherical cap volume formulas * reformatted * Update volume.py Co-authored-by: Christian Clauss --- maths/volume.py | 52 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/maths/volume.py b/maths/volume.py index 51b2b9fc0..fd24aa9ee 100644 --- a/maths/volume.py +++ b/maths/volume.py @@ -20,6 +20,56 @@ def vol_cube(side_length: int | float) -> float: return pow(side_length, 3) +def vol_spherical_cap(height: float, radius: float) -> float: + """ + Calculate the Volume of the spherical cap. + :return 1/3 pi * height ^ 2 * (3 * radius - height) + + >>> vol_spherical_cap(1, 2) + 5.235987755982988 + """ + return 1 / 3 * pi * pow(height, 2) * (3 * radius - height) + + +def vol_spheres_intersect( + radius_1: float, radius_2: float, centers_distance: float +) -> float: + """ + Calculate the volume of the intersection of two spheres. + + The intersection is composed by two spherical caps and therefore its volume is the + sum of the volumes of the spherical caps. First it calculates the heights (h1, h2) + of the the spherical caps, then the two volumes and it returns the sum. + The height formulas are + h1 = (radius_1 - radius_2 + centers_distance) + * (radius_1 + radius_2 - centers_distance) + / (2 * centers_distance) + h2 = (radius_2 - radius_1 + centers_distance) + * (radius_2 + radius_1 - centers_distance) + / (2 * centers_distance) + if centers_distance is 0 then it returns the volume of the smallers sphere + :return vol_spherical_cap(h1, radius_2) + vol_spherical_cap(h2, radius_1) + + >>> vol_spheres_intersect(2, 2, 1) + 21.205750411731103 + """ + if centers_distance == 0: + return vol_sphere(min(radius_1, radius_2)) + + h1 = ( + (radius_1 - radius_2 + centers_distance) + * (radius_1 + radius_2 - centers_distance) + / (2 * centers_distance) + ) + h2 = ( + (radius_2 - radius_1 + centers_distance) + * (radius_2 + radius_1 - centers_distance) + / (2 * centers_distance) + ) + + return vol_spherical_cap(h1, radius_2) + vol_spherical_cap(h2, radius_1) + + def vol_cuboid(width: float, height: float, length: float) -> float: """ Calculate the Volume of a Cuboid. @@ -127,6 +177,8 @@ def main(): print("Pyramid: " + str(vol_pyramid(2, 2))) # ~= 1.33 print("Sphere: " + str(vol_sphere(2))) # ~= 33.5 print("Circular Cylinder: " + str(vol_circular_cylinder(2, 2))) # ~= 25.1 + print("Spherical cap: " + str(vol_spherical_cap(1, 2))) # ~= 5.24 + print("Spheres intersetion: " + str(vol_spheres_intersect(2, 2, 1))) # ~= 21.21 if __name__ == "__main__":