def closest_point_on_segment(a, b, c):
    """Closest point on segment.
    Different from projection because an extremity is yielded if the projection is on the line but outside the segment.

    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.
    """

    p, distance = closest_point_on_line(a, b, c)

    ab = subtract_vectors(b, a)
    ap = subtract_vectors(p, a)

    if dot_vectors(ab, ap) < 0:
        return a, distance_point_point(c, a)
    elif length_vector(ab) < length_vector(ap):
        return b, distance_point_point(c, b)
    else:
        return p, distance
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
Esempio n. 3
0
def polyline_point(polyline, t=.5, snap_to_point=False):
    """Point on a polyline at a normalised parameter. If asked, the found position is snapped to the closest polyline node.

	Parameters
	----------
	polyline: list
	    The XYZ coordinates of the nodes of the polyline. The polyline can be closed.
	t: float 
	    The normalised parameter of the point on the polyline between 0 and 1.
	snap_to_point: bool
		If true, the closest node on the polyline is returned, if false, a point on a line.

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

	Raises
	------
	-

	"""

    if t < 0 or t > 1:
        return None

    length = sum([
        distance_point_point(polyline[i], polyline[i + 1])
        for i in range(len(polyline) - 1)
    ])
    target_length = t * length

    current_length = 0
    for i in range(len(polyline) - 1):
        current_point = polyline[i]
        next_point = polyline[i + 1]
        next_length = current_length + distance_point_point(
            current_point, next_point)
        if target_length >= current_length and target_length <= next_length:
            rest_length = target_length - current_length
            rest_t = rest_length / distance_point_point(
                current_point, next_point)
            xyz = add_vectors(
                current_point,
                scale_vector(subtract_vectors(next_point, current_point),
                             rest_t))
            if snap_to_point:
                if distance_point_point(xyz,
                                        current_point) < distance_point_point(
                                            xyz, next_point):
                    return current_point
                else:
                    return next_point
            else:
                return xyz
        else:
            current_length = next_length
 def board_intersection(pt1, vec1, len1, pt2, vec2, len2):
     line1 = line_creator(pt1, vec1, len1)
     line2 = line_creator(pt2, vec2, len2)
     # to check whether the boards are parallel
     if vec1 != vec2:
         int_pt = intersection_line_line_xy(line1, line2)
     else:
         # expand here later to deal with gluing parallel boards
         return 0
     # since intersection also hits when the lines intersect in their continuation, we have to add that one
     if distance_point_point(pt1, int_pt) < len1 / 2 and \
         distance_point_point(pt2, int_pt) < len2 / 2:
         return int_pt
     else:
         return 0
Esempio n. 5
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
def automated_smoothing_surface_constraints(mesh, surface):
	"""Apply automatically surface-related constraints to the vertices of a mesh to smooth: kinks, boundaries and surface.

	Parameters
	----------
	mesh : Mesh
		The mesh to apply the constraints to for smoothing.
	surface : Rhino surface guid
		A Rhino surface guid on which to constrain mesh vertices.

	Returns
	-------
	constraints : dict
		A dictionary of mesh constraints for smoothing as vertex keys pointing to point, curve or surface objects.

	"""

	surface = RhinoSurface.from_guid(surface)
	constraints = {}

	points = [rs.AddPoint(point) for point in surface.kinks()]
	curves = surface.borders(type = 0)

	constraints.update({vkey: surface.guid for vkey in mesh.vertices()})

	for vkey in mesh.vertices_on_boundary():
		xyz = mesh.vertex_coordinates(vkey)
		projections = {curve: distance_point_point(xyz, RhinoCurve.from_guid(curve).closest_point(xyz)) for curve in curves}
		constraints.update({vkey: min(projections, key = projections.get)})

	key_to_index = {i: vkey for i, vkey in enumerate(mesh.vertices_on_boundary())}
	vertex_coordinates = tuple(mesh.vertex_coordinates(vkey) for vkey in mesh.vertices_on_boundary())
	constraints.update({key_to_index[closest_point_in_cloud(rs.PointCoordinates(point), vertex_coordinates)[2]]: point for point in points})
	
	return constraints
Esempio n. 7
0
    def face_flatness(self, face, maxdev=0.02):
        """Compute the flatness of a face.

        Parameters
        ----------
        face : int
            The identifier of the face.

        Returns
        -------
        float
            The flatness.

        Note
        ----
        compas.geometry.mesh_flatness function currently only works for quadrilateral faces.
        This function uses the distance between each face vertex and its projected point
        on the best-fit plane of the face as the flatness metric.

        """
        deviation = 0
        polygon = self.face_coordinates(face)
        plane = bestfit_plane(polygon)
        for pt in polygon:
            pt_proj = project_point_plane(pt, plane)
            dev = distance_point_point(pt, pt_proj)
            if dev > deviation:
                deviation = dev
        return deviation
Esempio n. 8
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
Esempio n. 9
0
def xdraw_pipes(pipes, div=8):
    """ Draw a set of pipes.

    Parameters:
        pipes (list): {'radius':, 'start':, 'end':, 'color':, 'name':, 'layer':}.
        div (int): Divisions around cross-section.

    Returns:
        list: Created pipe objects.
    """
    objects = []
    bpy.ops.mesh.primitive_cylinder_add(radius=1, depth=1, vertices=div, location=[0, 0, 0])
    object = bpy.context.object
    for pipe in pipes:
        radius = pipe.get('radius', 1)
        start = pipe.get('start', [0, 0, 0])
        end = pipe.get('end', [0, 0, 1])
        L = distance_point_point(start, end)
        pos = centroid_points([start, end])
        copy = object.copy()
        copy.name = pipe.get('name', 'pipe')
        copy.rotation_euler[1] = acos((end[2] - start[2]) / L)
        copy.rotation_euler[2] = atan2(end[1] - start[1], end[0] - start[0])
        copy.location = Vector(pos)
        copy.data = copy.data.copy()
        copy.scale = ((radius, radius, L))
        copy.show_wire = True
        copy.data.materials.append(bpy.data.materials[pipe.get('color', 'white')])
        set_objects_layer([copy], pipe.get('layer', 0))
        objects.append(copy)
    delete_objects([object])
    for object in objects:
        bpy.context.scene.objects.link(object)
    deselect_all_objects()
    return objects
Esempio n. 10
0
    def face_curvature(self, fkey):
        """Dimensionless face curvature.

        Face curvature is defined as the maximum face vertex deviation from
        the best-fit plane of the face vertices divided by the average lengths of
        the face vertices to the face centroid.

        Parameters
        ----------
        fkey : int
            The face key.

        Returns
        -------
        float
            The dimensionless curvature.

        """
        vertices = self.face_vertices(fkey)
        points = [self.vertex_coordinates(key) for key in vertices]
        centroid = self.face_centroid(fkey)
        plane = bestfit_plane(points)
        max_deviation = max(
            [distance_point_plane(point, plane) for point in points])
        average_distances = vector_average(
            [distance_point_point(point, centroid) for point in points])
        return max_deviation / average_distances
Esempio n. 11
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
Esempio n. 12
0
def find_point_id(query_pt, pts, tol=EPS):
    ids = []
    for id, pt in enumerate(pts):
        if distance_point_point(query_pt, pt) < tol:
            ids.append(id)
    assert len(ids) == 1, 'duplicated pts!'
    return ids[0]
Esempio n. 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
Esempio n. 14
0
def cell_collapse_short_edge(cell, u, v, min_length=0.1):
    """Collapse short edges of a cell.

    Parameters
    ----------
    cell : Mesh
        Cell as a mesh object.
    u : hashable
        The key of the start vertex.
    v : hashable
        The key of the end vertex.
    min_length : float
        Minimum length of edges to be collapsed.

    Returns
    -------
    cell : Mesh
        Updated cell.

    """
    sp = cell.vertex_coordinates(u)
    ep = cell.vertex_coordinates(v)
    dist = distance_point_point(sp, ep)

    if dist < min_length:
        mp = midpoint_point_point(sp, ep)
        cell.vertex_update_xyz(u, mp)
        cell.vertex_update_xyz(v, mp)

    return cell
Esempio n. 15
0
def polygon_flatness(polygon):
    """Comput the flatness of a polygon.

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

    Returns
    -------
    float
        The flatness.

    Note
    ----
    compas.geometry.mesh_flatness function currently only works for quadrilateral faces.
    This function uses the distance between each face vertex and its projected point on the best-fit plane of the face as the flatness metric.

    """
    deviation = 0

    plane     = bestfit_plane(polygon)

    for pt in polygon:
        pt_proj = project_point_plane(pt, plane)
        dev     = distance_point_point(pt, pt_proj)
        if dev > deviation:
            deviation = dev

    return deviation
Esempio n. 16
0
def draw_cylinders(cylinders: List[Dict],
                   collection: Union[Text, bpy.types.Collection] = None,
                   uv: int = 10) -> List[bpy.types.Object]:
    """Draw cylinder objects as mesh primitives."""
    from math import acos
    from math import atan2
    bpy.ops.mesh.primitive_cylinder_add(location=[0, 0, 0],
                                        radius=1,
                                        depth=1,
                                        vertices=uv)
    empty = bpy.context.object
    _link_object(empty, collection)
    objects = [0] * len(cylinders)
    for index, data in enumerate(cylinders):
        sp = data['start']
        ep = data['end']
        mp = centroid_points([sp, ep])
        radius = data.get('radius', 1.0)
        length = distance_point_point(sp, ep)
        obj = empty.copy()
        obj.name = data.get('name', 'cylinder')
        obj.rotation_euler[1] = acos((ep[2] - sp[2]) / length)
        obj.rotation_euler[2] = atan2(ep[1] - sp[1], ep[0] - sp[0])
        obj.location = mp
        obj.scale = ((radius, radius, length))
        rgb = data.get('color', [1.0, 1.0, 1.0])
        _set_object_color(obj, rgb)
        objects[index] = obj
    _link_objects(objects, collection)
    empty.hide_set(True)
    return objects
Esempio n. 17
0
def draw_cylinders(cylinders, div=10, layer=None):
    # don't set the obvious defaults?
    bpy.ops.mesh.primitive_cylinder_add(location=[0, 0, 0],
                                        radius=1,
                                        depth=1,
                                        vertices=div)
    empty = bpy.context.active_object
    objects = [0] * len(cylinders)
    for index, data in enumerate(cylinders):
        sp = data['start']
        ep = data['end']
        mp = centroid_points([sp, ep])
        radius = data.get('radius', 1.0)
        length = distance_point_point(sp, ep)
        obj = empty.copy()
        obj.name = data.get('name', 'cylinder')
        # get this from geometry package
        obj.rotation_euler[1] = acos((ep[2] - sp[2]) / length)
        obj.rotation_euler[2] = atan2(ep[1] - sp[1], ep[0] - sp[0])
        obj.location = mp
        obj.scale = ((radius, radius, length))
        rgb = data.get('color') or [1.0, 1.0, 1.0]
        set_object_color(obj, rgb)
        objects[index] = obj
    delete_object(empty)
    link_objects(objects, layer=layer)
    return objects
Esempio n. 18
0
    def face_flatness(self, fkey, maxdev=0.02):
        """Compute the flatness of the mesh face.

        Parameters
        ----------
        fkey : int
            The identifier of the face.
        maxdev : float, optional
            A maximum value for the allowed deviation from flatness.
            Default is ``0.02``.

        Returns
        -------
        float
            The flatness.

        Notes
        -----
        Flatness is computed as the ratio of the distance between the diagonals
        of the face to the average edge length. A practical limit on this value
        realted to manufacturing is 0.02 (2%).

        Warnings
        --------
        This method only makes sense for quadrilateral faces.
        """
        vertices = self.face_vertices(fkey)
        f = len(vertices)
        points = self.vertices_attributes('xyz', keys=vertices)
        lengths = [distance_point_point(a, b) for a, b in pairwise(points + points[:1])]
        length = sum(lengths) / f
        d = distance_line_line((points[0], points[2]), (points[1], points[3]))
        return (d / length) / maxdev
Esempio n. 19
0
    def pull_to_edge(self, s_mesh, f_id):
        for u, v in s_mesh.c_mesh.face_halfedges(f_id):
            line = s_mesh.c_mesh.edge_coordinates(u, v)

            if cg.distance_point_point(line[0], line[1]) > TOL:
                if cg.distance_point_line(self.pos, line) < TOL:
                    return (u, v)
        return None
 def total_length_of_paths(self):
     """ Returns the total length of all paths. Does not consider extruder toggle. """
     total_length = 0
     for layer_key in self.printpoints_dict:
         for path_key in self.printpoints_dict[layer_key]:
             for prev, curr in pairwise(
                     self.printpoints_dict[layer_key][path_key]):
                 length = distance_point_point(prev.pt, curr.pt)
                 total_length += length
     return total_length
Esempio n. 21
0
def reorder_vertical_layers(slicer, align_with):
    """Re-orders the vertical layers in a specific way

    Parameters
    ----------
    slicer: :class:`compas_slicer.slicers.BaseSlicer`
        An instance of one of the compas_slicer.slicers classes.
    align_with: str or :class:`compas.geometry.Point`
        x_axis       = reorders the vertical layers starting from the positive x-axis
        y_axis       = reorders the vertical layers starting from the positive y-axis
        Point(x,y,z) = reorders the vertical layers starting from a given Point
    """

    if align_with == "x_axis":
        align_pt = Point(2**32, 0, 0)
    elif align_with == "y_axis":
        align_pt = Point(0, 2**32, 0)
    elif isinstance(align_with, Point):
        align_pt = align_with
    else:
        raise NameError("Unknown align_with : " + str(align_with))

    logger.info(
        "Re-ordering vertical layers to start with the vertical layer closest to: %s"
        % align_with)

    for layer in slicer.layers:
        assert layer.min_max_z_height[0] is not None and layer.min_max_z_height[1] is not None, \
            "To use the 'reorder_vertical_layers function you need first to calculate the layers' z_bounds. To do " \
            "that use the function 'Layer.calculate_z_bounds()'"

    # group vertical layers based on the min_max_z_height
    grouped_iter = itertools.groupby(slicer.layers,
                                     lambda x: x.min_max_z_height)
    grouped_layer_list = [list(group) for _key, group in grouped_iter]

    reordered_layers = []

    for grouped_layers in grouped_layer_list:
        distances = []
        for vert_layer in grouped_layers:
            # recreate head_centroid_pt as compas.Point
            head_centroid_pt = Point(vert_layer.head_centroid[0],
                                     vert_layer.head_centroid[1],
                                     vert_layer.head_centroid[2])
            # measure distance
            distances.append(distance_point_point(head_centroid_pt, align_pt))

        # sort lists based on closest distance to align pt
        grouped_new = [x for _, x in sorted(zip(distances, grouped_layers))]
        reordered_layers.append(grouped_new)

    # flatten list
    slicer.layers = [item for sublist in reordered_layers for item in sublist]
Esempio n. 22
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
def shoot_rays(room):
    """Performs the raytracing process using the room properties. Calculates
    all reflections, including geometry, times and energy values per segment.

    Parameters
    ----------
    room: object
        The room object to be analyzed.

    """
    # TODO: Figure out if it is possible to cut ray one reflection short.
    # TODO: how to get rid of deepcopy? it is super slow.
    # TODO: should propably use some generators, is that possible?

    directions = room.source.directions
    ref_srf = [room.surfaces[gk]['guid'] for gk in room.surfaces]
    ref_map = {room.surfaces[sk]['guid']: sk for sk in room.surfaces}

    room.ray_times = {dk: {} for dk in directions}
    room.ray_lengths = {dk: {} for dk in directions}
    room.ray_powers = {dk: {} for dk in directions}
    room.ray_lines = {dk: {} for dk in directions}

    for dk in directions:
        dir = directions[dk]
        src_ = room.source.xyz
        w = room.source.ray_power[dk]
        min_w = room.source.ray_minpower[dk]
        time = 0
        i = 0
        min_power = False
        while time < room.ctime and not min_power:
            i += 1
            ray = rs.ShootRay(ref_srf, src_, dir, 2)
            srf = rs.PointClosestObject(ray[0], ref_srf)[0]
            mp_list = []
            if i > 0:
                sk = ref_map[str(srf)]
                abs = room.materials[room.surfaces[sk]['material']].absorption
                for wk in w:
                    w[wk] *= (1 - abs[wk])
                    mp_list.append(w[wk] < min_w[wk])
            min_power = all(mp_list)
            l = distance_point_point(ray[0], ray[1])
            t = int((l / 343.0) * 1000)
            room.ray_times[dk][i] = t
            room.ray_lengths[dk][i] = l
            room.ray_powers[dk][i] = deepcopy(w)
            room.ray_lines[dk][i] = ((ray[0].X, ray[0].Y, ray[0].Z),
                                     (ray[1].X, ray[1].Y, ray[1].Z))
            dir = vector_from_points(ray[1], ray[2])
            src_ = ray[1]
            time += t
 def total_print_time(self):
     """ If the print speed is defined, it returns the total time of the print, else returns None"""
     if self.printpoints_dict['layer_0']['path_0'][
             0].velocity is not None:  # assume that all ppts are set or none
         total_time = 0
         for layer_key in self.printpoints_dict:
             for path_key in self.printpoints_dict[layer_key]:
                 for prev, curr in pairwise(
                         self.printpoints_dict[layer_key][path_key]):
                     length = distance_point_point(prev.pt, curr.pt)
                     total_time += length / curr.velocity
         return total_time
Esempio n. 25
0
def network_order(start, structure, network):
    """ Extract node and element orders from a Network for a given start-point.

    Parameters
    ----------
    start : list
        Start point co-ordinates.
    structure : obj
        Structure object.
    network : obj
        Network object.

    Returns
    -------
    list
        Ordered nodes.
    list
        Ordered elements.
    list
        Cumulative lengths at element mid-points.
    float
        Total length.

    """

    gkey_key = network.gkey_key()
    start = gkey_key[geometric_key(start, '{0}f'.format(structure.tol))]
    leaves = network.leaves()
    leaves.remove(start)
    end = leaves[0]

    adjacency = {i: network.vertex_neighbors(i) for i in network.vertices()}
    weight = {(u, v): 1 for u, v in network.edges()}
    weight.update({(v, u): weight[(u, v)] for u, v in network.edges()})
    path = dijkstra_path(adjacency, weight, start, end)
    nodes = [
        structure.check_node_exists(network.vertex_coordinates(i))
        for i in path
    ]
    elements, arclengths, length = [], [], 0

    for i in range(len(nodes) - 1):
        sp = nodes[i]
        ep = nodes[i + 1]
        elements.append(structure.check_element_exists([sp, ep]))
        xyz_sp = structure.node_xyz(sp)
        xyz_ep = structure.node_xyz(ep)
        dL = distance_point_point(xyz_sp, xyz_ep)
        arclengths.append(length + dL / 2.)
        length += dL

    return nodes, elements, arclengths, length
    def board_intersection(brd1, brd2):
        vec1 = Vector(brd1.length_vector[0], brd1.length_vector[1], brd1.length_vector[2])
        vec2 = Vector(brd2.length_vector[0], brd2.length_vector[1], brd2.length_vector[2])
        line1 = line_creator(brd1.centre_point, vec1, brd1.length)
        line2 = line_creator(brd2.centre_point, vec2, brd2.length)

        # to check whether the boards are parallel
        if vec1.angle(vec2) > 0.1:
            int_pt = intersection_line_line_xy(line1, line2)
        else:
            target_width = min(brd1.width, brd2.width)
            upper_boarder_1 = brd1.centre_point + brd1.width_vector*brd1.width
            lower_boarder_1 = brd1.centre_point

            # expand here later to deal with gluing parallel boards
            return 0
        # since intersection also hits when the lines intersect in their continuation, we have to add that one
        if distance_point_point(brd1.centre_point, int_pt) < brd1.length / 2 and \
            distance_point_point(brd2.centre_point, int_pt) < brd2.length / 2:
            return int_pt
        else:
            return 0
Esempio n. 27
0
    def get_dist_weights(self, point, point_cloud):
        dst = []
        weigths = []

        for c_point in point_cloud:
            dst.append(cg.distance_point_point(point, c_point))

        if len(dst) > 1:
            massDistance = reduce(lambda x, y: x + y, dst)
            return list(map(lambda x: x / massDistance, dst))

        else:
            return [1.0]
Esempio n. 28
0
def astar_shortest_path(graph, root, goal):
    """Find the shortest path between two vertices of a graph or mesh using the A* search algorithm.

    Parameters
    ----------
    graph : :class:`compas.datastructures.Network` | :class:`compas.datastructures.Mesh`
        A network or mesh data structure.
    root : hashable
        The identifier of the starting node.
    goal : hashable
        The identifier of the ending node.

    Returns
    -------
    list[hashable] | None
        The path from root to goal, or None, if no path exists between the vertices.

    References
    ----------
    https://en.wikipedia.org/wiki/A*_search_algorithm

    """
    adjacency = graph.adjacency
    weights = {}
    for u, v in graph.edges():
        u_coords = _get_coordinates(u, graph)
        v_coords = _get_coordinates(v, graph)
        distance = distance_point_point(u_coords, v_coords)
        weights[(u, v)] = distance
        weights[(v, u)] = distance

    heuristic = {}
    goal_coords = _get_coordinates(goal, graph)
    points = _get_points(graph)
    for u in points:
        u_coords = _get_coordinates(u, graph)
        heuristic[u] = distance_point_point(u_coords, goal_coords)

    return astar_lightest_path(adjacency, weights, heuristic, root, goal)
Esempio n. 29
0
def bmesh_edge_lengths(bmesh):
    """ Retrieve the edge legnths of a Blender mesh.

    Parameters:
        bmesh (obj): Blender mesh object.

    Returns:
        list: Lengths of each edge.
        float: Total length.
    """
    X, uv, _ = bmesh_data(bmesh)
    lengths = [distance_point_point(X[u], X[v]) for u, v in uv]
    L = sum(lengths)
    return lengths, L
Esempio n. 30
0
    def get_layer_ppts(self, layer, base_boundary):
        """ Creates the PrintPoints of a single layer."""
        max_layer_height = get_param(self.parameters,
                                     key='max_layer_height',
                                     defaults_type='layers')
        min_layer_height = get_param(self.parameters,
                                     key='min_layer_height',
                                     defaults_type='layers')
        avg_layer_height = get_param(self.parameters, 'avg_layer_height',
                                     'layers')

        all_pts = [pt for path in layer.paths for pt in path.points]
        closest_fks, projected_pts = utils.pull_pts_to_mesh_faces(
            self.slicer.mesh, all_pts)
        normals = [
            Vector(*self.slicer.mesh.face_normal(fkey)) for fkey in closest_fks
        ]

        count = 0
        crv_to_check = Path(
            base_boundary.points,
            True)  # creation of fake path for the lower boundary

        layer_ppts = {}
        for i, path in enumerate(layer.paths):
            layer_ppts['path_%d' % i] = []

            for p in path.points:
                cp = closest_point_on_polyline(p,
                                               Polyline(crv_to_check.points))
                d = distance_point_point(cp, p)

                ppt = PrintPoint(pt=p,
                                 layer_height=avg_layer_height,
                                 mesh_normal=normals[count])

                ppt.closest_support_pt = Point(*cp)
                ppt.distance_to_support = d
                ppt.layer_height = max(min(d, max_layer_height),
                                       min_layer_height)
                ppt.up_vector = Vector(
                    *normalize_vector(Vector.from_start_end(cp, p)))
                ppt.frame = ppt.get_frame()

                layer_ppts['path_%d' % i].append(ppt)
                count += 1

            crv_to_check = path

        return layer_ppts