Esempio n. 1
0
    def from_points(cls, point, point_xaxis, point_xyplane):
        """Constructs a frame from 3 points.

        Parameters
        ----------
        point : point
            The origin of the frame.
        point_xaxis : point
            A point on the x-axis of the frame.
        point_xyplane : point
            A point within the xy-plane of the frame.

        Returns
        -------
        :class:`compas.geometry.Frame`
            The constructed frame.

        Examples
        --------
        >>> frame = Frame.from_points([0, 0, 0], [1, 0, 0], [0, 1, 0])
        >>> frame.point
        Point(0.000, 0.000, 0.000)
        >>> frame.xaxis
        Vector(1.000, 0.000, 0.000)
        >>> frame.yaxis
        Vector(0.000, 1.000, 0.000)
        """
        xaxis = subtract_vectors(point_xaxis, point)
        xyvec = subtract_vectors(point_xyplane, point)
        yaxis = cross_vectors(cross_vectors(xaxis, xyvec), xaxis)
        return cls(point, xaxis, yaxis)
Esempio n. 2
0
def barycentric_coordinates(point, triangle):
    """Compute the barycentric coordinates of a point wrt to a triangle.

    Parameters
    ----------
    point: list
        Point location.
    triangle: (point, point, point)
        A triangle defined by 3 points.

    Returns
    -------
    list
        The barycentric coordinates of the point.

    """
    a, b, c = triangle
    v0 = subtract_vectors(b, a)
    v1 = subtract_vectors(c, a)
    v2 = subtract_vectors(point, a)
    d00 = dot_vectors(v0, v0)
    d01 = dot_vectors(v0, v1)
    d11 = dot_vectors(v1, v1)
    d20 = dot_vectors(v2, v0)
    d21 = dot_vectors(v2, v1)
    D = d00 * d11 - d01 * d01
    v = (d11 * d20 - d01 * d21) / D
    w = (d00 * d21 - d01 * d20) / D
    u = 1.0 - v - w
    return u, v, w
Esempio n. 3
0
def intersection_line_triangle(line, triangle, tol=1e-6):
    """Computes the intersection point of a line (ray) and a triangle
    based on the Moeller Trumbore intersection algorithm

    Parameters
    ----------
    line : [point, point] | :class:`compas.geometry.Line`
        Two points defining the line.
    triangle : [point, point, point]
        XYZ coordinates of the triangle corners.
    tol : float, optional
        A tolerance for membership verification.

    Returns
    -------
    [float, float, float] | None
        The intersection point between the line and the triangle,
        or None if the line and the plane are parallel.

    """
    a, b, c = triangle
    ab = subtract_vectors(b, a)
    ac = subtract_vectors(c, a)
    n = cross_vectors(ab, ac)
    plane = a, n

    x = intersection_line_plane(line, plane, tol=tol)

    if x:
        if is_point_in_triangle(x, triangle):
            return x
Esempio n. 4
0
 def _cross_edges(edge1, edge2):
     a, b = edge1
     c, d = edge2
     edge1_vec = normalize_vector(subtract_vectors(b, a))
     edge2_vec = normalize_vector(subtract_vectors(d, c))
     cross = cross_vectors(edge1_vec, edge2_vec)
     return cross
Esempio n. 5
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)
Esempio n. 6
0
def draw_lines(lines, layer=None, centroid=True):
    objects = [0] * len(lines)
    for index, data in enumerate(lines):
        sp = data['start']
        ep = data['end']
        mp = centroid_points([sp, ep]) if centroid else [0, 0, 0]
        name = data.get('name', 'line')
        curve = bpy.data.curves.new(name, type='CURVE')
        curve.dimensions = '3D'
        spline = curve.splines.new('NURBS')
        spline.points.add(2)
        spline.points[0].co = list(subtract_vectors(sp, mp)) + [1]
        spline.points[1].co = list(subtract_vectors(ep, mp)) + [1]
        spline.order_u = 1
        obj = bpy.data.objects.new(name, curve)
        obj.location = mp
        obj.data.fill_mode = 'FULL'
        obj.data.bevel_depth = data.get('width', 0.05)
        obj.data.bevel_resolution = 0
        obj.data.resolution_u = 20
        rgb = data.get('color') or [1.0, 1.0, 1.0]
        set_object_color(obj, rgb)
        objects[index] = obj
    link_objects(objects, layer=layer)
    return objects
Esempio n. 7
0
def polygon_area_footprint(polygon):
    """Compute the non-oriented area of a polygon (can be convex or concave).

    Parameters
    ----------
    polygon : list of lists
        A list of polygon point coordinates.

    Returns
    -------
    float
        The non-oriented area of the polygon.

    """
    area = 0
    w = centroid_points(polygon)

    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)
        area += length_vector(normal)

    return area
def GetConvexPolygonArea(polygon):

    center = [0.0,0.0,0.0]


    for p in polygon:
        center=[center[0]+p[0],center[1]+p[1],center[2]+p[2]]
   
    n = len(polygon.points)
    center=[center[0]/n,center[1]/n,center[2]/n]

    areaSum = 0.0



    for i in range(0, n):
        
        p0 = polygon[i]
        p1 = polygon[(i+1)%n]
        p2 = center
        u = subtract_vectors(p2,p1)
        v = subtract_vectors(p2,p0)
        area = length_vector(cross_vectors(u,v))*0.5
        areaSum+=area

    

    print(areaSum)

    return areaSum
Esempio n. 9
0
    def separate(self, dst, boids, mxf=0.02, mxs=0.02):
        count = 0
        sum_vec = [0, 0, 0]
        tol = 1e-6

        for boid in boids:
            d = cg.distance_point_point(self.pos, boid.pos)
            print('distance is {}'.format(d))

            if d > tol and d < dst:
                dif = subtract_vectors(self.pos, boid.pos)
                dif = cg.normalize_vector(cg.scale_vector(dif, 1/d))
                sum_vec = cg.add_vectors(dif, sum_vec)
                count += 1

            if count > 0:
                sum_vec = cg.normalize_vector(cg.scale_vector(sum_vec,
                                                              1/count)
                                              )
                sum_vec = cg.scale_vector(sum_vec, mxs)

                # Reynold's steering formula
                steer = subtract_vectors(sum_vec, self.vel)
                steer = ut.limit_vector(steer, mxf)
                return steer
        return sum_vec
Esempio n. 10
0
def draw_lines(lines: List[Dict],
               collection: Union[Text, bpy.types.Collection] = None,
               centroid: bool = True) -> List[bpy.types.Object]:
    """Draw line objects."""
    L = len(lines)
    N = len(str(L))
    objects = [0] * L
    for index, data in enumerate(lines):
        sp = data['start']
        ep = data['end']
        origin = centroid_points([sp, ep]) if centroid else [0, 0, 0]
        name = data.get('name', f'L.{index:0{N}d}')
        curve = bpy.data.curves.new(name, type='CURVE')
        curve.dimensions = '3D'
        spline = curve.splines.new('POLY')
        spline.points.add(1)
        spline.points[0].co = subtract_vectors(sp, origin) + [1.0]
        spline.points[1].co = subtract_vectors(ep, origin) + [1.0]
        spline.order_u = 1
        obj = bpy.data.objects.new(name, curve)
        obj.location = origin
        obj.data.fill_mode = 'FULL'
        obj.data.bevel_depth = data.get('width', 0.05)
        obj.data.bevel_resolution = 0
        obj.data.resolution_u = 20
        rgb = data.get('color', [1.0, 1.0, 1.0])
        _set_object_color(obj, rgb)
        objects[index] = obj
    _link_objects(objects, collection)
    return objects
Esempio n. 11
0
def draw_line(start=[0, 0, 0],
              end=[1, 1, 1],
              width=0.05,
              centroid=True,
              name='line',
              color=[1, 1, 1],
              layer=None):
    mp = centroid_points([start, end]) if centroid else [0, 0, 0]
    curve = bpy.data.curves.new(name, type='CURVE')
    curve.dimensions = '3D'
    object = bpy.data.objects.new(name, curve)
    object.location = mp
    spline = curve.splines.new('NURBS')
    spline.points.add(2)
    spline.points[0].co = list(subtract_vectors(start, mp)) + [1]
    spline.points[1].co = list(subtract_vectors(end, mp)) + [1]
    spline.order_u = 1
    object.data.fill_mode = 'FULL'
    object.data.bevel_depth = width
    object.data.bevel_resolution = 0
    object.data.resolution_u = 20
    object.color = color + [1]
    bpy.context.collection.objects.link(object)
    if layer:
        set_objects_layer(objects=[object], layer=layer)
    return object
Esempio n. 12
0
 def DrawForeground(self, e):
     draw_dot = e.Display.DrawDot
     draw_arrows = e.Display.DrawArrows
     a = self.mouse.p1
     b = self.mouse.p2
     ab = subtract_vectors(b, a)
     Lab = length_vector(ab)
     if not Lab:
         return
     for index, vertex in enumerate(self.form_vertex_xyz):
         c = self.form_vertex_xyz[vertex]
         D = length_vector(
             cross_vectors(subtract_vectors(a, c), subtract_vectors(b, c)))
         if D / Lab < self.tol:
             point = Point3d(*c)
             draw_dot(point, str(index), self.dotcolor, self.textcolor)
             lines = List[Line](len(self.form_vertex_edges[vertex]))
             for u, v in self.form_vertex_edges[vertex]:
                 lines.Add(
                     Line(Point3d(*self.form_vertex_xyz[u]),
                          Point3d(*self.form_vertex_xyz[v])))
             draw_arrows(lines, self.linecolor)
             lines = List[Line](len(self.force_face_edges[vertex]))
             for u, v in self.force_face_edges[vertex]:
                 lines.Add(
                     Line(Point3d(*self.force_vertex_xyz[u]),
                          Point3d(*self.force_vertex_xyz[v])))
             draw_arrows(lines, self.linecolor)
             break
Esempio n. 13
0
def project_point_line(point, line):
    """Project a point onto a line.

    Parameters
    ----------
    point : list of float
        XYZ coordinates of the point.
    line : tuple
        Two points defining the projection line.

    Returns
    -------
    list
        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)
Esempio n. 14
0
 def face_normal(self, fkey, unitized=True):
     points = self.face_coordinates(fkey)
     normal = polygon_normal_oriented(points, unitized)
     if length_vector(normal) == 0:
         uv = subtract_vectors(points[1], points[0])
         vw = subtract_vectors(points[2], points[1])
         normal = normalize_vector(cross_vectors(uv, vw))
     return normal
Esempio n. 15
0
 def halfface_oriented_normal(self, hfkey, unitized=True):
     vertices = self.halfface_vertices(hfkey)
     points = [self.vertex_coordinates(vkey) for vkey in vertices]
     normal = polygon_normal_oriented(points, unitized)
     if length_vector(normal) == 0:
         uv = subtract_vectors(points[1], points[0])
         vw = subtract_vectors(points[2], points[1])
         normal = normalize_vector(cross_vectors(uv, vw))
     return normal
Esempio n. 16
0
    def DrawForeground(self, e):
        p1 = self.mouse.p1
        p2 = self.mouse.p2
        v12 = subtract_vectors(p2, p1)
        l12 = length_vector(v12)

        # force diagram

        for ckey in self.volmesh.cell:
            p0 = self.volmesh.cell_center(ckey)
            dual_p0 = self.network.vertex_coordinates(ckey)
            v01 = subtract_vectors(p1, p0)
            v02 = subtract_vectors(p2, p0)
            l = length_vector(cross_vectors(v01, v02))

            if l12 == 0.0 or (l / l12) < self.tol:

                hf_colors = {}

                nbr_vkeys = self.network.vertex_neighbours(ckey)

                for index, nbr_vkey in enumerate(nbr_vkeys):
                    value = float(index) / (len(nbr_vkeys) - 1)

                    print('boo', value)

                    color = i_to_rgb(value)
                    color = System.Drawing.Color.FromArgb(*color)
                    nbr_xyz = self.network.vertex_coordinates(nbr_vkey)
                    e.Display.DrawLine(Point3d(*dual_p0), Point3d(*nbr_xyz),
                                       color, 4)

                    hfkey = self.volmesh.cell_pair_halffaces(ckey, nbr_vkey)[0]
                    hf_colors[hfkey] = color

                for hfkey in self.volmesh.cell_halffaces(ckey):
                    vkeys = self.volmesh.halfface_vertices(hfkey)
                    face_coordinates = [
                        self.volmesh.vertex_coordinates(vkey) for vkey in vkeys
                    ]
                    face_coordinates.append(face_coordinates[0])
                    polygon_xyz = [Point3d(*xyz) for xyz in face_coordinates]
                    e.Display.DrawDot(Point3d(*p0), str(ckey), self.dotcolor,
                                      self.textcolor)
                    e.Display.DrawPolyline(polygon_xyz, self.edgecolor, 2)

                    e.Display.DrawDot(Point3d(*dual_p0), str(ckey),
                                      self.dotcolor, self.textcolor)

                    if hfkey in hf_colors:
                        hf_color = hf_colors[hfkey]
                        e.Display.DrawPolygon(polygon_xyz,
                                              hf_color,
                                              filled=True)

                break
def boundary_triangulation(outer_boundary, inner_boundaries, polyline_features = [], point_features = [], src='numpy_rpc'):
	"""Generate Delaunay triangulation between a planar outer boundary and planar inner boundaries. All vertices lie the boundaries.

	Parameters
	----------
	outer_boundary : list
		Planar outer boundary as list of vertex coordinates.
	inner_boundaries : list
		List of planar inner boundaries as lists of vertex coordinates.
	polyline_features : list
		List of planar polyline_features as lists of vertex coordinates.
	point_features : list
		List of planar point_features as lists of vertex coordinates.
	src : str
		Source of Delaunay triangulation. Default is NumPy via RPC.

	Returns
	-------
	delaunay_mesh : Mesh
		The Delaunay mesh.

	"""

	# generate planar Delaunay triangulation
	vertices = [pt for boundary in [outer_boundary] + inner_boundaries + polyline_features for pt in boundary] + point_features
	if src == 'numpy_rpc':
		faces = delaunay_numpy_rpc(vertices)
	elif src == 'numpy':
		faces = delaunay_numpy(vertices)
	else:
		delaunay_compas(vertices)
	
	delaunay_mesh = Mesh.from_vertices_and_faces(vertices, faces)
	
	# delete false faces with aligned vertices
	for fkey in list(delaunay_mesh.faces()):
		a, b, c = [delaunay_mesh.vertex_coordinates(vkey) for vkey in delaunay_mesh.face_vertices(fkey)]
		ab = subtract_vectors(b, a)
		ac = subtract_vectors(c, a)
		if length_vector(cross_vectors(ab, ac)) == 0:
			delaunay_mesh.delete_face(fkey)

	# delete faces outisde the borders
	for fkey in list(delaunay_mesh.faces()):
		centre = trimesh_face_circle(delaunay_mesh, fkey)[0]
		if not is_point_in_polygon_xy(centre, outer_boundary) or any([is_point_in_polygon_xy(centre, inner_boundary) for inner_boundary in inner_boundaries]):
			delaunay_mesh.delete_face(fkey)

	# topological cut along the feature polylines through unwelding
	vertex_map = {geometric_key(delaunay_mesh.vertex_coordinates(vkey)): vkey for vkey in delaunay_mesh.vertices()}
	edges = [edge for polyline in polyline_features for edge in pairwise([vertex_map[geometric_key(point)] for point in polyline])]
	mesh_unweld_edges(delaunay_mesh, edges)

	return delaunay_mesh
Esempio n. 18
0
 def from_bounding_box(cls, bbox):
     a = bbox[0]
     b = bbox[1]
     d = bbox[3]
     e = bbox[4]
     xaxis = Vector(*subtract_vectors(d, a))
     yaxis = Vector(*subtract_vectors(b, a))
     zaxis = Vector(*subtract_vectors(e, a))
     xsize = xaxis.length
     ysize = yaxis.length
     zsize = zaxis.length
     frame = Frame(a, xaxis, yaxis)
     return cls(frame, xsize, ysize, zsize)
    def branches_splitting_flipped_faces(self):
        """Add new branches to fix the problem of polyline patches that would form flipped faces in the decomposition mesh.

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

		"""

        new_branches = []
        centre_to_fkey = {
            geometric_key(trimesh_face_circle(self, fkey)[0]): fkey
            for fkey in self.faces()
        }

        # compute total rotation of polyline
        for polyline in self.branches_singularity_to_singularity():
            angles = [
                angle_vectors_signed(subtract_vectors(v, u),
                                     subtract_vectors(w, v), [0., 0., 1.])
                for u, v, w in window(polyline, n=3)
            ]
            # subdivide once per angle limit in rotation
            if abs(sum(angles)) > self.flip_angle_limit:
                # the step between subdivision points in polylines (+ 2 for the extremities, which will be discarded)
                alone = len(self.compas_singular_faces()) == 0
                n = floor(abs(sum(angles)) / self.flip_angle_limit) + 1
                step = int(floor(len(polyline) / n))
                # add new branches from corresponding face in Delaunay mesh
                seams = polyline[::step]
                if polyline[-1] != seams[-1]:
                    if len(seams) == n + 1:
                        del seams[-1]
                    seams.append(polyline[-1])
                if alone:
                    seams = seams[0:-1]
                else:
                    seams = seams[1:-1]
                for point in seams:
                    fkey = centre_to_fkey[geometric_key(point)]
                    for edge in self.face_halfedges(fkey):
                        if 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
Esempio n. 20
0
 def intersect(self):
     intersections = []
     for u, v in list(self.mesh.edges()):
         a = self.mesh.vertex_attributes(u, 'xyz')
         b = self.mesh.vertex_attributes(v, 'xyz')
         x = intersection_segment_plane((a, b), self.plane)
         if not x:
             continue
         L_ax = length_vector(subtract_vectors(x, a))
         L_ab = length_vector(subtract_vectors(b, a))
         t = L_ax / L_ab
         key = self.mesh.split_edge(u, v, t=t, allow_boundary=True)
         intersections.append(key)
     self._intersections = intersections
Esempio n. 21
0
def extrude_normal(polygon, distance, plane=None):
    if plane is None:
        x, y, z = cross_vectors(subtract_vectors(polygon[0], polygon[1]),
                                subtract_vectors(polygon[0], polygon[2]))
        normal = Vector(x, y, z)
    else:
        normal = plane.normal
    Vector.unitize(normal)
    normal = scale_vector(normal, distance)
    # normal = Vector(x, y, z)

    moved = [add_vectors(pt, normal) for pt in polygon]
    polygon.extend(moved)
    return polygon
Esempio n. 22
0
def reflect_line_triangle(line, triangle, tol=1e-6):
    """Bounce a line of a reflection triangle.

    Parameters
    ----------
    line : tuple
        Two points defining the line.
    triangle : tuple
        The triangle vertices.
    tol : float, optional
        A tolerance for membership verification.
        Default is ``1e-6``.

    Returns
    -------
    tuple
        The reflected line defined by the intersection point of the line and triangle
        and the mirrored start point of the line with respect to a line perpendicular
        to the triangle through the intersection.

    Notes
    -----
    The direction of the line and triangle are important.
    The line is only reflected if it points towards the front of the triangle.
    This is true if the dot product of the direction vector of the line and the
    normal vector of the triangle is smaller than zero.

    Examples
    --------
    >>> triangle = [1.0, 0, 0], [-1.0, 0, 0], [0, 0, 1.0]
    >>> line = [-1, 1, 0], [-0.5, 0.5, 0]
    >>> reflect_line_triangle(line, triangle)
    ([0.0, 0.0, 0.0], [1.0, 1.0, 0.0])

    """
    x = intersection_line_triangle(line, triangle, tol=tol)
    if not x:
        return

    a, b = line
    t1, t2, t3 = triangle
    ab = subtract_vectors(b, a)
    n = cross_vectors(subtract_vectors(t2, t1), subtract_vectors(t3, t1))

    if dot_vectors(ab, n) > 0:
        # the line does not point towards the front of the triangle
        return

    mirror = x, add_vectors(x, n)
    return x, mirror_point_line(a, mirror)
    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
Esempio n. 24
0
 def DrawForeground(self, e):
     p1 = self.mouse.p1
     p2 = self.mouse.p2
     v12 = subtract_vectors(p2, p1)
     l12 = length_vector(v12)
     for index, (key, attr) in enumerate(self.mesh.vertices(True)):
         p0 = attr['x'], attr['y'], attr['z']
         text = str(index)
         v01 = subtract_vectors(p1, p0)
         v02 = subtract_vectors(p2, p0)
         l = length_vector(cross_vectors(v01, v02))  # noqa: E741
         if l12 == 0.0 or (l / l12) < self.tol:
             point = Point3d(*p0)
             e.Display.DrawDot(point, text, self.dotcolor, self.textcolor)
             break
def CalcAreaPolygon(polygon):

    totalArea = 0.0
    n = len(polygon.points)
    for i in range(0, n):
        v0 = polygon[i]
        v1 = polygon[(i + 1) % n]
        v2 = polygon.centroid
        a = subtract_vectors(v2, v1)
        b = subtract_vectors(v2, v0)
        cross_ab = cross_vectors(a, b)
        area = 0.5 * length_vector(cross_ab)
        totalArea += area

    return totalArea
Esempio n. 26
0
 def edge_vector(self, u, v, unitized=True):
     u_xyz = self.vertex_coordinates(u)
     v_xyz = self.vertex_coordinates(v)
     vector = subtract_vectors(v_xyz, u_xyz)
     if unitized:
         return normalize_vector(vector)
     return vector
Esempio n. 27
0
 def from_bounding_box(cls, bbox):
     # this should put the frame at the centroid of the box
     # not at the bottom left corner
     a = bbox[0]
     b = bbox[1]
     d = bbox[3]
     e = bbox[4]
     xaxis = Vector(*subtract_vectors(d, a))
     yaxis = Vector(*subtract_vectors(b, a))
     zaxis = Vector(*subtract_vectors(e, a))
     xsize = xaxis.length
     ysize = yaxis.length
     zsize = zaxis.length
     frame = Frame(a, xaxis, yaxis)
     frame.point += frame.xaxis * 0.5 * xsize + frame.yaxis * 0.5 * ysize + frame.zaxis * 0.5 * zsize
     return cls(frame, xsize, ysize, zsize)
Esempio n. 28
0
def draw_pipes(pipes: List[Dict],
               collection: Union[Text, bpy.types.Collection] = None,
               centroid: bool = True,
               smooth: bool = True) -> List[bpy.types.Object]:
    """Draw polyline objects."""
    P = len(pipes)
    N = len(str(P))
    objects = [0] * P
    for index, data in enumerate(pipes):
        points = data['points']
        origin = centroid_points(points) if centroid else [0, 0, 0]
        name = data.get('name', f'POLY.{index:0{N}d}')
        curve = bpy.data.curves.new(name, type='CURVE')
        curve.dimensions = '3D'
        curve.fill_mode = 'FULL'
        curve.bevel_depth = data.get('width', 0.05)
        curve.bevel_resolution = 0
        curve.resolution_u = 20
        curve.use_fill_caps = True
        if smooth:
            spline = curve.splines.new('NURBS')
        else:
            spline = curve.splines.new('POLY')
        spline.points.add(len(points) - 1)
        for i, point in enumerate(points):
            spline.points[i].co = subtract_vectors(point, origin) + [1.0]
        spline.order_u = 1
        obj = bpy.data.objects.new(name, curve)
        obj.location = origin
        rgb = data.get('color', [1.0, 1.0, 1.0])
        _set_object_color(obj, rgb)
        objects[index] = obj
    _link_objects(objects, collection)
    return objects
Esempio n. 29
0
def mirror_vector_vector(v1, v2):
    """Mirrors vector about vector.

    Parameters
    ----------
    v1 : [float, float, float] | :class:`compas.geometry.Vector`
        The vector.
    v2 : [float, float, float] | :class:`compas.geometry.Vector`
        The normalized vector as mirror axis

    Returns
    -------
    [float, float, float]
        The mirrored vector.

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

    References
    ----------
    .. [1] Math Stack Exchange. *How to get a reflection vector?*
           Available at: https://math.stackexchange.com/questions/13261/how-to-get-a-reflection-vector.

    """
    return subtract_vectors(v1, scale_vector(v2, 2 * dot_vectors(v1, v2)))
Esempio n. 30
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