Пример #1
0
def _sort_vertex_neighbors(key, nbrs, xyz, ccw=True):
    if len(nbrs) == 1:
        return nbrs
    ordered = nbrs[0:1]
    a = xyz[key]
    for i, nbr in enumerate(nbrs[1:]):
        c = xyz[nbr]
        pos = 0
        b = xyz[ordered[pos]]
        while not is_ccw_xy(a, b, c):
            pos += 1
            if pos > i:
                break
            b = xyz[ordered[pos]]
        if pos == 0:
            pos = -1
            b = xyz[ordered[pos]]
            while is_ccw_xy(a, b, c):
                pos -= 1
                if pos < -len(ordered):
                    break
                b = xyz[ordered[pos]]
            pos += 1
        ordered.insert(pos, nbr)
    if not ccw:
        return ordered[::-1]
    return ordered
Пример #2
0
def _sort_neighbours(network, ccw=True):
    sorted_neighbours = {}
    xyz = {key: network.vertex_coordinates(key) for key in network.vertices()}
    for key in network.vertices():
        nbrs = network.vertex_neighbours(key)
        if len(nbrs) == 1:
            sorted_neighbours[key] = nbrs
            continue
        ordered = [nbrs[0]]
        a = xyz[key]
        for i, nbr in enumerate(nbrs[1:]):
            c = xyz[nbr]
            pos = 0
            b = xyz[ordered[pos]]
            while not is_ccw_xy(a, b, c):
                pos += 1
                if pos > i:
                    break
                b = xyz[ordered[pos]]
            if pos == 0:
                pos = -1
                b = xyz[ordered[pos]]
                while is_ccw_xy(a, b, c):
                    pos -= 1
                    if pos < -len(ordered):
                        break
                    b = xyz[ordered[pos]]
                pos += 1
            ordered.insert(pos, nbr)
        if not ccw:
            sorted_neighbours[key] = ordered[::-1]
        sorted_neighbours[key] = ordered
    for key, nbrs in sorted_neighbours.items():
        network.vertex[key]['sorted_neighbours'] = nbrs[::-1]
    return sorted_neighbours
Пример #3
0
def _find_first_neighbor(key, network):
    nbrs = list(network.halfedge[key].keys())
    if len(nbrs) == 1:
        return nbrs[0]
    ab = [-1.0, -1.0, 0.0]
    a = network.vertex_coordinates(key, 'xyz')
    b = [a[0] + ab[0], a[1] + ab[1], 0]
    angles = []
    for nbr in nbrs:
        c = network.vertex_coordinates(nbr, 'xyz')
        ac = [c[0] - a[0], c[1] - a[1], 0]
        alpha = angle_vectors(ab, ac)
        if is_ccw_xy(a, b, c, True):
            alpha = PI2 - alpha
        angles.append(alpha)
    return nbrs[angles.index(min(angles))]
Пример #4
0
def network_node_find_first_neighbor(network, key):
    nbrs = network.neighbors(key)
    if len(nbrs) == 1:
        return nbrs[0]
    ab = [-1.0, -1.0, 0.0]
    a = network.node_coordinates(key, 'xyz')
    b = [a[0] + ab[0], a[1] + ab[1], 0]
    angles = []
    for nbr in nbrs:
        c = network.node_coordinates(nbr, 'xyz')
        ac = [c[0] - a[0], c[1] - a[1], 0]
        alpha = angle_vectors(ab, ac)
        if is_ccw_xy(a, b, c, True):
            alpha = PI2 - alpha
        angles.append(alpha)
    return nbrs[angles.index(min(angles))]
Пример #5
0
def _find_first_neighbour(key, network):
    nbrs = list(network.halfedge[key].keys())
    if len(nbrs) == 1:
        return nbrs[0]
    vu = [-1.0, -1.0, 0.0]
    a = network.vertex_coordinates(key, 'xyz')
    b = [a[0] + vu[0], a[1] + vu[1], 0]
    cw = []
    for nbr in nbrs:
        c = network.vertex_coordinates(nbr, 'xyz')
        if not is_ccw_xy(a, b, c, True):
            cw.append(nbr)
    if cw:
        nbrs = cw
    angles = []
    v = [network.vertex[key][_] for _ in 'xyz']
    for nbr in nbrs:
        w = [network.vertex[nbr][_] for _ in 'xyz']
        vw = [w[0] - v[0], w[1] - v[1], 0]
        angles.append(angle_vectors(vu, vw))
    if cw:
        return nbrs[angles.index(min(angles))]
    return nbrs[angles.index(max(angles))]
Пример #6
0
def _is_point_in_edgezone(p, p0, p1):
    n = cross_vectors(p1 - p0, [0, 0, 1.])
    return (is_ccw_xy(p0 - p0, n, p - p0)
            and not is_ccw_xy(p0 - p0, p1 - p0, p - p0)
            and not is_ccw_xy(p1 - p1, n, p - p1))
Пример #7
0
def network_embed_in_plane(network, fix=None, straightline=True):
    """Embed the network in the plane.

    Parameters
    ----------
    network : Network
        A network object.
    fix : list (None)
        Two fixed points.
    straightline : bool (True)
        Embed using straight lines.

    Returns
    -------
    bool
        True if the embedding was successful.
        False otherwise.

    Raises
    ------
    ImportError
        If NetworkX is not installed.

    Warning
    -------
    This function uses the Python package NetworkX. NetworkX can be *pip installed*.

    Examples
    --------
    .. plot::
        :include-source:

        import compas

        from compas.datastructures import Network
        from compas.topology import network_embed_in_plane
        from compas.plotters import NetworkPlotter

        network = Network.from_obj(compas.get('fink.obj'))

        embedding = network.copy()

        fix = (1, 12)

        if network_embed_in_plane(embedding, fix=fix):

            plotter = NetworkPlotter(embedding)

            plotter.draw_lines([{'start': network.vertex_coordinates(u, 'xy'),
                                  'end': network.vertex_coordinates(v, 'xy'),
                                  'color': '#cccccc'} for u, v in network.edges()])

            plotter.draw_vertices(radius=0.3,
                                  text={key: key for key in embedding.vertices()},
                                  facecolor={key: '#ff0000' for key in fix})

            plotter.draw_edges()
            plotter.show()

    """
    try:
        import networkx as nx
    except ImportError:
        print(
            "NetworkX is not installed. Get NetworkX at https://networkx.github.io/."
        )
        raise

    x = network.get_vertices_attribute('x')
    y = network.get_vertices_attribute('y')
    xmin, xmax = min(x), max(x)
    ymin, ymax = min(y), max(y)
    xspan = xmax - xmin
    yspan = ymax - ymin

    edges = [(u, v) for u, v in network.edges()
             if not network.is_vertex_leaf(u) and not network.is_vertex_leaf(v)
             ]

    is_embedded = False

    count = 100
    while count:
        graph = nx.Graph(edges)
        pos = nx.spring_layout(graph,
                               2,
                               iterations=100,
                               scale=max(xspan, yspan))
        if not _network_are_edges_crossed(edges, pos):
            is_embedded = True
            break
        count -= 1

    if not is_embedded:
        return False

    if fix:
        a, b = fix
        p0 = network.vertex_coordinates(a, 'xy')
        p1 = network.vertex_coordinates(b, 'xy')
        p2 = pos[b]
        vec0 = [
            network.vertex[b][axis] - network.vertex[a][axis] for axis in 'xy'
        ]
        vec1 = [pos[b][axis] - pos[a][axis] for axis in (0, 1)]
        # rotate
        a = angle_vectors_xy(vec0, vec1)
        if is_ccw_xy(p0, p1, p2):
            a = 2 * pi - a
        cosa = cos(a)
        sina = sin(a)
        for key in pos:
            x, y = pos[key]
            pos[key][0] = cosa * x - sina * y
            pos[key][1] = sina * x + cosa * y
        # scale
        l0 = (vec0[0]**2 + vec0[1]**2)**0.5
        l1 = (vec1[0]**2 + vec1[1]**2)**0.5
        scale = l0 / l1
        for key in pos:
            pos[key][0] *= scale
            pos[key][1] *= scale
        # translate
        t = network.vertex[fix[0]]['x'] - pos[fix[0]][0], network.vertex[
            fix[0]]['y'] - pos[fix[0]][1]
        for key in pos:
            pos[key][0] += t[0]
            pos[key][1] += t[1]

    # update network vertex coordinates
    for key in network.vertices():
        if key in pos:
            network.vertex[key]['x'] = pos[key][0]
            network.vertex[key]['y'] = pos[key][1]

    return True
Пример #8
0
def network_embed_in_plane(network, fixed=None, straightline=True):
    """Embed the network in the plane.

    Parameters
    ----------
    network : Network
        A network object.
    fixed : list (None)
        Two fixed points.
    straightline : bool (True)
        Embed using straight lines.

    Returns
    -------
    bool
        True if the embedding was successful.
        False otherwise.

    Raises
    ------
    ImportError
        If NetworkX is not installed.

    Examples
    --------
    >>>
    """
    try:
        import networkx as nx
    except ImportError:
        print(
            "NetworkX is not installed. Get NetworkX at https://networkx.github.io/."
        )
        raise

    x = network.nodes_attribute('x')
    y = network.nodes_attribute('y')
    xmin, xmax = min(x), max(x)
    ymin, ymax = min(y), max(y)
    xspan = xmax - xmin
    yspan = ymax - ymin

    edges = [(u, v) for u, v in network.edges()
             if not network.is_leaf(u) and not network.is_leaf(v)]

    is_embedded = False

    count = 100
    while count:
        graph = nx.Graph(edges)
        pos = nx.spring_layout(graph, iterations=100, scale=max(xspan, yspan))
        if not _are_edges_crossed(edges, pos):
            is_embedded = True
            break
        count -= 1

    if not is_embedded:
        return False

    if fixed:
        a, b = fixed
        p0 = network.node_attributes(a, 'xy')
        p1 = network.node_attributes(b, 'xy')
        p2 = pos[b]
        vec0 = subtract_vectors_xy(p1, p0)
        vec1 = subtract_vectors_xy(pos[b], pos[a])
        # rotate
        angle = angle_vectors_xy(vec0, vec1)
        if is_ccw_xy(p0, p1, p2):
            angle = 2 * pi - angle
        cosa = cos(angle)
        sina = sin(angle)
        for key in pos:
            x, y = pos[key]
            pos[key][0] = cosa * x - sina * y
            pos[key][1] = sina * x + cosa * y
        # scale
        l0 = (vec0[0]**2 + vec0[1]**2)**0.5
        l1 = (vec1[0]**2 + vec1[1]**2)**0.5
        scale = l0 / l1
        for key in pos:
            pos[key][0] *= scale
            pos[key][1] *= scale
        # translate
        t = subtract_vectors_xy(p0, pos[a])
        for key in pos:
            pos[key][0] += t[0]
            pos[key][1] += t[1]

    # update network node coordinates
    for key in network.nodes():
        if key in pos:
            network.node_attributes(key, 'xy', pos[key])

    return True
Пример #9
0
def network_embed_in_plane(network, fix=None, straightline=True):
    """Embed the network in the plane.

    Parameters:
        network (compas.datastructures.network.Network): The network object.

        fix (list): Optional.
            Two fixed points.
            Default is ``None``.

        straightline (bool): Optional.
            Embed using straight lines.
            Default is ``True``.

    Returns:
        bool:
        ``True`` if the embedding was successful.
        ``False`` otherwise.

    Raises:
        ImportError: If NetworkX is not installed.

    Example:

        .. plot::
            :include-source:

            import compas
            from compas.datastructures.network import Network
            from compas.visualization.plotters import NetworkPlotter
            from compas.datastructures.network.algorithms import network_embed_in_plane

            network = Network.from_obj(compas.get_data('fink.obj'))
            embedding = network.copy()

            fix = (1, 12)

            if network_embed_in_plane(embedding, fix=fix):

                plotter = NetworkPlotter(embedding)

                points = []
                for key in network:
                    points.append({
                        'pos': network.vertex_coordinates(key, 'xy'),
                        'radius': 0.1
                    })

                lines = []
                for u, v in network.edges():
                    lines.append({
                        'start': network.vertex_coordinates(u, 'xy'),
                        'end'  : network.vertex_coordinates(v, 'xy'),
                        'color': '#cccccc',
                    })

                plotter.draw_xlines(lines)
                plotter.draw_xpoints(points)

                plotter.draw_edges()
                plotter.draw_vertices(facecolor={key: ('#ff0000' if key in fix else '#ffffff') for key in embedding.vertices()}, text={key: key for key in fix})

                plotter.show()

    """
    try:
        import networkx as nx
    except ImportError:
        print(
            "NetworkX is not installed. Get NetworkX at https://networkx.github.io/."
        )
        raise

    x = network.get_vertices_attribute('x')
    y = network.get_vertices_attribute('y')
    xmin, xmax = min(x), max(x)
    ymin, ymax = min(y), max(y)
    xspan = xmax - xmin
    yspan = ymax - ymin

    edges = [(u, v) for u, v in network.edges()
             if not network.is_vertex_leaf(u) and not network.is_vertex_leaf(v)
             ]

    is_embedded = False

    count = 100
    while count:
        graph = nx.Graph(edges)
        pos = nx.spring_layout(graph,
                               2,
                               iterations=100,
                               scale=max(xspan, yspan))
        if not _network_are_edges_crossed(edges, pos):
            is_embedded = True
            break
        count -= 1

    if not is_embedded:
        return False

    if fix:
        a, b = fix
        p0 = network.vertex_coordinates(a, 'xy')
        p1 = network.vertex_coordinates(b, 'xy')
        p2 = pos[b]
        vec0 = [network[b][axis] - network[a][axis] for axis in 'xy']
        vec1 = [pos[b][axis] - pos[a][axis] for axis in (0, 1)]
        # rotate
        a = angle_smallest_vectors_xy(vec0, vec1)
        if is_ccw_xy(p0, p1, p2):
            a = 2 * pi - a
        cosa = cos(a)
        sina = sin(a)
        for key in pos:
            x, y = pos[key]
            pos[key][0] = cosa * x - sina * y
            pos[key][1] = sina * x + cosa * y
        # scale
        l0 = (vec0[0]**2 + vec0[1]**2)**0.5
        l1 = (vec1[0]**2 + vec1[1]**2)**0.5
        scale = l0 / l1
        for key in pos:
            pos[key][0] *= scale
            pos[key][1] *= scale
        # translate
        t = network[fix[0]]['x'] - pos[fix[0]][0], network[fix[0]]['y'] - pos[
            fix[0]][1]
        for key in pos:
            pos[key][0] += t[0]
            pos[key][1] += t[1]

    # update network vertex coordinates
    for key in network:
        if key in pos:
            network[key]['x'] = pos[key][0]
            network[key]['y'] = pos[key][1]

    return True