def bbox_volume(coords, angles=(0., 0.)): """ Compute the volume of bouding box of a cloud of points for a given rotation of the cloud of points Needs the rotation angles (rotation angle along x, rotation angle along y) and the coordinates (3D array) of the cloud of points """ angles = np.array(angles) # cloud of points rotation coords_rot = bf.rotate_aggregate(coords, angles=angles) # calculation of the side _min = coords_rot.min(axis=0) _max = coords_rot.max(axis=0) lengths = np.sqrt((_max - _min)**2) volume = lengths[0] * lengths[1] * lengths[2] return volume
def included_ellipsoid_optim(coord, tol=1e-13, quiet=True): """ Compute the largest included ellidpsoid of a cloud of points Needs the required precision (tol) and the coordinates (3D array) of the cloud of points """ # finding optimal bounding box bbox_res = bbox.bbox_optim(coord) if quiet is False: plot.bbox_plot(coord, bbox_res) # rotation of the cloud of points in the main direction of the bbox coord = bf.rotate_aggregate(coord, angles=bbox_res['angles']) # initial a, b, c a = (np.sqrt((max(coord[:, 0]) - min(coord[:, 0]))**2)) / 2. b = (np.sqrt((max(coord[:, 1]) - min(coord[:, 1]))**2)) / 2. c = (np.sqrt((max(coord[:, 2]) - min(coord[:, 2]))**2)) / 2. a_before = 0. b_before = 0. c_before = 0. volume_before = 0. volume = 4. / 3. * np.pi * a * b * c test = 'false' point_inside = 'true' while abs(volume - volume_before) > tol: volume_before = volume # test if points inside the bounded ellipsoid for i in range(len(coord)): if (coord[i, 0]**2 / a**2 + coord[i, 1]**2 / b**2 + coord[i, 2]**2 / c**2) < 1: point_inside = 'true' #print('x =', coord[i, 0], 'y =', coord[i, 1], 'z =', coord[i, 2]) break else: point_inside = 'false' if point_inside == 'true': a1 = a_before b1 = b_before c1 = c_before a_before = a b_before = b c_before = c a = a - abs(a1 - a) / 2. b = b - abs(b1 - b) / 2. c = c - abs(c1 - c) / 2. test = 'true' elif point_inside == 'false' and test == 'true': a1 = a_before b1 = b_before c1 = c_before a_before = a b_before = b c_before = c a = a + abs(a1 - a) / 2. b = b + abs(b1 - b) / 2. c = c + abs(c1 - c) / 2. else: print( 'error, the bbox did not work:' ' bbox does not not touch the extrema of the cloud of points') break volume = 4. / 3. * np.pi * a * b * c if (quiet is False): print('volume =', volume) print('a = ', a, 'b = ', b, 'c = ', c) plot.fit_ellipsoid_plot(coord, a, b, c, 10000) return {'volume': volume, 'a': a, 'b': b, 'c': c, 'bbox': bbox_res}
def bounding_ellipsoid_optim(coord, tol=1e-3, quiet=True): """ Compute the smallest bounding ellidpsoid of a cloud of points Needs the required precision (tol) and the coordinates (3D array) of the cloud of points """ # finding optimal bounding box bbox_res = bbox.bbox_optim(coord) if quiet is False: plot.bbox_plot(coord, bbox_res) # rotation of the cloud of points in the main direction of the bbox coord = bf.rotate_aggregate(coord, angles=bbox_res['angles']) # plot.bbox_plot(coord, 0., 0., 2) # initial a, b, c a = np.sqrt((max(coord[:, 0]) - min(coord[:, 0]))**2) / 2. b = np.sqrt((max(coord[:, 1]) - min(coord[:, 1]))**2) / 2. c = np.sqrt((max(coord[:, 2]) - min(coord[:, 2]))**2) / 2. volume_before = 0. volume = 4. / 3. * np.pi * a * b * c while abs(volume - volume_before) > tol: volume_before = volume # test if points outside the bounded ellipsoid for i in range(len(coord)): if (coord[i, 0]**2 / a**2 + coord[i, 1]**2 / b**2 + coord[i, 2]**2 / c**2) > 1: point_outside = 'true' break else: point_outside = 'false' if point_outside == 'true': a_before = a b_before = b c_before = c a = a * 2 b = b * 2 c = c * 2 elif point_outside == 'false': a1 = a_before b1 = b_before c1 = c_before a_before = a b_before = b c_before = c a = a - abs(a1 - a) / 2. b = b - abs(b1 - b) / 2. c = c - abs(c1 - c) / 2. volume = 4. / 3. * np.pi * a * b * c """ print(point_outside) print('before =', volume_before) """ if (quiet is False): print('volume =', volume) print('a = ', a, 'b = ', b, 'c = ', c) plot.fit_ellipsoid_plot(coord, a, b, c, 10000) return {'volume': volume, 'a': a, 'b': b, 'c': c, 'bbox': bbox_res}
import basic_functions as bf import matplotlib.pyplot as plt ellipsoid = {'a': 100, 'b': 50, 'c': 30} aggregate = tie.ellipsoid_test_image(ellipsoid, npoints=10000, noise_amplitude=10., angles=(np.pi / 7., np.pi / 6.)) fig = plot.scatter_plot(aggregate) bb.bbox_volume(aggregate) bbox = bb.bbox_optim(aggregate) print(bbox) fig = plot.bbox_plot(aggregate, bbox) rotated_aggregate = bf.rotate_aggregate(aggregate, angles=bbox['angles']) rotated_bbox = bb.compute_bbox(rotated_aggregate) fig = plot.bbox_plot(rotated_aggregate, rotated_bbox) ellipsoid = be.bounding_ellipsoid_optim(aggregate) plot.fit_ellipsoid_plot(rotated_aggregate, ellipsoid) ellipsoid = {'a': 100, 'b': 50, 'c': 30} aggregate = tie.ellipsoid_test_image(ellipsoid, npoints=10000, noise_amplitude=30., angles=(np.pi / 7., np.pi / 6.)) plot.scatter_plot(aggregate) ellipsoid = be.bounding_ellipsoid_optim(aggregate, 1e-3) rotated_aggregate = bf.rotate_aggregate(aggregate,