Python scipy.spatial 模块,ConvexHull() 实例源码

我们从Python开源项目中,提取了以下25个代码示例,用于说明如何使用scipy.spatial.ConvexHull()

项目:meshpy    作者:BerkeleyAutomation    | 项目源码 | 文件源码
def convex_hull(self):
        """Return a 3D mesh that represents the convex hull of the mesh.
        """
        hull = ss.ConvexHull(self.vertices_)
        hull_tris = hull.simplices
        if self.normals_ is None:
            cvh_mesh = Mesh3D(self.vertices_.copy(), hull_tris.copy(), center_of_mass=self.center_of_mass_)
        else:
            cvh_mesh = Mesh3D(self.vertices_.copy(), hull_tris.copy(), normals=self.normals_.copy(), center_of_mass=self.center_of_mass_)
        cvh_mesh.remove_unreferenced_vertices()
        return cvh_mesh
项目:aiida-fleur    作者:broeder-j    | 项目源码 | 文件源码
def determine_convex_hull(formation_en_grid):
    """
    Wraps the scipy.spatial ConvexHull algo for our purposes.
    For now only for 2D phase diagrams
    Adds the points [1.0, 0.0] and [0.0, 1.0], because in material science these
    are always there.

    :params: formation_en_grid: list of points in phase space [[x, formation_energy]]
    :returns: a hul datatype
    """
    import numpy as np
    from scipy.spatial import ConvexHull

    # TODO multi d
    # check if endpoints are in
    if [1.0, 0.0] not in formation_en_grid:
        formation_en_grid.append([1.0, 0.0])
    if [0.0, 0.0] not in formation_en_grid:
        formation_en_grid.append([0.0, 0.0])

    points = np.array(formation_en_grid)
    hull = ConvexHull(points)

    return hull
项目:order    作者:ipudu    | 项目源码 | 文件源码
def compute_vc(self, points):
        """compute the Voronoi cell"""
        #compute S and V
        S = ConvexHull(points).area
        V = ConvexHull(points).volume

        #voronoi cell
        eta = S ** 3 / (36 * np.pi * V ** 2)

        return eta
项目:SyConn    作者:StructuralNeurobiologyLab    | 项目源码 | 文件源码
def convex_hull_area(pts):
    """
    Calculates the surface area from a given point cloud using simplices of
    its convex hull. For the estimation of the synapse contact area, divide by
    a factor of two, in order to get the area of only one face (we assume that
    the contact site is sufficiently thin represented by the points).
    :param pts: np.array of coordinates in nm (scaled)
    :return: Area of the point cloud (nm^2)
    """
    if len(pts) < 4:
        return 0
    area = 0
    try:
        ch = ConvexHull(pts)
        triangles = ch.points[ch.simplices]
        for triangle in triangles:
            area += poly_area(triangle)
    except QhullError as e:
        # warnings.warn("%s encountered during calculation of convex hull "
        #               "area with %d points. Returning 0 nm^2." %
        #               (e, len(pts)), RuntimeWarning)
        pass
    return area
项目:invo    作者:rafidrm    | 项目源码 | 文件源码
def fit_convex_hull(points):
    """ Creates a feasible set by taking a convex hull of the points given. Returns P = { x : Ax >= b }

    Args:
        points (list): Set of numpy points.

    Returns:
        A (numpy): constraint matrix
        b (numpy): constraint vector
    """
    hull = ConvexHull(points)
    m,n = hull.equations.shape
    A = -1 * hull.equations[:,0:n-1]
    b = hull.equations[:,n-1]
    return np.mat(A), np.mat(b).T
项目:meshpy    作者:BerkeleyAutomation    | 项目源码 | 文件源码
def tri_normals(self, align_to_hull=False):
        """Returns a list of the triangle normals.

        Parameters
        ----------
        align_to_hull : bool
            If true, we re-orient the normals to point outward from
            the mesh by using the convex hull.

        Returns
        -------
        :obj:`numpy.ndarray` of float
            A #triangles by 3 array of floats, where each 3-ndarray
            represents the 3D normal vector of the corresponding triangle.
        """
        # compute normals
        v0 = self.vertices_[self.triangles_[:,0],:]
        v1 = self.vertices_[self.triangles_[:,1],:]
        v2 = self.vertices_[self.triangles_[:,2],:]
        n = np.cross(v1 - v0, v2 - v0)
        normals = n / np.tile(np.linalg.norm(n, axis=1)[:,np.newaxis], [1,3])

        # reverse normal based on alignment with convex hull
        if align_to_hull:
            tri_centers = self.tri_centers()
            hull = ss.ConvexHull(tri_centers)
            hull_tris = hull.simplices
            hull_vertex_ind = hull_tris[0][0]
            hull_vertex = tri_centers[hull_vertex_ind]
            hull_vertex_normal = normals[hull_vertex_ind]
            v = hull_vertex.reshape([1,3])
            n = hull_vertex_normal
            ip = (tri_centers - np.tile(hull_vertex,
                  [tri_centers.shape[0], 1])).dot(n)
            if ip[0] > 0:
                normals = -normals
        return normals
项目:PySAT    作者:USGS-Astrogeology    | 项目源码 | 文件源码
def _rubberband(bands, intensities, num_ranges):
    '''Basic rubberband method,
    from p.77 of "IR and Raman Spectroscopy" (OPUS manual)'''
    # create n ranges of equal size in the spectrum
    range_size = len(intensities) // num_ranges
    y = intensities[:range_size * num_ranges].reshape((num_ranges, range_size))
    # find the smallest intensity point in each range
    idx = np.arange(num_ranges) * range_size + np.argmin(y, axis=1)
    # add in the start and end points as well, to avoid weird edge effects
    if idx[0] != 0:
        idx = np.append(0, idx)
    if idx[-1] != len(intensities) - 1:
        idx = np.append(idx, len(intensities) - 1)
    baseline_pts = np.column_stack((bands[idx], intensities[idx]))
    # wrap a rubber band around the baseline points
    hull = ConvexHull(baseline_pts)
    hidx = idx[hull.vertices]
    # take only the bottom side of the hull
    left = np.argmin(bands[hidx])
    right = np.argmax(bands[hidx])
    mask = np.ones(len(hidx), dtype=bool)
    for i in range(len(hidx)):
        if i > right and (i < left or right > left):
            mask[i] = False
        elif i < left and i < right:
            mask[i] = False
    hidx = hidx[mask]
    hidx = hidx[np.argsort(bands[hidx])]
    # interpolate a baseline
    return np.interp(bands, bands[hidx], intensities[hidx])
项目:multi-contact-zmp    作者:stephane-caron    | 项目源码 | 文件源码
def compute_polyhedron_shadow(n, light_poly, ground_poly, inf_dist=1000):
    light_hull = ConvexHull(light_poly)
    ground_hull = ConvexHull(ground_poly)
    light_vertices = [light_poly[i] for i in light_hull.vertices]
    ground_vertices = [ground_poly[i] for i in ground_hull.vertices]
    rays = [gv - lv for gv in ground_vertices for lv in light_vertices]
    return ground_vertices + [v + inf_dist * r
                              for v in ground_vertices for r in rays]
项目:mapsplotlib    作者:tcassou    | 项目源码 | 文件源码
def polygons(latitudes, longitudes, clusters, maptype=MAPTYPE):
    """Plot clusters of points on map, including them in a polygon defining their convex hull.

    :param pandas.Series latitudes: series of sample latitudes
    :param pandas.Series longitudes: series of sample longitudes
    :param pandas.Series clusters: marker clusters, as integers
    :param string maptype: type of maps, see GoogleStaticMapsAPI docs for more info

    :return: None
    """
    width = SCALE * MAX_SIZE
    img, pixels = background_and_pixels(latitudes, longitudes, MAX_SIZE, maptype)

    polygons = []
    for c in clusters.unique():
        in_polygon = clusters == c
        if in_polygon.sum() < 3:
            print '[WARN] Cannot draw polygon for cluster {} - only {} samples.'.format(c, in_polygon.sum())
            continue
        cluster_pixels = pixels.loc[clusters == c]
        polygons.append(Polygon(cluster_pixels.iloc[ConvexHull(cluster_pixels).vertices], closed=True))

    plt.figure(figsize=(10, 10))
    ax = plt.subplot(111)
    plt.imshow(np.array(img))                                               # Background map
    p = PatchCollection(polygons, cmap='jet', alpha=0.15)                   # Collection of polygons
    p.set_array(clusters.unique())
    ax.add_collection(p)
    plt.scatter(                                                            # Scatter plot
        pixels['x_pixel'],
        pixels['y_pixel'],
        c=clusters,
        s=width / 40,
        linewidth=0,
        alpha=0.25,
    )
    plt.gca().invert_yaxis()                                                # Origin of map is upper left
    plt.axis([0, width, width, 0])                                          # Remove margin
    plt.axis('off')
    plt.tight_layout()
    plt.show()
项目:pygeotools    作者:dshean    | 项目源码 | 文件源码
def get_edges(a, convex=False):
    a = checkma(a)
    #Need to deal with RGB images here
    #Need to be careful, probably want to take minimum value from masks
    if a.ndim == 3:
        #Assume that the same mask applies to each band
        #Only create edges for one band
        b = a[:,:,0]
        #Could convert to HSL and do edges for L channel
        #b = a[:,:,0].mask + a[:,:,1].mask + a[:,:,2].mask
    else:
        b = a

    #Compute edges along both axes, need both to handle undercuts
    #These are inclusive, indices indicate position of unmasked data
    edges0 = np.ma.notmasked_edges(b, axis=0)
    edges1 = np.ma.notmasked_edges(b, axis=1)
    edges = np.array([np.concatenate([edges0[0][0], edges0[1][0], edges1[1][0], edges1[0][0]]), np.concatenate([edges0[0][1], edges0[1][1], edges1[1][1], edges1[0][1]])])

    #This is a rough outline - needs testing
    if convex:
        from scipy.spatial import ConvexHull
        #hull = ConvexHull(edges.T)
        #edges = edges.T[hull.simplices]
        #This is in scipy v0.14
        #edges0 = edges1 = hull.vertices

    return edges0, edges1, edges
项目:EasyMKL    作者:jmikko    | 项目源码 | 文件源码
def convex_hull(self, model):
        train = np.array(model.data)
        global t1,t2
        t1,t2 = [],[]

        for i,example in enumerate(train):
            if example[2]==1:
                t1.append(example[0:2])
            else:
                t2.append(example[0:2])
        global ch1,ch2,has_margin
        if (has_margin):
            self.ax.lines.pop(len(t1)+len(t2)-1)
        for i in range(ch1+ch2):
            self.ax.lines.pop(len(t1)+len(t2)-1)
        if len(t1) > 2:
            X1 = np.matrix(np.array(t1))
            hull1 = ConvexHull(X1);    
            for simplex in hull1.simplices:
                self.ax.plot(X1[simplex,0],X1[simplex,1], color='grey',linewidth=1)
            ch1 = len(hull1.simplices)

        if len(t2) > 2:
            X2 = np.matrix(np.array(t2))
            hull2 = ConvexHull(X2);
            for simplex in hull2.simplices:
                self.ax.plot(X2[simplex,0],X2[simplex,1], color='0.25')
            #self.ax.plot(cx2,cy2,'+',ms=10, color="blue")
            ch2 = len(hull2.simplices)
        global isFitted
        #print len(train),"\t"
        #if isFitted:
        #    self.draw_distance(model,model.clf.gamma)
        self.set_dim()
项目:OBB    作者:chrisdevito    | 项目源码 | 文件源码
def build_from_hull(self):
        """
        Test oriented bounding box algorithm using convex hull points.

        Raises:
            None

        Returns:
            EigenVectors(OpenMaya.MVector)
            CenterPoint(OpenMaya.MVector)
            BoundingExtents(OpenMaya.MVector)
        """
        npPointList = [[self.points[i].x, self.points[i].y, self.points[i].z]
                       for i in xrange(self.points.length())]

        try:
            hull = ConvexHull(npPointList)
        except NameError:
            raise RuntimeError(
                "From hull method unavailable because"
                " scipy cannot be imported."
                "Please install it if you need it.")

        indices = hull.simplices
        vertices = npPointList[indices]
        hullPoints = list(vertices.flatten())
        hullTriPoints = list(indices.flatten())

        hullArray = OpenMaya.MVectorArray()
        for ind in xrange(0, len(hullPoints), 3):
            hullArray.append(
                OpenMaya.MVector(
                    hullPoints[ind], hullPoints[ind+1], hullPoints[ind+2]))

        triPoints = OpenMaya.MIntArray()
        for tri in xrange(len(hullTriPoints)):
            triPoints.append(tri)

        return self.build_from_triangles(points=hullArray, triangles=triPoints)
项目:deeptravel    作者:keon    | 项目源码 | 文件源码
def generate_one_example(n_nodes):
    points = numpy.random.rand(n_nodes, 2)
    hull = ConvexHull(points)  # scipy.spatial.ConvexHull will generate points in CCW order
    v = hull.vertices
    # v = numpy.roll(v, -list(v).index(numpy.min(v)))  # start from the smallest indice
    return points, v + 1
项目:pyhiro    作者:wanweiwei07    | 项目源码 | 文件源码
def oriented_bounds_2D(points):
    '''
    Find an oriented bounding box for a set of 2D points.

    Arguments
    ----------
    points: (n,2) float, 2D points

    Returns
    ----------
    transform: (3,3) float, homogenous 2D transformation matrix to move the input set of 
               points to the FIRST QUADRANT, so no value is negative. 
    rectangle: (2,) float, size of extents once input points are transformed by transform
    '''
    c = ConvexHull(np.asanyarray(points))
    # (n,2,3) line segments
    hull = c.points[c.simplices] 
    # (3,n) points on the hull to check against
    dot_test = c.points[c.vertices].reshape((-1,2)).T
    edge_vectors = unitize(np.diff(hull, axis=1).reshape((-1,2)))
    perp_vectors = np.fliplr(edge_vectors) * [-1.0,1.0]
    bounds = np.zeros((len(edge_vectors), 4))
    for i, edge, perp in zip(range(len(edge_vectors)),
                             edge_vectors, 
                             perp_vectors):
        x = np.dot(edge, dot_test)
        y = np.dot(perp, dot_test)
        bounds[i] = [x.min(), y.min(), x.max(), y.max()]

    extents  = np.diff(bounds.reshape((-1,2,2)), axis=1).reshape((-1,2))
    area     = np.product(extents, axis=1)
    area_min = area.argmin()

    offset = -bounds[area_min][0:2]
    theta  = np.arctan2(*edge_vectors[area_min][::-1])

    transform = transformation_2D(offset, theta)
    rectangle = extents[area_min]

    return transform, rectangle
项目:pyhiro    作者:wanweiwei07    | 项目源码 | 文件源码
def convex_hull(mesh, clean=True):
    '''
    Get a new Trimesh object representing the convex hull of the 
    current mesh. Requires scipy >.12.

    Argments
    --------
    clean: boolean, if True will fix normals and winding
           to be coherent (as qhull/scipy outputs are not)

    Returns
    --------
    convex: Trimesh object of convex hull of current mesh
    '''

    type_trimesh = type_named(mesh, 'Trimesh')
    c = ConvexHull(mesh.vertices.view(np.ndarray).reshape((-1,3)))

    vid = np.sort(c.vertices)
    mask = np.zeros(len(c.points), dtype=np.int64)
    mask[vid] = np.arange(len(vid))

    faces    = mask[c.simplices]
    vertices = c.points[vid].copy()

    convex = type_trimesh(vertices = vertices, 
                          faces    = faces,
                          process  = True)
    if clean:
        # the normals and triangle winding returned by scipy/qhull's
        # ConvexHull are apparently random, so we need to completely fix them
        convex.fix_normals()
    return convex
项目:pyhiro    作者:wanweiwei07    | 项目源码 | 文件源码
def planar_hull(points, normal, origin=None, input_convex=False):
    '''
    Find the convex outline of a set of points projected to a plane.

    Arguments
    -----------
    points: (n,3) float, input points
    normal: (3) float vector, normal vector of plane
    origin: (3) float, location of plane origin
    input_convex: bool, if True we assume the input points are already from
                  a convex hull which provides a speedup. 

    Returns
    -----------
    hull_lines: (n,2,2) set of unordered line segments
    T:          (4,4) float, transformation matrix 
    '''
    if origin is None:
        origin = np.zeros(3)
    if not input_convex:
        pass
    planar, T = project_to_plane(points,
                                 plane_normal     = normal,
                                 plane_origin     = origin,
                                 return_planar    = False,
                                 return_transform = True)
    hull_edges = ConvexHull(planar[:,0:2]).simplices
    hull_lines = planar[hull_edges]
    planar_z = planar[:,2]
    height = np.array([planar_z.min(),
                       planar_z.max()])
    return hull_lines, T, height
项目:wake-exchange    作者:byuflowlab    | 项目源码 | 文件源码
def calculate_boundary(vertices):

    # find the points that actually comprise a convex hull
    hull = ConvexHull(list(vertices))

    # keep only vertices that actually comprise a convex hull and arrange in CCW order
    vertices = vertices[hull.vertices]

    # get the real number of vertices
    nVertices = vertices.shape[0]

    # initialize normals array
    unit_normals = np.zeros([nVertices, 2])

    # determine if point is inside or outside of each face, and distance from each face
    for j in range(0, nVertices):

        # calculate the unit normal vector of the current face (taking points CCW)
        if j < nVertices - 1:  # all but the set of point that close the shape
            normal = np.array([vertices[j+1, 1]-vertices[j, 1],
                               -(vertices[j+1, 0]-vertices[j, 0])])
            unit_normals[j] = normal/np.linalg.norm(normal)
        else:   # the set of points that close the shape
            normal = np.array([vertices[0, 1]-vertices[j, 1],
                               -(vertices[0, 0]-vertices[j, 0])])
            unit_normals[j] = normal/np.linalg.norm(normal)

    return vertices, unit_normals
项目:SyConn    作者:StructuralNeurobiologyLab    | 项目源码 | 文件源码
def get_normals(hull, number_fitnodes=12):
    """
    Calculate normals from given hull points using local convex hull fitting.
    Orientation of normals is found using local center of mass.
    :param hull: 3D coordinates of points representing cell hull
    :type hull: np.array
    :return: normals for each hull point
    """
    normals = np.zeros_like(hull, dtype=np.float)
    hull_tree = spatial.cKDTree(hull)
    dists, nearest_nodes_ixs = hull_tree.query(hull, k=number_fitnodes,
                                                distance_upper_bound=1000)
    for ii, nearest_ixs in enumerate(nearest_nodes_ixs):
        nearest_nodes = hull[nearest_ixs[dists[ii] != np.inf]]
        ch = ConvexHull(nearest_nodes, qhull_options='QJ Pp')
        triangles = ch.points[ch.simplices]
        normal = np.zeros((3), dtype=np.float)
        # average normal
        for triangle in triangles:
            cnt = 0
            n_help = unit_normal(triangle[0], triangle[1], triangle[2])
            if not np.any(np.isnan(n_help)):
                normal += np.abs(n_help)
        normal /= np.linalg.norm(normal)
        normal_sign = (hull[ii] - np.mean(nearest_nodes, axis=0))/\
                      np.abs(hull[ii] - np.mean(nearest_nodes, axis=0))
        normals[ii] = normal * normal_sign
    return normals
项目:DCN    作者:alexnowakvila    | 项目源码 | 文件源码
def convexhull_example(self, length, scales):
        points = np.random.uniform(0, 1, [length, self.input_size])
        target = -1 * np.ones([length])
        ch = ConvexHull(points).vertices
        argmin = np.argsort(ch)[0]
        ch = list(ch[argmin:]) + list(ch[:argmin])
        target[:len(ch)] = np.array(ch)
        target += 1
        return points, target
项目:PyMaid    作者:schlegelp    | 项目源码 | 文件源码
def _in_volume_convex(points, volume, remote_instance=None, approximate=False, ignore_axis=[]):
    """ Uses scipy to test if points are within a given CATMAID volume.
    The idea is to test if adding the point to the cloud would change the
    convex hull. 
    """

    if remote_instance is None:
        if 'remote_instance' in sys.modules:
            remote_instance = sys.modules['remote_instance']
        elif 'remote_instance' in globals():
            remote_instance = globals()['remote_instance']

    if type(volume) == type(str()):
        volume = fetch.get_volume(volume, remote_instance)

    verts = volume['vertices']

    if not approximate:
        intact_hull = ConvexHull(verts)
        intact_verts = list(intact_hull.vertices)

        if isinstance(points, list):
            points = np.array(points)
        elif isinstance(points, pd.DataFrame):
            points = points.to_matrix()

        return [list(ConvexHull(np.append(verts, list([p]), axis=0)).vertices) == intact_verts for p in points]
    else:
        bbox = [(min([v[0] for v in verts]), max([v[0] for v in verts])),
                (min([v[1] for v in verts]), max([v[1] for v in verts])),
                (min([v[2] for v in verts]), max([v[2] for v in verts]))
                ]

        for a in ignore_axis:
            bbox[a] = (float('-inf'), float('inf'))

        return [False not in [bbox[0][0] < p.x < bbox[0][1], bbox[1][0] < p.y < bbox[1][1], bbox[2][0] < p.z < bbox[2][1], ] for p in points]
项目:pycollimate    作者:fvelotti    | 项目源码 | 文件源码
def get_hull(self):
        points = self.get_points_hull()
        return ConvexHull(points)
项目:boundary-detection    作者:marcos-sandim    | 项目源码 | 文件源码
def run_hpr(grid, viewpoint, gamma, boundary):
    """Runs the HPR operator for a single viewpoint and its neighborhood

    Runs the HPR operator for a single viewpoint and its neighborhood.

    Args:
        grid: The support grid containing the data
        viewpoint: The viewpoint to be used by the HPR operator.
        gamma: The exponent used to flip the points.
        boundary: An array of flags used as output.
    """
    candidates = grid.get_candidates(viewpoint)

    if (candidates.shape[0] == 0):
        return

    if (candidates.shape[0] <= grid.dimension):
        boundary[candidates] = True
        return

    flipped = exponential_flip(grid.points[candidates], viewpoint, gamma)

    # add the viewpoint to the end of the list
    flipped = np.vstack([flipped, np.zeros([1, grid.dimension])])

    hull = ConvexHull(flipped)
    visible_idx = hull.vertices

    # remove the index corresponding to the viewpoint
    visible_idx.sort()
    visible_idx = np.delete(visible_idx, -1)

    visible_idx = candidates[visible_idx]

    boundary[visible_idx] = True
项目:multi-contact-zmp    作者:stephane-caron    | 项目源码 | 文件源码
def compute_polygon_shadow(n, light_poly, ground_poly):
    """Polygons are described by their convex hulls.

    n -- normal vector used in ZMP computations
    light_poly -- polygon acting as light source
    ground_poly -- polygon whose shadow is projected under the light one

    """
    t = [n[2] - n[1], n[0] - n[2], n[1] - n[0]]
    n = array(n) / pymanoid.toolbox.norm(n)
    t = array(t) / pymanoid.toolbox.norm(t)
    b = cross(n, t)

    light_proj = [array([dot(t, p), dot(b, p)]) for p in light_poly]
    light_hull = ConvexHull(light_proj)
    ground_proj = [array([dot(t, p), dot(b, p)]) for p in ground_poly]
    ground_hull = ConvexHull(ground_proj)
    vertex2poly = {i: j for (i, j) in enumerate(ground_hull.vertices)}
    light_vertices = [light_proj[i] for i in light_hull.vertices]
    ground_vertices = [ground_proj[i] for i in ground_hull.vertices]
    mink_diff = [gv - lv for gv in ground_vertices for lv in light_vertices]

    try:
        u_low, u_high = pymanoid.draw.pick_2d_extreme_rays(mink_diff)
    except pymanoid.exceptions.UnboundedPolyhedron:
        big_dist = 1000  # [m]
        vertices = [
            array([-big_dist, -big_dist, light_poly[0][2]]),
            array([-big_dist, +big_dist, light_poly[0][2]]),
            array([+big_dist, -big_dist, light_poly[0][2]]),
            array([+big_dist, +big_dist, light_poly[0][2]])]
        return vertices, []

    nb_vertices = len(ground_vertices)
    vertex_indices = range(len(ground_vertices))

    def f_low(i):
        return cross(u_low, ground_vertices[i])

    def f_high(i):
        return cross(u_high, ground_vertices[i])

    v_low = min(vertex_indices, key=f_low)
    v_high = max(vertex_indices, key=f_high)
    vertices = [ground_poly[vertex2poly[vertex_index % nb_vertices]]
                for vertex_index in xrange(v_high, (v_low + nb_vertices + 1))]
    rays = [u_low[0] * t + u_low[1] * b,
            u_high[0] * t + u_high[1] * b]
    return vertices, rays
项目:imgProcessor    作者:radjkarl    | 项目源码 | 文件源码
def sortCorners(corners):
    '''
    sort the corners of a given quadrilateral of the type
    corners : [ [xi,yi],... ]

    to an anti-clockwise order starting with the bottom left corner

    or (if plotted as image where y increases to the bottom):
    clockwise, starting top left
    '''
    corners = np.asarray(corners)
    # bring edges in order:
    corners2 = corners[ConvexHull(corners).vertices]

    if len(corners2) == 3:
        # sometimes ConvexHull one point is missing because it is
        # within the hull triangle
        # find the right position of set corner as the minimum perimeter
        # built with that point as different indices
        for c in corners:
            if c not in corners2:
                break
        perimeter = []
        for n in range(0, 4):
            corners3 = np.insert(corners2, n, c, axis=0)
            perimeter.append(
                np.linalg.norm(
                    np.diff(
                        corners3,
                        axis=0),
                    axis=1).sum())
        n = np.argmin(perimeter)
        corners2 = np.insert(corners2, n, c, axis=0)

    # find the edge with the right angle to the quad middle:
    mn = corners2.mean(axis=0)
    d = (corners2 - mn)
    ascent = np.arctan2(d[:, 1], d[:, 0])
    bl = np.abs(BL_ANGLE + ascent).argmin()
    # build a index list starting with bl:
    i = list(range(bl, 4))
    i.extend(list(range(0, bl)))
    return corners2[i]
项目:learning-to-prune    作者:timvieira    | 项目源码 | 文件源码
def lambda_cone(accuracy, runtime, ax, c, conesize, lines=1, aspect_equal=1):
    #ax.scatter(runtime, accuracy, c=tradeoff, lw=0)

    P = zip(runtime, accuracy)
    #P.extend([(0,0), (runtime.max()+0.5e7, accuracy.max())])
    P.extend([(runtime.min()-.1*runtime.ptp(), 0),
              (runtime.max()+.1*runtime.ptp(), accuracy.max())])

#    tradeoff = np.array(list(tradeoff) + [np.inf, 0.0])

    hull = ConvexHull(P)
    v = hull.points[hull.vertices]

    ddd = []

    V = len(hull.vertices)
    for i in range(V):
        x1,y1 = v[(i-1) % V]
        x,y = v[i]
        x3,y3 = v[(i+1) % V]

        # slopes give a range for lambda values to try.
        m12 = (y-y1)/(x-x1)
        m23 = (y3-y)/(x3-x)

        # Note: This filter skips cases where the convex hull contains a
        # segments (edge) that is beneath the fronter (we know this because of
        # the orientation of the edge)..
        if m12 >= m23:
            continue

        ddd.append([m12, m23, x, y])

        ax.add_artist(Polygon([[x,y],
                               point(x, y, m12, -conesize),
                               point(x, y, m23, -conesize),
                               [x,y]],
                              linewidth=0,
                              alpha=0.5,
                              color=c,
                          ))

        if lines:
            ax.plot([x1,x,x3], [y1,y,y3], c=c, alpha=0.5)

    if aspect_equal:
        ax.set_aspect('equal')
    ax.grid(True)
    return ddd