r""" Calculate the volume of the union of two spheres that possibly intersect. It is the sum of sphere :math:`A` and sphere :math:`B` minus their intersection. First, it calculates the volumes :math:`(v_1, v_2)` of the spheres, then the volume of the intersection :math:`i` and i
(
radius_1: float, radius_2: float, centers_distance: float
)
| 122 | |
| 123 | |
| 124 | def vol_spheres_union( |
| 125 | radius_1: float, radius_2: float, centers_distance: float |
| 126 | ) -> float: |
| 127 | r""" |
| 128 | Calculate the volume of the union of two spheres that possibly intersect. |
| 129 | |
| 130 | It is the sum of sphere :math:`A` and sphere :math:`B` minus their intersection. |
| 131 | First, it calculates the volumes :math:`(v_1, v_2)` of the spheres, |
| 132 | then the volume of the intersection :math:`i` and |
| 133 | it returns the sum :math:`v_1 + v_2 - i`. |
| 134 | If `centers_distance` is 0 then it returns the volume of the larger sphere |
| 135 | |
| 136 | :return: ``vol_sphere`` (:math:`radius_1`) + ``vol_sphere`` (:math:`radius_2`) |
| 137 | - ``vol_spheres_intersect`` |
| 138 | (:math:`radius_1`, :math:`radius_2`, :math:`centers\_distance`) |
| 139 | |
| 140 | >>> vol_spheres_union(2, 2, 1) |
| 141 | 45.814892864851146 |
| 142 | >>> vol_spheres_union(1.56, 2.2, 1.4) |
| 143 | 48.77802773671288 |
| 144 | >>> vol_spheres_union(0, 2, 1) |
| 145 | Traceback (most recent call last): |
| 146 | ... |
| 147 | ValueError: vol_spheres_union() only accepts non-negative values, non-zero radius |
| 148 | >>> vol_spheres_union('1.56', '2.2', '1.4') |
| 149 | Traceback (most recent call last): |
| 150 | ... |
| 151 | TypeError: '<=' not supported between instances of 'str' and 'int' |
| 152 | >>> vol_spheres_union(1, None, 1) |
| 153 | Traceback (most recent call last): |
| 154 | ... |
| 155 | TypeError: '<=' not supported between instances of 'NoneType' and 'int' |
| 156 | """ |
| 157 | |
| 158 | if radius_1 <= 0 or radius_2 <= 0 or centers_distance < 0: |
| 159 | raise ValueError( |
| 160 | "vol_spheres_union() only accepts non-negative values, non-zero radius" |
| 161 | ) |
| 162 | |
| 163 | if centers_distance == 0: |
| 164 | return vol_sphere(max(radius_1, radius_2)) |
| 165 | |
| 166 | return ( |
| 167 | vol_sphere(radius_1) |
| 168 | + vol_sphere(radius_2) |
| 169 | - vol_spheres_intersect(radius_1, radius_2, centers_distance) |
| 170 | ) |
| 171 | |
| 172 | |
| 173 | def vol_cuboid(width: float, height: float, length: float) -> float: |
no test coverage detected