Example #1
0
def compute_sag(pattern, opening):
    u, v = opening[0]
    if pattern.vertex_attribute(u, 'is_fixed'):
        a = pattern.vertex_attributes(u, 'xyz')
        aa = pattern.vertex_attributes(v, 'xyz')
    else:
        a = pattern.vertex_attributes(v, 'xyz')
        aa = pattern.vertex_attributes(u, 'xyz')
    u, v = opening[-1]
    if pattern.vertex_attribute(u, 'is_fixed'):
        b = pattern.vertex_attributes(u, 'xyz')
        bb = pattern.vertex_attributes(v, 'xyz')
    else:
        b = pattern.vertex_attributes(v, 'xyz')
        bb = pattern.vertex_attributes(u, 'xyz')
    span = distance_point_point_xy(a, b)
    apex = intersection_line_line_xy((a, aa), (b, bb))
    if apex is None:
        rise = 0.0
    else:
        midspan = midpoint_point_point_xy(a, b)
        rise = 0.5 * distance_point_point_xy(midspan, apex)
    sag = rise / span
    return sag
Example #2
0
def parallelise_edges(xy, edges, targets, i_nbrs, ij_e, fixed=None, kmax=100, lmin=None, lmax=None, callback=None):
    """Parallelise the edges of a mesh to given target vectors.

    Parameters
    ----------
    xy : list
        The XY coordinates of the vertices of the edges.
    edges : list
        The edges as pairs of indices in ``xy``.
    targets : list
        A target vector for every edge.
    i_nbrs : dict
        A list of neighbours per vertex.
    ij_e : dict
        An edge index per vertex pair.
    fixed : list, optional
        The fixed nodes of the mesh.
        Default is ``None``.
    kmax : int, optional
        Maximum number of iterations.
        Default is ``100``.
    lmin : list, optional
        Minimum length per edge.
        Default is ``None``.
    lmax : list, optional
        Maximum length per edge.
        Default is ``None``.
    callback : callable, optional
        A user-defined callback function to be executed after every iteration.
        Default is ``None``.

    Returns
    -------
    None

    Examples
    --------
    >>>
    """
    if callback:
        if not callable(callback):
            raise Exception('The provided callback is not callable.')

    fixed = fixed or []
    fixed = set(fixed)

    n = len(xy)

    for k in range(kmax):
        xy0 = [[x, y] for x, y in xy]
        uv = [[xy[j][0] - xy[i][0], xy[j][1] - xy[i][1]] for i, j in edges]
        lengths = [(dx**2 + dy**2)**0.5 for dx, dy in uv]

        if lmin:
            lengths[:] = [max(a, b) for a, b in zip(lengths, lmin)]

        if lmax:
            lengths[:] = [min(a, b) for a, b in zip(lengths, lmax)]

        for j in range(n):
            if j in fixed:
                continue

            nbrs = i_nbrs[j]
            x, y = 0.0, 0.0

            for i in nbrs:
                ax, ay = xy0[i]

                if (i, j) in ij_e:
                    e = ij_e[(i, j)]
                    l = lengths[e]  # noqa: E741
                    tx, ty = targets[e]
                    x += ax + l * tx
                    y += ay + l * ty

                else:
                    e = ij_e[(j, i)]
                    l = lengths[e]  # noqa: E741
                    tx, ty = targets[e]
                    x += ax - l * tx
                    y += ay - l * ty

            xy[j][0] = x / len(nbrs)
            xy[j][1] = y / len(nbrs)

        for (i, j) in ij_e:
            e = ij_e[(i, j)]

            if lengths[e] == 0.0:
                c = midpoint_point_point_xy(xy[i], xy[j])
                xy[i][:] = c[:][:2]
                xy[j][:] = c[:][:2]

        if callback:
            callback(k, xy, edges)
Example #3
0
def parallelise_edges(xy,
                      edges,
                      i_nbrs,
                      ij_e,
                      target_vectors,
                      target_lengths,
                      fixed=None,
                      line_constraints=None,
                      kmax=100,
                      callback=None):
    """Parallelise the edges of a mesh to given target vectors.

    Parameters
    ----------
    xy : list
        The XY coordinates of the vertices of the edges.
    edges : list
        The edges as pairs of indices in ``xy``.
    i_nbrs : dict
        A list of neighbours per vertex.
    ij_e : dict
        An edge index per vertex pair.
    target_vectors : list
        A list with an entry for each edge representing the target vector or ``None``.
    target_lengths : list
        A list with an entry for each edge representing the target length or ``None``.
    fixed : list, optional
        The fixed nodes of the mesh.
        Default is ``None``.
    line_constraints : list, optional
        Line constraints applied to the free nodes.
        Default is an ``None`` in which case no line constraints are considered.
    kmax : int, optional
        Maximum number of iterations.
        Default is ``100``.
    callback : callable, optional
        A user-defined callback function to be executed after every iteration.
        Default is ``None``.

    Returns
    -------
    None

    Notes
    -----
    This implementation is based on the function ``compas_tna.equilibrium.parallelisation.parallelise_edges``.

    Examples
    --------
    >>>
    """
    if callback:
        if not callable(callback):
            raise Exception('The provided callback is not callable.')

    n = len(xy)

    for k in range(kmax):
        xy0 = [[x, y] for x, y in xy]
        uv = [[xy[j][0] - xy[i][0], xy[j][1] - xy[i][1]] for i, j in edges]
        lengths = [(dx**2 + dy**2)**0.5 for dx, dy in uv]

        for j in range(n):
            if j in fixed:
                continue

            nbrs = i_nbrs[j]
            x, y = 0.0, 0.0

            len_nbrs = 0
            for i in nbrs:
                if (i, j) in ij_e:
                    e = ij_e[(i, j)]
                    u, v = i, j
                    signe = +1.0
                else:
                    e = ij_e[(j, i)]
                    u, v = j, i
                    signe = -1.0

                if target_lengths[
                        e] is not None:  # edges with constraint on length ...
                    lij = target_lengths[e]
                    if target_vectors[
                            e]:  # edges with constraint on length + orientation
                        tx, ty = target_vectors[e]
                    else:  # edges with constraint on length only
                        if lengths[e] == 0.0:
                            tx = ty = 0.0
                        else:
                            tx = (xy0[v][0] - xy0[u][0]) / lengths[e]
                            ty = (xy0[v][1] - xy0[u][1]) / lengths[
                                e]  # check if xy0 is indeed better than xy
                else:
                    if target_vectors[
                            e]:  # edges with constraint on orientation only
                        tx, ty = target_vectors[e]
                        lij = lengths[e]
                    else:
                        continue  # edges to discard

                ax, ay = xy0[i]
                x += ax + signe * lij * tx
                y += ay + signe * lij * ty
                len_nbrs += 1

            if len_nbrs > 0:
                xy[j][0] = x / len_nbrs
                xy[j][1] = y / len_nbrs

                # check if line constraints are applied and project result
                if line_constraints:
                    line = line_constraints[j]
                    if line:
                        pt_proj = project_point_line_xy(xy[j], line)
                        xy[j][0] = pt_proj[0]
                        xy[j][1] = pt_proj[1]

        for (i, j) in ij_e:
            e = ij_e[(i, j)]

            if lengths[e] == 0.0 or target_lengths[e] == 0.0:
                c = midpoint_point_point_xy(xy[i], xy[j])
                xy[i][:] = c[:][:2]
                xy[j][:] = c[:][:2]

        if callback:
            callback(k, xy, edges)