def transformed_stress_vector_fields(mesh, vector_fields, stress_type,
                                     ref_vector):
    """
    Rescales a vector field based on a plane stress transformation.
    """
    vf1, vf2 = vector_fields

    # TODO: mapping is not robust! depends on naming convention
    stress_components = {
        "bending": {
            "names": ["mx", "my", "mxy"],
            "ps": "m_1"
        },
        "axial": {
            "names": ["nx", "ny", "nxy"],
            "ps": "n_1"
        }
    }

    stress_names = stress_components[stress_type]["names"]
    vf_ps = mesh.vector_field(stress_components[stress_type]["ps"])

    vf1_transf = VectorField()
    vf2_transf = VectorField()

    for fkey in mesh.faces():
        # query stress components
        sx, sy, sxy = mesh.face_attributes(fkey, names=stress_names)

        # generate principal stresses and angles
        s1a, s1 = principal_stresses_and_angles(sx, sy, sxy)
        s1, angle1 = s1a

        vector_ps = vf_ps[fkey]
        vector1 = vf1[fkey]
        vector2 = vf2[fkey]

        # compute delta between reference vector and principal bending vector
        # TODO: will take m1 as reference. does this always hold?

        delta = angle1 - angle_vectors(vector_ps, ref_vector)
        # add delta to angles of the vector field to transform
        theta = delta + angle_vectors(vector1, ref_vector)

        # transform stresses - this becomes the scale of the vectors
        s1, s2, _ = transformed_stresses(sx, sy, sxy, theta)

        vf1_transf.add_vector(fkey, scale_vector(normalize_vector(vector1),
                                                 s1))
        vf2_transf.add_vector(fkey, scale_vector(normalize_vector(vector2),
                                                 s2))

    return vf1_transf, vf2_transf
示例#2
0
    def kinks(self, threshold=1e-3):
        """Return the XYZ coordinates of kinks, i.e. tangency discontinuities, along the surface's boundaries.

        Returns
        -------
        list
            The list of XYZ coordinates of surface boundary kinks.

        """
        kinks = []
        borders = self.borders(type=0)

        for border in borders:
            border = RhinoCurve(border)
            extremities = map(
                lambda x: rs.EvaluateCurve(border.guid,
                                           rs.CurveParameter(border.guid, x)),
                [0., 1.])

            if border.is_closed():
                start_tgt, end_tgt = border.tangents(extremities)
                if angle_vectors(start_tgt, end_tgt) > threshold:
                    kinks += extremities

            else:
                kinks += extremities

        return list(set(kinks))
示例#3
0
    def set_vertex_vectors_angles(self, name):
        for v in self.c_mesh.vertices():
            # 1. find keys of vertex' neighbouring faces
            face_idxs = self.c_mesh.vertex_faces(v, ordered=True)

            # 2. get attributes of the found faces and calculate weights
            vec_a = self.c_mesh.faces_attribute(name=str(name) + '_a', keys=face_idxs)
            vec_b = self.c_mesh.faces_attribute(name=str(name) + '_b', keys=face_idxs)

            # 3. get connected edges
            angles = []
            for face_idx in face_idxs:
                edges = []
                for edge in self.c_mesh.face_halfedges(face_idx):
                    if v in edge:
                        edges.append(edge)
                # if len(edges) > 1:
                e_1 = self.c_mesh.edge_vector(edges[0][0], edges[0][1])
                e_2 = self.c_mesh.edge_vector(edges[1][0], edges[1][1])
                angle = cg.angle_vectors(e_1, e_2, deg=True)
                angles.append(angle)

            mass_angle = reduce(lambda x, y: x+y, angles)
            weights = list(map(lambda x: x/mass_angle, angles))

            # 4. multiply vectors by weights
            nd_vec_a = ut.vectors_weight_reduce(vec_a, weights)
            nd_vec_b = ut.vectors_weight_reduce(vec_b, weights)

            # 6. assign vector attributes to vertices
            self.c_mesh.vertex_attribute(v, str(name) + '_a', nd_vec_a)
            self.c_mesh.vertex_attribute(v, str(name) + '_b', nd_vec_b)
示例#4
0
    def get_angle_weights(self, c_mesh, v_key, f_keys):
        angles = []
        weigths = []

        angles = []
        for f_key in f_keys:
            edges = []
            for edge in c_mesh.face_halfedges(f_key):
                if v_key in edge:
                    edges.append(edge)

            e_1 = c_mesh.edge_vector(edges[0][0], edges[0][1])
            e_2 = c_mesh.edge_vector(edges[1][0], edges[1][1])

            try:
                angle = cg.angle_vectors(e_1, e_2, deg=True)
            except Exception:
                angle = 1e-6
            angles.append(angle)

        if len(angles) > 1:
            mass_angle = reduce(lambda x, y: x + y, angles)
            if mass_angle > 0:
                return list(map(lambda x: x / mass_angle, angles))
        return [1.0]
示例#5
0
def find_points_extreme(pts_all, pts_init):
    """update a bar's axis end point based on all the contact projected points specified in `pts_all`

    Parameters
    ----------
    pts_all : list of points
        all the contact points projected on the axis (specified by pts_init)
    pts_init : list of two points
        the initial axis end points

    Returns
    -------
    [type]
        [description]
    """
    vec_init = normalize_vector(vector_from_points(*pts_init))
    # * find the pair of points with maximal distance
    sorted_pt_pairs = sorted(combinations(pts_all, 2), key=lambda pt_pair: distance_point_point(*pt_pair))
    pts_draw = sorted_pt_pairs[-1]

    vec_new = normalize_vector(vector_from_points(*pts_draw))
    if angle_vectors(vec_init, vec_new, deg=True) > 90:
        # angle can only be 0 or 180
        pts_draw = pts_draw[::-1]

    # ext_len = 30
    # pts_draw = (add_vectors(pts_draw[0], scale_vector(normalize_vector(vector_from_points(pts_draw[1], pts_draw[0])), ext_len)), add_vectors(pts_draw[1], scale_vector(normalize_vector(vector_from_points(pts_draw[0], pts_draw[1])), ext_len)))

    return pts_draw
示例#6
0
def orient_points(points, reference_plane, target_plane):
    """Orient points from one plane to another.

    Parameters
    ----------
    points : list of points
        XYZ coordinates of the points.
    reference_plane : plane
        Base point and normal defining a reference plane.
    target_plane : plane
        Base point and normal defining a target plane.

    Returns
    -------
    points : list of point
        XYZ coordinates of the oriented points.

    Notes
    -----
    This function is useful to orient a planar problem in the xy-plane to simplify
    the calculation (see example).

    Examples
    --------
    >>> from compas.geometry import orient_points
    >>> from compas.geometry import intersection_segment_segment_xy
    >>>
    >>> refplane = ([0.57735, 0.57735, 0.57735], [1.0, 1.0, 1.0])
    >>> tarplane = ([0.0, 0.0, 0.0], [0.0, 0.0, 1.0])
    >>>
    >>> points = [\
            [0.288675, 0.288675, 1.1547],\
            [0.866025, 0.866025, 0.0],\
            [1.077350, 0.077350, 0.57735],\
            [0.077350, 1.077350, 0.57735]\
        ]
    >>>
    >>> points = orient_points(points, refplane, tarplane)
    >>>
    >>> ab = points[0], points[1]
    >>> cd = points[2], points[3]
    >>>
    >>> point = intersection_segment_segment_xy(ab, cd)
    >>>
    >>> points = orient_points([point], tarplane, refplane)
    >>> Point(*points[0])
    Point(0.577, 0.577, 0.577)
    """
    axis = cross_vectors(reference_plane[1], target_plane[1])
    angle = angle_vectors(reference_plane[1], target_plane[1])
    origin = reference_plane[0]

    if angle:
        points = rotate_points(points, angle, axis, origin)

    vector = subtract_vectors(target_plane[0], reference_plane[0])
    points = translate_points(points, vector)

    return points
示例#7
0
def get_rebar_angles(x_dir, ori):
    angle = cg.angle_vectors(ori, x_dir, deg=True)
    angle_2 = angle + 90.0

    # if angle > 90.0:
    #     angle = angle-90
    #     angle_2 = angle - 90.0

    return angle, angle_2
示例#8
0
 def update_angle_deviations(self):
     """Compute the angle deviation with the corresponding halfface normal in the ForceVolMesh.
     """
     for edge in self.edges():
         halfface = self.dual_halfface(edge)
         normal = self.dual.halfface_normal(halfface)
         edge_vector = self.edge_vector(*edge)
         a = angle_vectors(edge_vector, normal, deg=True)
         self.edge_attribute(edge, '_a', a)
         self.dual.face_attribute(halfface, '_a', a)
示例#9
0
def _find_first_neighbour(key, network):
    angles = []
    nbrs = list(network.halfedge[key].keys())
    if len(nbrs) == 1:
        return nbrs[0]
    vu = [-1, -1, 0]
    for nbr in nbrs:
        w = [network.vertex[nbr][_] for _ in 'xyz']
        v = [network.vertex[key][_] for _ in 'xyz']
        vw = [w[0] - v[0], w[1] - v[1], 0]
        angles.append(angle_vectors(vu, vw))
    return nbrs[angles.index(min(angles))]
示例#10
0
def _check_deviation(volmesh, network):
    deviation = 0
    for u, v in network.edges():
        u_hf, v_hf = volmesh.cell_pair_halffaces(u, v)
        normal = volmesh.halfface_normal(u_hf)
        edge = network.edge_vector(u, v, unitized=True)
        perp_check = angle_vectors(normal, edge, deg=True)
        # dot = dot_vectors(normal, edge)
        # perp_check = 1 - abs(dot)
        if perp_check > deviation:
            deviation = perp_check
    return deviation
    def branches_splitting_boundary_kinks(self):
        """Add new branches to fix the problem of boundary kinks not marked by the skeleton
		Due to a low density that did not spot the change of curvature at the kink.
		Does not modify the singularites on the contrarty to increasing the density.

		Returns
		-------
		new_branches : list
			List of polylines as list of point XYZ-coordinates.

		"""

        new_branches = []

        compas_singular_faces = set(self.compas_singular_faces())
        for boundary in self.boundaries():
            angles = {(u, v, w): angle_vectors(
                subtract_vectors(self.vertex_coordinates(v),
                                 self.vertex_coordinates(u)),
                subtract_vectors(self.vertex_coordinates(w),
                                 self.vertex_coordinates(v)))
                      for u, v, w in window(boundary + boundary[:2], n=3)}
            for u, v, w, x, y in list(window(boundary + boundary[:4], n=5)):

                # check if not a corner
                if self.vertex_degree(w) == 2:
                    continue

                angle = angles[(v, w, x)]
                adjacent_angles = (angles[(u, v, w)] + angles[(w, x, y)]) / 2

                if angle - adjacent_angles > self.relative_kink_angle_limit:
                    # check if not already marked via an adjacent compas_singular face
                    if all([
                            fkey not in compas_singular_faces
                            for fkey in self.vertex_faces(w)
                    ]):
                        fkeys = list(self.vertex_faces(w, ordered=True))
                        fkey = fkeys[int(floor(len(fkeys) / 2))]
                        for edge in self.face_halfedges(fkey):
                            if w in edge and not self.is_edge_on_boundary(
                                    *edge):
                                new_branches += [[
                                    trimesh_face_circle(self, fkey)[0],
                                    self.vertex_coordinates(vkey)
                                ] for vkey in edge]
                                break

        return new_branches
示例#12
0
 def corner_vertices(self, tol=160):
     vkeys = []
     for key in self.vertices_on_boundary():
         if self.vertex_degree(key) == 2:
             vkeys.append(key)
         else:
             nbrs = []
             for nkey in self.vertex_neighbors(key):
                 if self.is_edge_on_boundary(key, nkey):
                     nbrs.append(nkey)
             u = (self.edge_vector(key, nbrs[0]))
             v = (self.edge_vector(key, nbrs[1]))
             if angle_vectors(u, v, deg=True) < tol:
                 vkeys.append(key)
     return vkeys
示例#13
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))]
示例#14
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))]
示例#15
0
    def blocks(self):
        """Compute the blocks.

        Returns
        -------
        list
            A list of blocks defined as simple meshes.

        Notes
        -----
        This method is used by the ``from_geometry`` constructor of the assembly data structure
        to create an assembly "from geometry".

        """
        if self.rise > self.span / 2:
            raise Exception("Not a semicircular arch.")

        radius = self.rise / 2 + self.span**2 / (8 * self.rise)
        # base = [0.0, 0.0, 0.0]
        top = [0.0, 0.0, self.rise]
        left = [-self.span / 2, 0.0, 0.0]
        center = [0.0, 0.0, self.rise - radius]
        vector = subtract_vectors(left, center)
        springing = angle_vectors(vector, [-1.0, 0.0, 0.0])
        sector = radians(180) - 2 * springing
        angle = sector / self.n

        a = top
        b = add_vectors(top, [0, self.depth, 0])
        c = add_vectors(top, [0, self.depth, self.thickness])
        d = add_vectors(top, [0, 0, self.thickness])

        R = Rotation.from_axis_and_angle([0, 1.0, 0], 0.5 * sector, center)
        bottom = transform_points([a, b, c, d], R)

        blocks = []
        for i in range(self.n):
            R = Rotation.from_axis_and_angle([0, 1.0, 0], -angle, center)
            top = transform_points(bottom, R)
            vertices = bottom + top
            faces = [[0, 1, 2, 3], [7, 6, 5, 4], [3, 7, 4, 0], [6, 2, 1, 5],
                     [7, 3, 2, 6], [5, 1, 0, 4]]
            mesh = Mesh.from_vertices_and_faces(vertices, faces)
            blocks.append(mesh)
            bottom = top

        return blocks
示例#16
0
文件: vector.py 项目: yishizu/compas
    def angle_vectors(left, right):
        """Compute the smallest angle between corresponding pairs of two lists of vectors.

        Parameters
        ----------
        left : list
            A list of vectors.
        right : list
            A list of vectors.

        Returns
        -------
        list
            A list of angles.

        Examples
        --------
        >>> Vector.angle_vectors([[1.0, 0.0, 0.0], [2.0, 0.0, 0.0]], [[0.0, 1.0, 0.0], [0.0, 0.0, 2.0]])
        [1.5707963267948966, 1.5707963267948966]
        """
        return [angle_vectors(u, v) for u, v in zip(left, right)]
示例#17
0
    def angle(self, other):
        """Compute the smallest angle between this vector and another vector.

        Parameters
        ----------
        other : :class:`compas.geometry.Vector` or list
            The other vector.

        Returns
        -------
        float
            The smallest angle between the two vectors.

        Examples
        --------
        >>> u = Vector(1.0, 0.0, 0.0)
        >>> v = Vector(0.0, 1.0, 0.0)
        >>> u.angle(v) == 0.5 * math.pi
        True
        """
        return angle_vectors(self, other)
示例#18
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))]
示例#19
0
def arch_from_rise_and_span(height, span, depth, thickness, n):
    """Create a semicircular arch from rise and span.

    Parameters
    ----------
    height : float
        ...
    span : float
        Dimension of the span in meter measured at the impost level (intrados-intrados).
    depth : float
        Depth in meter of the arch perpendicular to the front view plane.
    thickness : float
        Thickness in meter of the arch.
    n: int
        number of voussoirs.

    Returns
    -------
    Assembly
        Data structure of the semicircular arch.
    """
    assembly = Assembly()

    if height > span / 2:
        raise Exception("Not a semicircular arch.")

    radius = height / 2 + (span**2 / (8 * height))

    base = [0.0, 0.0, 0.0]
    top = [0.0, 0.0, height]
    left = [-span / 2, 0.0, 0.0]
    center = [0.0, 0.0, height - radius]

    vector = subtract_vectors(left, center)
    springing = angle_vectors(vector, [-1.0, 0.0, 0.0])
    sector = radians(180) - 2 * springing
    angle = sector / n

    a = top
    b = add_vectors(top, [0, depth, 0])
    c = add_vectors(top, [0, depth, thickness])
    d = add_vectors(top, [0, 0, thickness])

    R = Rotation.from_axis_and_angle([0, 1.0, 0], 0.5 * sector, center)
    bottom = transform_points([a, b, c, d], R)

    blocks = []
    for i in range(n):
        R = Rotation.from_axis_and_angle([0, 1.0, 0], -angle, center)
        top = transform_points(bottom, R)
        vertices = bottom + top
        faces = [[0, 1, 2, 3], [7, 6, 5, 4], [3, 7, 4, 0], [6, 2, 1, 5],
                 [7, 3, 2, 6], [5, 1, 0, 4]]
        block = Block.from_vertices_and_faces(vertices, faces)
        assembly.add_block(block)
        bottom = top

    assembly.node_attribute(0, 'is_support', True)
    assembly.node_attribute(n - 1, 'is_support', True)

    return assembly
    mesh.face_attribute(key=fkey, name=name_1, value=vec)

    vec_2 = cross_vectors(vec, [0.0, 0.0, 1.0])
    mesh.face_attribute(key=fkey, name=name_2, value=vec_2)
    recalibrated_perp[fkey, :] = vec_2

# =============================================================================
# Calculate resulting deviation
# =============================================================================

base = values
target = recalibrated_values

deviations = np.zeros(mesh.number_of_faces())
for fkey in mesh.faces():
    deviations[fkey] = angle_vectors(base[fkey], target[fkey], deg=True)

# =============================================================================
# Compute MSE Loss
# =============================================================================

losses = np.zeros(mesh.number_of_faces())
for fkey in mesh.faces():    
    losses[fkey] = length_vector_sqrd(subtract_vectors(base[fkey], target[fkey]))

print("MSE Loss: {}".format(np.mean(deviations)))

# =============================================================================
# Draw kmeans vectors
# =============================================================================
示例#21
0
def plot_2d(filename,
            plate_height,
            e_modulus,
            poisson=0,
            basis_direction="X",
            draw_boundary_edges=True,
            draw_faces=True,
            draw_faces_centroids=False,
            draw_colorbar=True,
            draw_edges=False,
            save_img=True,
            show_img=False):
    """
    Calculates the bending strain energy in a plate.

    Parameters
    ----------
    filename : `str`
        The name of the JSON file that stores the clustering resultes w.r.t certain
        \n mesh, attribute, alglrithm and number of clusters.
    """

    moment_names = ["mx", "my", "mxy"]
    basis_vectors = {"X": [1, 0, 0], "Y": [0, 1, 0]}
    basis_vector = basis_vectors[basis_direction]

    # ==========================================================================
    # Load Mesh
    # ==========================================================================

    # load a mesh from a JSON file
    name_in = filename + ".json"
    json_in = os.path.abspath(os.path.join(JSON, name_in))

    mesh = MeshPlus.from_json(json_in)

    # ==========================================================================
    # Select vector fields
    # ==========================================================================

    # select a vector field along which the strain energy will be calculated
    available_vf = mesh.vector_fields()
    print("Avaliable vector fields on the mesh are:\n", available_vf)

    while True:
        vf_name = input(
            "Select a vector field to calculate the metric along: ")
        if vf_name in available_vf:
            break
        print("This vector field is not available. Please try again.")

    vf = mesh.vector_field(vf_name)

    # select a vector field to take as the basis reference
    while True:
        msg = "Now choose a field as the PS directional basis. Often m_1: "
        vf_basis_name = input(msg)
        if vf_basis_name in available_vf:
            break
        print("This vector field is not available. Please try again.")

    # TODO: taking m_1 as reference. does it always hold?
    vf_ps = mesh.vector_field(vf_basis_name)

    # ==========================================================================
    # Choose structural metric to compute
    # ==========================================================================

    structural_metrics = {
        "energy": {
            "cbar_legend": "Strain Energy [kNm]"
        },
        "work": {
            "cbar_label": "Work [kNm]"
        },
        "volume": {
            "func": volume_reinforcement_bending,
            "cbar_label": "Volume [KNm]"
        },
        "volume1": {
            "func": volume_reinforcement_bending_dir,
            "cbar_label": "Volume 1 [KNm]"
        },
        "volume2": {
            "func": volume_reinforcement_bending_dir,
            "cbar_label": "Volume 2 [KNm]"
        }
    }

    energy_func = partial(strain_energy_bending,
                          height=plate_height,
                          e_modulus=e_modulus,
                          poisson=poisson)
    structural_metrics["energy"]["func"] = energy_func

    work_func = partial(virtual_work_bending,
                        height=plate_height,
                        e_modulus=e_modulus,
                        poisson=poisson)
    structural_metrics["work"]["func"] = work_func

    # Choose metric
    while True:
        msg = "What metric should I compute, energy, work, volume, volume1, volume2? "
        metric_name = input(msg)
        if metric_name in structural_metrics:
            break
        print("This metric is not available. Please try again.")

    structure_func = structural_metrics[metric_name]["func"]
    cbar_label = structural_metrics[metric_name]["cbar_label"]

    # ==========================================================================
    # Calculate bending strain energy
    # ==========================================================================

    # transform bending moments
    data = np.zeros(mesh.number_of_faces())
    sorted_fkeys = sorted(list(mesh.faces()))

    # compute strain energy per face in the mesh
    for fkey in sorted_fkeys:

        # get bending moments stored in the mesh
        mx, my, mxy = mesh.face_attributes(fkey, names=moment_names)

        # calculate the principal bending moments
        m1a, _ = principal_stresses_and_angles(mx, my, mxy)
        _, angle1 = m1a

        # compute delta between reference vector and principal bending vector
        # TODO: will take m1 as reference. does this always hold?
        # basis vector is often the global X vector, [1, 0, 0]
        vec_ps = vf_ps[fkey]
        delta = angle1 - angle_vectors(vec_ps, basis_vector)

        # add delta to target transformation vector field
        vec = vf[fkey]
        theta = delta + angle_vectors(vec, basis_vector)

        # transform bending moments with theta
        m1, m2, m12 = transformed_stresses(mx, my, mxy, theta)

        # calculate value of structural metric
        if metric_name == "volume1":
            value = structure_func(m1, m12)
        elif metric_name == "volume2":
            value = structure_func(m2, m12)
        else:
            value = structure_func(m1, m2, m12)

        # store the bending strain energy
        data[fkey] = value

    # ==========================================================================
    # Calculate total bending strain energy
    # ==========================================================================

    total_data = data.sum()
    print("Plate {0}: {1}".format(metric_name, round(total_data, 2)))

    # ==========================================================================
    # Plot Mesh
    # ==========================================================================

    # ClusterPlotter is a custom wrapper around a COMPAS MeshPlotter
    plotter = MeshPlusPlotter(mesh, figsize=(16, 9), dpi=300)
    if draw_boundary_edges:
        plotter.draw_edges(keys=list(mesh.edges_on_boundary()))

    # draw mesh edges
    if draw_edges:
        plotter.draw_edges()

    # color up the faces of the mesh according to their cluster
    if draw_faces or draw_faces_centroids:

        if draw_faces:

            collection = plotter.draw_faces(keys=sorted_fkeys)

        elif draw_faces_centroids:

            points = []
            for fkey in sorted_fkeys:
                point = {}
                point["pos"] = mesh.face_centroid(fkey)
                point["radius"] = 0.03
                point["edgewidth"] = 0.10
                points.append(point)

            collection = plotter.draw_points(points)

        collection.set(array=data,
                       cmap="YlGnBu")  # Spectral, BrBG, viridis, PiYG
        collection.set_linewidth(lw=0.0)

        if draw_colorbar:
            # create label for color map
            ticks = np.linspace(data.min(), data.max(), 7)
            ticks_labels = [np.round(x, 2) for x in ticks]
            extend = "both"

            colorbar = plt.colorbar(collection,
                                    shrink=0.9,
                                    pad=0.01,
                                    extend=extend,
                                    extendfrac=0.05,
                                    ax=plotter.axes,
                                    aspect=30,
                                    orientation="vertical")

            colorbar.set_ticks(ticks)
            colorbar.ax.set_yticklabels(ticks_labels)
            colorbar.set_label(cbar_label, fontsize="large")

    # save image
    if save_img:
        dt = datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
        img_name = filename.split(
            "/")[-1] + metric_name + "_" + vf_name + "_" + dt + ".png"
        img_path = os.path.abspath(os.path.join(DATA, "images", img_name))
        plt.tight_layout()
        plotter.save(img_path, bbox_inches='tight', pad_inches=0.0)
        print("Saved image to : {}".format(img_path))

    # show to screen
    if show_img:
        plotter.show()
示例#22
0
"""Assignment:

1a Given two vectors, use the cross product to create a set of three orthonormal vectors.
1b Use the cross product to compute the area of a convex, 2D polygon.
1c Define a function for computing the cross products of two same-length arrays of vectors by
    a. Prototype in pure Python (loop over the arrays).
    b. Make Numpy equivalent without loops.
"""

# 1a. Given two vectors, use the cross product to create a set of three orthonormal vectors.

from compas.geometry import cross_vectors
from compas.geometry import angle_vectors
import math as m

v1 = [1,2,3]
v2 = [4,5,6]

# replace #... and fill in there
x1 = #...
x2 = #...
x3 = #...

print(x1)
print(x2)
print(x3)

print(m.degrees(angle_vectors(x1, x2)))
print(m.degrees(angle_vectors(x1, x3)))
print(m.degrees(angle_vectors(x2, x3)))     
mesh = Mesh()
mesh.load(HERE)
mesh_unify_cycles(mesh)

# ==========================================================================
# Create PS vector lines
# ==========================================================================

vector_tag = 'ps_1_top'  # ps_1_top

angles = {}
centroids = {}
for fkey, attr in mesh.faces(data=True):
    vector = attr.get(vector_tag)
    angle = angle_vectors([1.0, 0.0, 0.0], vector, deg=True)
    angles[fkey] = angle
    centroids[fkey] = np.array(mesh.face_centroid(fkey))

print('max angle', min(angles.values()))
print('min angle', max(angles.values()))

for idx, angle in angles.items():
    if angle <= 90.0:
        continue
    angles[idx] = 180.0 - angle

print('max angle', min(angles.values()))
print('min angle', max(angles.values()))

anglemax = max(angles.values())
示例#24
0
 def set_angle(self, vector):
     angle = cg.angle_vectors([1.0, 0.0, 0.0], vector, deg=True)
     if angle > 90.0:
         angle = 180.0 - angle
     self.angle = angle
示例#25
0
descdent_tree = copy.deepcopy(convex_hull_mesh.halfedge)

for u, v in convex_hull_mesh.edges():
    descdent_tree[u][v] = {'jp': None, 'lp': None}
    descdent_tree[v][u] = {'jp': None, 'lp': None}

current_key = convex_hull_mesh.number_of_vertices()

for fkey in convex_hull_mesh.faces():
    f_centroid = convex_hull_mesh.face_centroid(fkey)
    vec = Vector.from_start_end(pt_center, f_centroid)

    # if the branches has a 'convex' corner,
    # flip the vec to the corresponding face.
    f_normal = convex_hull_mesh.face_normal(fkey)
    angle = angle_vectors(f_normal, vec, False)
    if angle > math.pi * 0.5:
        # vec.scale(-1)
        pln = Plane(pt_center, f_normal)
        pt_mirror = mirror_point_plane(f_centroid, pln)
        vec = Vector.from_start_end(pt_center, pt_mirror)

        # angle = math.pi - angle

    vec.unitize()
    # dist = joint_width / math.cos(angle)
    # vec.scale(dist)
    vec.scale(joint_width)

    pt = add_vectors(pt_center, vec)
示例#26
0
def test_angle_vectors(u, v, angle):
    assert angle_vectors(u, v) == pytest.approx(angle)
示例#27
0
from compas.geometry import cross_vectors
from compas.geometry import angle_vectors

u = [1.0, 0.0, 0.0]
v = [0.0, 1.0, 0.0]

print(angle_vectors(u, v))
print(angle_vectors(v, u))
示例#28
0
def test_angle_vectors_fails_when_input_is_zero(u, v):
    with pytest.raises(ZeroDivisionError):
        angle_vectors(u, v)
示例#29
0
def test_angle_vectors(u, v, angle):
    assert close(angle_vectors(u, v), angle)
示例#30
0
>>>>>>> 584331387c8b670cd9258e4c252df49c39192943
        # ----------------------------------------------------------------------
        #   4. update force diagram
        # ----------------------------------------------------------------------

        if weight != 1:
            volmesh_planarise(volmesh,
                              kmax=1,
                              target_normals=target_normals)

        # boundary perpness
        for fkey in boundary_fkeys:
            f_normal = volmesh.halfface_normal(fkey)
            target_normal = target_normals[fkey]
            b_perpness = angle_vectors(f_normal, target_normal, deg=True)
            # 1 - abs(dot_vectors(f_normal, target_normal))

            if b_perpness > deviation_boundary_perp:
                deviation_boundary_perp = b_perpness

        # ----------------------------------------------------------------------
        #   5. check convergence
        # ----------------------------------------------------------------------
        perpness = _check_deviation(volmesh, formdiagram)

        if perpness < tolerance and deviation_boundary_perp < tolerance_boundary:

            if print_result_info:
                print_result('Reciprocation', k, perpness)