LinAlgError on oriented_bounding_box_numpy with some inputs
beneltayar opened this issue · comments
There are some valid inputs that cause oriented_bounding_box_numpy
to throw an numpy.linalg.LinAlgError
To Reproduce
import numpy as np
from compas.geometry import oriented_bounding_box_numpy
oriented_bounding_box_numpy(np.array([
[198.71435547, -18.45817566, 61.03982544],
[198.78266907, -18.38731384, 62.90990448],
[198.78266907, -18.38731384, 61.03982544],
[199.78454590, -17.34801292, 62.90990448],
[199.26994324, -17.88183594, 75.31147766],
[199.78454590, -17.34801292, 64.32066345],
[199.78454590, -17.34801292, 62.90989685],
]))
Output
Traceback (most recent call last):
File "C:\Users\benel\AppData\Roaming\JetBrains\PyCharm2022.3\scratches\scratch.py", line 8, in <module>
oriented_bounding_box_numpy(np.array([
File "C:\git\buildots\pycode\venv39\lib\site-packages\compas\geometry\bbox\bbox_numpy.py", line 133, in oriented_bounding_box_numpy
rst = world_to_local_coordinates_numpy(frame, xyz)
File "C:\git\buildots\pycode\venv39\lib\site-packages\compas\geometry\transformations\transformations_numpy.py", line 141, in world_to_local_coordinates_numpy
rst = solve(uvw, xyz)
File "C:\git\buildots\pycode\venv39\lib\site-packages\scipy\linalg\_basic.py", line 223, in solve
_solve_check(n, info)
File "C:\git\buildots\pycode\venv39\lib\site-packages\scipy\linalg\_basic.py", line 29, in _solve_check
raise LinAlgError('Matrix is singular.')
numpy.linalg.LinAlgError: Matrix is singular.
Expected behavior
Getting an oriented bounding box of this specific set of points
Desktop:
- OS: Windows11 - 64bit
- Python version 3.9.10
- Numpy version 1.23.5
- Scipy version 1.10.0
- Python package manager: pip
hi,
that is indeed a bug.
when possible, the code tries to use the convex hull of the points to build the oriented box, but it doesn't check the validity of the simplices of the hull during that process, which it should.
i will have a look at how this can be done more robustly.
in the meantime, you could use the function the algorithm normally falls back to if the convex hull algorithm fails.
it is more robust but doesn't always produce the smallest oriented box for the input.
from compas.geometry import Point, Box
from compas.geometry.bbox.bbox_numpy import oabb_numpy
from compas_view2.app import App
points = [
[198.71435547, -18.45817566, 61.03982544],
[198.78266907, -18.38731384, 62.90990448],
[198.78266907, -18.38731384, 61.03982544],
[199.78454590, -17.34801292, 62.90990448],
[199.26994324, -17.88183594, 75.31147766],
[199.78454590, -17.34801292, 64.32066345],
[199.78454590, -17.34801292, 62.90989685],
]
box = oabb_numpy(points)
box = Box.from_bounding_box(box)
viewer = App()
for point in points:
viewer.add(Point(*point))
viewer.add(box)
viewer.run()
@beneltayar i think this is now resolved. would you mind having a look?