Exemplo n.º 1
0
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
Exemplo n.º 2
0
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}
Exemplo n.º 3
0
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,