Beispiel #1
0
def line_sdl(start, direction, length, both_sides=True):
    """
    Creates a line from a start point with a given direction and length. It will also extend the line in the oposite direction unless both_sides is set to `False`.

    Parameters
    ----------
    start : `list` of `float`, shape(n,), n<=3
        A point defined by XYZ coordinates.
        If Z coordinate is not given, then the results are in 2D.
        If Y and Z coordinates are not given, then the results are in 1D.
    direction : `list` of `float`
        XYZ components of the vector to create a line.
    length : `float`
        The length of the line.
    both_sides : `bool`, optional
        Flag to produce a line in one or both directions.
        Deafault is set to `True`.

    Returns
    -------
    a, b : `tuple`
        Returns the start and end points of the line.
    """
    direction = normalize_vector(direction[:])
    a = start
    b = add_vectors(start, scale_vector(direction, +length))
    if both_sides:
        a = add_vectors(start, scale_vector(direction, -length))
    return a, b
def framelines(origin, xaxis, yaxis, zaxis, name):
    lines = []

    lines.append({
        'start': origin,
        'end': add_vectors(origin, scale_vector(xaxis, 0.1)),
        'color': (255, 0, 0),
        'name': "{}.X".format(name)
    })

    lines.append({
        'start': origin,
        'end': add_vectors(origin, scale_vector(yaxis, 0.1)),
        'color': (0, 255, 0),
        'name': "{}.Y".format(name)
    })

    lines.append({
        'start': origin,
        'end': add_vectors(origin, scale_vector(zaxis, 0.1)),
        'color': (0, 0, 255),
        'name': "{}.Z".format(name)
    })

    return lines
Beispiel #3
0
def plot_axes(xyz, e11, e22, e33, layer, sc=1):
    """ Plots a set of axes.

    Parameters
    ----------
    xyz : list
        Origin of the axes.
    e11 : list
        Normalised first axis component [x1, y1, z1].
    e22 : list
        Normalised second axis component [x2, y2, z2].
    e33 : list
        Normalised third axis component [x3, y3, z3].
    layer : str
        Layer to plot on.
    sc : float
         Size of the axis lines.

    Returns
    -------
    None

    """

    ex = rs.AddLine(xyz, add_vectors(xyz, scale_vector(e11, sc)))
    ey = rs.AddLine(xyz, add_vectors(xyz, scale_vector(e22, sc)))
    ez = rs.AddLine(xyz, add_vectors(xyz, scale_vector(e33, sc)))

    rs.ObjectColor(ex, [255, 0, 0])
    rs.ObjectColor(ey, [0, 255, 0])
    rs.ObjectColor(ez, [0, 0, 255])
    rs.ObjectLayer(ex, layer)
    rs.ObjectLayer(ey, layer)
    rs.ObjectLayer(ez, layer)
Beispiel #4
0
def intersection_plane_plane(plane1, plane2, tol=1e-6):
    """Computes the intersection of two planes

    Parameters
    ----------
    plane1 : tuple
        The base point and normal (normalized) defining the 1st plane.
    plane2 : tuple
        The base point and normal (normalized) defining the 2nd plane.
    tol : float, optional
        A tolerance for membership verification.
        Default is ``1e-6``.

    Returns
    -------
    line : tuple
        Two points defining the intersection line. None if planes are parallel.

    """
    o1, n1 = plane1
    o2, n2 = plane2

    if fabs(dot_vectors(n1, n2)) >= 1 - tol:
        return None

    # direction of intersection line
    d = cross_vectors(n1, n2)
    # vector in plane 1 perpendicular to the direction of the intersection line
    v1 = cross_vectors(d, n1)
    # point on plane 1
    p1 = add_vectors(o1, v1)

    x1 = intersection_line_plane((o1, p1), plane2, tol=tol)
    x2 = add_vectors(x1, d)
    return x1, x2
Beispiel #5
0
 def draw_interface_frames(self):
     """Draw the frames of the interfaces.
     """
     layer = "{}::Interfaces::Frames".format(self.layer) if self.layer else None
     lines = []
     for (a, b), attr in self.assembly.edges(True):
         o = attr['interface_origin']
         u, v, w = attr['interface_uvw']
         lines.append({
             'start' : o,
             'end'   : add_vectors(o, u),
             'name'  : "{}.iframe.{}-{}.u".format(self.assembly.name, a, b),
             'color' : (255, 0, 0),
             'arrow' : 'end'
         })
         lines.append({
             'start' : o,
             'end'   : add_vectors(o, v),
             'name'  : "{}.iframe.{}-{}.v".format(self.assembly.name, a, b),
             'color' : (0, 255, 0),
             'arrow' : 'end'
         })
         lines.append({
             'start' : o,
             'end'   : add_vectors(o, w),
             'name'  : "{}.iframe.{}-{}.w".format(self.assembly.name, a, b),
             'color' : (0, 0, 255),
             'arrow' : 'end'
         })
     self.draw_lines(lines, layer=layer, clear=True, redraw=True)
Beispiel #6
0
def plot_structure(structure):
    eks = []
    for ep in structure.element_properties:
        elements = structure.element_properties[ep].elements
        elset = structure.element_properties[ep].elset
        if elements:
            eks = elements
        elif elset:
            eks = structure.sets[elset].selection
        sec = structure.element_properties[ep].section
        t = structure.sections[sec].geometry['t']
        for ek in eks:
            nodes = structure.elements[ek].nodes
            vert = [structure.nodes[nk].xyz() for nk in nodes]
            n = scale_vector(normalize_vector(normal_polygon(vert)), t / 2.)
            n_ = scale_vector(n, -1)
            v_out = [add_vectors(v, n) for v in vert]
            v_in = [add_vectors(v, n_) for v in vert]
            s1 = rs.AddSrfPt(v_out)
            s2 = rs.AddSrfPt(v_in)
            srfs = [s1, s2]
            for i in range(len(v_in)):
                srf = rs.AddSrfPt(
                    [v_in[-i], v_in[-i - 1], v_out[-i - 1], v_out[-i]])
                if srf:
                    srfs.append(srf)
            rs.JoinSurfaces(srfs, delete_input=True)
def line_sdl(start, direction, length, both_sides=True):

    direction = normalize_vector(direction[:])
    a = start
    b = add_vectors(start, scale_vector(direction, +length))
    if both_sides:
        a = add_vectors(start, scale_vector(direction, -length))
    return a, b
Beispiel #8
0
def offset_line(line, distance, normal=[0.0, 0.0, 1.0]):
    """Offset a line by a distance.

    Parameters
    ----------
    line : tuple
        Two points defining the line.
    distances : float or list of floats
        The offset distance as float.
        A single value determines a constant offset. Alternatively, two
        offset values for the start and end point of the line can be used to
        a create variable offset.
    normal : vector
        The normal of the offset plane.

    Returns
    -------
    offset line : tuple
        Two points defining the offset line.

    Notes
    -----
    The offset direction is chosen such that if the line were along the positve
    X axis and the normal of the offset plane is along the positive Z axis, the
    offset line is in the direction of the postive Y axis.

    Examples
    --------
    .. code-block:: python

        line = [(0.0, 0.0, 0.0), (3.0, 3.0, 0.0)]

        distance = 0.2 # constant offset
        line_offset = offset_line(line, distance)
        print(line_offset)

        distance = [0.2, 0.1] # variable offset
        line_offset = offset_line(line, distance)
        print(line_offset)

    """

    a, b = line
    ab = subtract_vectors(b, a)
    direction = normalize_vector(cross_vectors(normal, ab))

    if not is_item_iterable(distance):
        distance = [distance]
    distances = list(iterable_like(line, distance, distance[-1]))

    u = scale_vector(direction, distances[0])
    v = scale_vector(direction, distances[1])
    c = add_vectors(a, u)
    d = add_vectors(b, v)
    return c, d
Beispiel #9
0
 def super_triangle(coords):
     centpt = centroid_points(coords)
     bbpts = bounding_box(coords)
     dis = distance_point_point(bbpts[0], bbpts[2])
     dis = dis * 300
     v1 = (0 * dis, 2 * dis, 0)
     v2 = (1.73205 * dis, -1.0000000000001 * dis, 0)  # due to numerical issues
     v3 = (-1.73205 * dis, -1 * dis, 0)
     pt1 = add_vectors(centpt, v1)
     pt2 = add_vectors(centpt, v2)
     pt3 = add_vectors(centpt, v3)
     return pt1, pt2, pt3
Beispiel #10
0
    def draw_block_frame(self, key, fkey):
        """Draw the frame of a specific face of a specific block of the assembly.

        Parameters
        ----------
        key : int
            Identifier of the block.
        fkey : int
            The identifier of the face.

        """
        block = self.assembly.blocks[key]
        o, uvw = block.frame(fkey)
        o = block.face_center(fkey)
        lines = []
        lines.append({
            'start':
            o,
            'end':
            add_vectors(o, uvw[0]),
            'color': (255, 0, 0),
            'arrow':
            'end',
            'name':
            '{}.block.{}.face.{}.frame.u'.format(self.assembly.name, key, fkey)
        })
        lines.append({
            'start':
            o,
            'end':
            add_vectors(o, uvw[1]),
            'color': (0, 255, 0),
            'arrow':
            'end',
            'name':
            '{}.block.{}.face.{}.frame.v'.format(self.assembly.name, key, fkey)
        })
        lines.append({
            'start':
            o,
            'end':
            add_vectors(o, uvw[2]),
            'color': (0, 0, 255),
            'arrow':
            'end',
            'name':
            '{}.block.{}.face.{}.frame.w'.format(self.assembly.name, key, fkey)
        })
        self.draw_lines(lines,
                        layer=self.layer,
                        clear_layer=False,
                        redraw=True)
Beispiel #11
0
def offset_line(line, distance, normal=[0., 0., 1.]):
    """Offset a line by a distance.

    Parameters
    ----------
    line : tuple
        Two points defining the line.
    distances : float or tuples of floats
        The offset distance as float.
        A single value determines a constant offset. Alternatively, two
        offset values for the start and end point of the line can be used to
        a create variable offset.
    normal : tuple
        The normal of the offset plane.

    Returns
    -------
    offset line (tuple)
        Two points defining the offset line.

    Examples
    --------
    .. code-block:: python

        line = [(0.0, 0.0, 0.0), (3.0, 3.0, 0.0)]

        distance = 0.2 # constant offset
        line_offset = offset_line(line, distance)
        print(line_offset)

        distance = [0.2, 0.1] # variable offset
        line_offset = offset_line(line, distance)
        print(line_offset)

    """
    pt1, pt2 = line[0], line[1]
    vec = subtract_vectors(pt1, pt2)
    dir_vec = normalize_vector(cross_vectors(vec, normal))

    if isinstance(distance, list) or isinstance(distance, tuple):
        distances = distance
    else:
        distances = [distance, distance]

    vec_pt1 = scale_vector(dir_vec, distances[0])
    vec_pt2 = scale_vector(dir_vec, distances[1])
    pt1_new = add_vectors(pt1, vec_pt1)
    pt2_new = add_vectors(pt2, vec_pt2)
    return pt1_new, pt2_new
Beispiel #12
0
def tween_points(points1, points2, num):
    """Compute the interpolated points between two sets of points.

    Parameters
    ----------
    points1 : list
        The first set of points
    points2 : list
        The second set of points
    num : int
        The number of interpolated sets to return

    Returns
    -------
    list
        Nested list of points.

    Raises
    ------
    AssertionError
        When the two point sets do not have the same length.

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

        from compas.geometry import tween_points
        from compas_plotters import Plotter

        points1 = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [2.0, 0.0, 0.0], [3.0, 0.0, 0.0]]
        points2 = [[0.0, 0.0, 0.0], [1.0, 3.0, 0.0], [2.0, 1.0, 0.0], [3.0, 0.0, 0.0]]

        tweens = tween_points(points1, points2, 5)

        polylines = [{'points': points1, 'width': 1.0}]

        for points in tweens:
            polylines.append({'points': points, 'width': 0.5})

        polylines.append({'points': points2, 'width': 1.0})

        plotter = Plotter()
        plotter.draw_polylines(polylines)
        plotter.show()

    Notes
    -----
    The two point sets should have the same length.

    """
    vectors = [vector_from_points(p1, p2) for p1, p2 in zip(points1, points2)]
    tweens = []
    for j in range(num):
        tween = []
        for point, vector in zip(points1, vectors):
            scale = (j + 1.0) / (num + 1.0)
            tween.append(add_vectors(point, scale_vector(vector, scale)))
        tweens.append(tween)
    return tweens
Beispiel #13
0
def tween_points_distance(points1, points2, dist, index=None):
    """Compute an interpolated set of points between two sets of points, at
    a given distance.

    Parameters
    ----------
    points1 : list
        The first set of points
    points2 : list
        The second set of points
    dist : float
        The distance from the first set to the second at which to compute the
        interpolated set.
    index: int
        The index of the point in the first set from which to calculate the
        distance to the second set. If no value is given, the first point will be used.

    Returns
    -------
    list
        List of points

    """
    if not index:
        index = 0
    d = distance_point_point(points1[index], points2[index])
    scale = float(dist) / d
    tweens = []
    for i in range(len(points1)):
        tweens.append(
            add_vectors(
                points1[i],
                scale_vector(vector_from_points(points1[i], points2[i]),
                             scale)))
    return tweens
Beispiel #14
0
def line_point(line, t=.5):
    """Point on a lyline at a normalised parameter.

	Parameters
	----------
	polyline: list
	    The XYZ coordinates of the extremities of the line.
	t: float 
	    The normalised parameter of the point on the polyline between 0 and 1.

	Returns
	-------
	xyz: list, None
		The point coordinates.
		None if the parameter is not in [0,1]

	Raises
	------
	-

	"""

    u, v = line
    uv = subtract_vectors(v, u)
    return add_vectors(u, scale_vector(uv, t))
Beispiel #15
0
    def draw(self, show_point=False, show_normal=False):
        """Draw the circle.

        Parameters
        ----------
        show_point : bool, optional
            Default is ``False``.
        show_normal : bool, optional
            Default is ``False``.

        Returns
        -------
        list
            The GUIDs of the created Rhino objects.
        """
        point = list(self.primitive.plane.point)
        normal = list(self.primitive.plane.normal)
        plane = point, normal
        radius = self.primitive.radius
        guids = []
        if show_point:
            points = [{'pos': point, 'color': self.color, 'name': self.primitive.name}]
            guids += compas_rhino.draw_points(points, layer=self.layer, clear=False, redraw=False)
        if show_normal:
            lines = [{'start': point, 'end': add_vectors(point, normal), 'arrow': 'end', 'color': self.color, 'name': self.primitive.name}]
            guids += compas_rhino.draw_lines(lines, layer=self.layer, clear=False, redraw=False)
        circles = [{'plane': plane, 'radius': radius, 'color': self.color, 'name': self.primitive.name}]
        guids += compas_rhino.draw_circles(circles, layer=self.layer, clear=False, redraw=False)
        return guids
Beispiel #16
0
def tween_points_distance(points1, points2, dist, index=None):
    """Compute an interpolated set of points between two sets of points, at
    a given distance.

    Parameters
    ----------
    points1 : list[[float, float, float] | :class:`compas.geometry.Point`]
        The first set of points.
    points2 : list[[float, float, float] | :class:`compas.geometry.Point`]
        The second set of points.
    dist : float
        The distance from the first set to the second at which to compute the interpolated set.
    index: int, optional
        The index of the point in the first set from which to calculate the distance to the second set.
        If no value is given, the first point will be used.

    Returns
    -------
    list[list[[float, float, float]]]
        List of points.

    """
    if not index:
        index = 0
    d = distance_point_point(points1[index], points2[index])
    scale = float(dist) / d
    tweens = []
    for i in range(len(points1)):
        tweens.append(
            add_vectors(
                points1[i],
                scale_vector(subtract_vectors(points2[i], points1[i]), scale)))
    return tweens
Beispiel #17
0
def project_point_line(point, line):
    """Project a point onto a line.

    Parameters
    ----------
    point : [float, float, float] | :class:`compas.geometry.Point`
        XYZ coordinates of the point.
    line : [point, point] | :class:`compas.geometry.Line`
        Two points defining the projection line.

    Returns
    -------
    [float, float, float]
        XYZ coordinates of the projected point.

    Notes
    -----
    For more info, see [1]_.

    References
    ----------
    .. [1] Wiki Books. *Linear Algebra/Orthogonal Projection Onto a Line*.
           Available at: https://en.wikibooks.org/wiki/Linear_Algebra/Orthogonal_Projection_Onto_a_Line.

    """
    a, b = line
    ab = subtract_vectors(b, a)
    ap = subtract_vectors(point, a)
    c = vector_component(ap, ab)

    return add_vectors(a, c)
Beispiel #18
0
    def draw(self,  color: Optional[RGBColor] = None, show_point=False, show_normal=False) -> List[bpy.types.Object]:
        """Draw the circle.

        Parameters
        ----------
        color : tuple of float or tuple of int, optional
            The RGB color of the capsule.
        show_point : bool, optional
            Default is ``False``.
        show_normal : bool, optional
            Default is ``False``.

        Returns
        -------
        list
            The objects created in Blender.
        """
        color = color or self.color
        point = self.primitive.plane.point
        normal = self.primitive.plane.normal
        plane = point, normal
        radius = self.primitive.radius
        objects = []
        if show_point:
            points = [{'pos': point, 'color': color, 'name': self.primitive.name, 'radius': 0.01}]
            objects += compas_blender.draw_points(points, collection=self.collection)
        if show_normal:
            end = add_vectors(point, normal)
            lines = [{'start': point, 'end': end, 'color': color, 'name': self.primitive.name}]
            objects += compas_blender.draw_lines(lines, collection=self.collection)
        circles = [{'plane': plane, 'radius': radius, 'color': color, 'name': self.primitive.name}]
        objects += compas_blender.draw_circles(circles, collection=self.collection)
        return objects
Beispiel #19
0
def polygon_normal_oriented(polygon, unitized=True):
    """Compute the oriented normal of any closed polygon (can be convex, concave or complex).

    Parameters
    ----------
    polygon : sequence
        The XYZ coordinates of the vertices/corners of the polygon.
        The vertices are assumed to be in order.
        The polygon is assumed to be closed:
        the first and last vertex in the sequence should not be the same.

    Returns
    -------
    list
        The weighted or unitized normal vector of the polygon.

    """
    p = len(polygon)
    assert p > 2, "At least three points required"
    w          = centroid_points(polygon)
    normal_sum = (0, 0, 0)

    for i in range(-1, len(polygon) - 1):
        u          = polygon[i]
        v          = polygon[i + 1]
        uv         = subtract_vectors(v, u)
        vw         = subtract_vectors(w, v)
        normal     = scale_vector(cross_vectors(uv, vw), 0.5)
        normal_sum = add_vectors(normal_sum, normal)

    if not unitized:
        return normal_sum

    return normalize_vector(normal_sum)
Beispiel #20
0
    def draw_vertexnormals(self, vertices=None, color=(0, 255, 0), scale=1.0):
        """Draw the normals at the vertices of the mesh.

        Parameters
        ----------
        vertices : list, optional
            A selection of vertex normals to draw.
            Default is to draw all vertex normals.
        color : tuple, optional
            The color specification of the normal vectors.
            The default color is green, ``(0, 255, 0)``.
        scale : float, optional
            Scale factor for the vertex normals.
            Default is ``1.0``.

        Returns
        -------
        list
            The GUIDs of the created Rhino objects.

        """
        vertex_xyz = self.vertex_xyz
        vertices = vertices or list(self.mesh.vertices())
        lines = []
        for vertex in vertices:
            a = vertex_xyz[vertex]
            n = self.mesh.vertex_normal(vertex)
            b = add_vectors(a, scale_vector(n, scale))
            lines.append({
                'start': a,
                'end': b,
                'color': color,
                'name': "{}.vertexnormal.{}".format(self.mesh.name, vertex),
                'arrow': 'end'})
        return compas_rhino.draw_lines(lines, layer=self.layer, clear=False, redraw=False)
Beispiel #21
0
    def draw_facenormals(self, faces=None, color=(0, 255, 255), scale=1.0):
        """Draw the normals of the faces.

        Parameters
        ----------
        faces : list, optional
            A selection of face normals to draw.
            Default is to draw all face normals.
        color : tuple, optional
            The color specification of the normal vectors.
            The default color is cyan, ``(0, 255, 255)``.
        scale : float, optional
            Scale factor for the face normals.
            Default is ``1.0``.

        Returns
        -------
        list
            The GUIDs of the created Rhino objects.

        """
        vertex_xyz = self.vertex_xyz
        faces = faces or list(self.mesh.faces())
        lines = []
        for face in faces:
            a = centroid_points([vertex_xyz[vertex] for vertex in self.mesh.face_vertices(face)])
            n = self.mesh.face_normal(face)
            b = add_vectors(a, scale_vector(n, scale))
            lines.append({
                'start': a,
                'end': b,
                'name': "{}.facenormal.{}".format(self.mesh.name, face),
                'color': color,
                'arrow': 'end'})
        return compas_rhino.draw_lines(lines, layer=self.layer, clear=False, redraw=False)
def closest_point_on_line(a, b, c):
    """Closest point on line.
    Same as projection.

    Parameters
    ----------
    a: list
        First line point coordinates.
    b: list
        Second line point coordinates.
    c: list
        Point coordinates.

    Returns
    -------
    tuple
        The projected point coordinates and the distance from the input point.
    """

    ab = subtract_vectors(b, a)
    ac = subtract_vectors(c, a)

    if length_vector(ab) == 0:
        return a, distance_point_point(c, a)

    p = add_vectors(
        a, scale_vector(ab,
                        dot_vectors(ab, ac) / length_vector(ab)**2))
    distance = distance_point_point(c, p)
    return p, distance
Beispiel #23
0
def spiral_array(n, d, anchor=[0.0, 0.0, 0.0]):
	# spiral parameters set to respect d spacing between consecutive points and consecutive spiral elements
	a, b = 0, d / (2 * pi)
	ts = [pi * b]
	for i in range(n):
		ts.append((2 * d / b + ts[-1] ** 2) ** .5)
	return [add_vectors(anchor, archimedean_spiral_evaluate(t, a, b, 0)) for t in ts]
Beispiel #24
0
 def divide(self, number_of_segments):
     m, l, r = self.control_point_coordinates()
     points = [
         list(i) for i in interpolate_bezier(m[0], r[0], l[1], m[1],
                                             number_of_segments + 1)
     ]
     return [add_vectors(self.location, point) for point in points]
Beispiel #25
0
def mesh_offset(mesh, offset=1.0, cls=None):
    """Offset a mesh.

    Parameters
    ----------
    mesh : Mesh
        A Mesh to offset.
    offset : real
        The offset distance.

    Returns
    -------
    Mesh
        The offset mesh.

    """
    if cls is None:
        cls = type(mesh)

    # new coordinates of vertex keys
    vertex_map = {}
    for i, vkey in enumerate(mesh.vertices()):
        if len(mesh.vertex_neighbors(vkey)) == 0:
            vertex_map[vkey] = i, [0, 0, 0]
        else:
            vertex_map[vkey] = i, add_vectors(
                mesh.vertex_coordinates(vkey),
                scale_vector(mesh.vertex_normal(vkey), offset))

    vertices = [xyz for i, xyz in vertex_map.values()]
    faces = [[vertex_map[vkey][0] for vkey in mesh.face_vertices(fkey)]
             for fkey in mesh.faces()]

    return cls.from_vertices_and_faces(vertices, faces)
Beispiel #26
0
def _draw_arc(normal_1, normal_2, origin):
    mid_pt = normalize_vector(add_vectors(normal_1, normal_2))
    arc    = Arc(Point3d(*[sum(axis) for axis in zip(normal_1, origin)]),
                 Point3d(*[sum(axis) for axis in zip(mid_pt, origin)]),
                 Point3d(*[sum(axis) for axis in zip(normal_2, origin)]))
    arc_as_curve = ArcCurve(arc)
    return arc_as_curve
Beispiel #27
0
    def get_vector_on_face_ext(self, point, f_key, name, vec=[0, 0, 0]):
        f_keys = [f_key]
        f_keys.extend(self.c_mesh.face_neighbours(f_key))
        v_keys = []
        pt_cloud = []

        for f_key in f_keys:
            v_keys.extend(self.c_mesh.face_vertices(f_key))

        v_keys = list(set(v_keys))
        v_vectors_a = self.c_mesh.vertices_attribute(name=str(name) + '_a',
                                                        keys=v_keys
                                                        )
        v_vectors_b = self.c_mesh.vertices_attribute(name=str(name) + '_b',
                                                        keys=v_keys
                                                        )

        v_vectors = ut.filter_aligned_vectors(vec, v_vectors_a, v_vectors_b)

        for v_key in v_keys:
            pt_cloud.append(self.c_mesh.vertex_coordinates(v_key))

        weights = ut.get_dist_weights(point, pt_cloud)
        new_vectors = []
        for idx, vec in enumerate(v_vectors):
            new_vector = cg.scale_vector(vec, weights[idx])
            new_vectors.append(new_vector)

        return reduce(lambda x, y: cg.add_vectors(x, y), new_vectors)
Beispiel #28
0
 def draw_vertexnormals(self, keys=None, color=None, scale=None):
     keys = keys or list(self.mesh.vertices())
     scale = scale or self.settings.get('scale.normal:vertex')
     color = color or self.settings.get('color.normal:vertex')
     lines = []
     for key in keys:
         a = self.mesh.vertex_coordinates(key)
         n = self.mesh.vertex_normal(key)
         b = add_vectors(a, scale_vector(n, scale))
         lines.append({
             'start':
             a,
             'end':
             b,
             'color':
             color,
             'name':
             "{}.vertex.normal.{}".format(self.mesh.name, key),
             'arrow':
             'end'
         })
     return compas_rhino.draw_lines(lines,
                                    layer=self.layer,
                                    clear=False,
                                    redraw=False)
Beispiel #29
0
    def draw_facenormals(self, color=None, scale=1.0):
        """Draw the normals of the faces.

        Parameters
        ----------
        color : str (HEX) or tuple (RGB), optional
            The color specification of the normal vectors.
            String values are interpreted as hex colors (e.g. ``'#ff0000'`` for red).
            Tuples are interpreted as RGB component specifications (e.g. ``(255, 0, 0) for red``.
            The default value is ``None``, in which case the labels are assigned
            the default normal vector color (``self.defaults['color.normal']``).

        Notes
        -----
        The face normals are named using the following template:
        ``"{}.face.normal.{}".format(self.datastructure.name, key)``.
        This name is used afterwards to identify the normals in the Rhino model.

        """
        color = color or self.defaults.get('color.normal')

        lines = []
        for fkey, attr in self.datastructure.faces(True):
            n = self.datastructure.face_normal(fkey)
            sp = self.datastructure.face_centroid(fkey)
            ep = add_vectors(sp, scale_vector(n, scale))
            lines.append({
                'start': sp,
                'end': ep,
                'name': "{}.face.normal.{}".format(self.datastructure.name, fkey),
                'color': color,
                'arrow': 'end'
            })
        return compas_rhino.draw_lines(lines, layer=self.layer, clear=False, redraw=False)
Beispiel #30
0
    def get_vector_on_face_faces(self, point, f_key, name, vec=[0, 0, 0]):
        pt_cloud = []

        f_keys = [f_key]
        f_keys.extend(self.c_mesh.face_neighbors(f_key))
        f_keys = list(set(f_keys))

        f_vectors_a = self.c_mesh.faces_attribute(f_keys,
                                                      str(name) + '_a'
                                                      )
        f_vectors_b = self.c_mesh.faces_attribute(f_keys,
                                                      str(name) + '_b',
                                                      )
        f_vectors = ut.filter_aligned_vectors(vec, f_vectors_a, f_vectors_b)

        for f_key in f_keys:
            pt_cloud.append(self.c_mesh.face_centroid(f_key))

        weights = ut.get_dist_weights(point, pt_cloud)
        new_vectors = []
        for idx, vec in enumerate(f_vectors):
            new_vector = cg.scale_vector(vec, weights[idx])
            new_vectors.append(new_vector)

        return reduce(lambda x, y: cg.add_vectors(x, y), new_vectors)