Skip to content

Commit

Permalink
Increased resilience of minimal_bounding_sphere method
Browse files Browse the repository at this point in the history
The ``minimal_bounding_sphere`` method is reliant on the solution to a linear system of equations. For polyhedra with portions that protrude out from the main mass, this method can fail due to numerical instability in a small percent of cases. This fix double-checks that the calculated miniball contains all points on the polyhedron, and allows the method to make more attempts to find a correct answer before failing.
  • Loading branch information
janbridley committed Feb 13, 2023
1 parent 2df65c0 commit 40f500c
Showing 1 changed file with 12 additions and 2 deletions.
14 changes: 12 additions & 2 deletions coxeter/shapes/polyhedron.py
Original file line number Diff line number Diff line change
Expand Up @@ -556,21 +556,31 @@ def minimal_bounding_sphere(self):
'directly from PyPI using "pip install miniball".'
)

# Define a check function to ensure points lie within a sphere
def points_within_sphere(points, center, radius):
return np.linalg.norm(points - center, axis=1) <= radius

# The algorithm in miniball involves solving a linear system and
# can therefore occasionally be somewhat unstable. Applying a
# random rotation will usually fix the issue.
max_attempts = 10
# random rotation will usually fix the issue, and checking if
# points lie inside will guarantee a correct answer.
max_attempts = 20
attempt = 0
current_rotation = [1, 0, 0, 0]
vertices = self.vertices
while attempt < max_attempts:
attempt += 1
try:
center, r2 = miniball.get_bounding_ball(vertices)
assert np.all(points_within_sphere(vertices, center, np.sqrt(r2)))
break
except np.linalg.LinAlgError:
current_rotation = rowan.random.rand(1)
vertices = rowan.rotate(current_rotation, vertices)
except AssertionError:
print("Miniball sphere does not contain vertices. Retesting...")
current_rotation = rowan.random.rand(1)
vertices = rowan.rotate(current_rotation, vertices)
else:
raise RuntimeError("Unable to solve for a bounding sphere.")

Expand Down

0 comments on commit 40f500c

Please sign in to comment.