diff options
| author | Lex Neva <github.com@lexneva.name> | 2022-04-28 23:25:52 -0400 |
|---|---|---|
| committer | Kaalleen <reni@allenka.de> | 2022-05-04 19:18:33 +0200 |
| commit | e2ede5e456d8037552ac9077f2cc34ccdfb52db2 (patch) | |
| tree | 38165f05047c7f2e0a40c026c8d67b301c1a5883 /lib/stitches | |
| parent | f019d396588f538431b7a1c7d41240d5db66930c (diff) | |
get rid of "closest point" strategy
Diffstat (limited to 'lib/stitches')
| -rw-r--r-- | lib/stitches/tangential_fill_stitch_line_creator.py | 10 | ||||
| -rw-r--r-- | lib/stitches/tangential_fill_stitch_pattern_creator.py | 243 |
2 files changed, 4 insertions, 249 deletions
diff --git a/lib/stitches/tangential_fill_stitch_line_creator.py b/lib/stitches/tangential_fill_stitch_line_creator.py index deb87659..46b5a262 100644 --- a/lib/stitches/tangential_fill_stitch_line_creator.py +++ b/lib/stitches/tangential_fill_stitch_line_creator.py @@ -146,9 +146,8 @@ def make_tree_uniform_ccw(tree): # Used to define which stitching strategy shall be used class StitchingStrategy(IntEnum): - CLOSEST_POINT = 0 - INNER_TO_OUTER = 1 - SPIRAL = 2 + INNER_TO_OUTER = 0 + SPIRAL = 1 def check_and_prepare_tree_for_valid_spiral(tree): @@ -350,10 +349,7 @@ def offset_poly(poly, offset, join_style, stitch_distance, min_stitch_distance, make_tree_uniform_ccw(tree) - if strategy == StitchingStrategy.CLOSEST_POINT: - (connected_line, connected_line_origin) = tangential_fill_stitch_pattern_creator.connect_raster_tree_nearest_neighbor( - tree, 'root', offset, stitch_distance, min_stitch_distance, starting_point, offset_by_half) - elif strategy == StitchingStrategy.INNER_TO_OUTER: + if strategy == StitchingStrategy.INNER_TO_OUTER: (connected_line, connected_line_origin) = tangential_fill_stitch_pattern_creator.connect_raster_tree_from_inner_to_outer( tree, 'root', offset, stitch_distance, min_stitch_distance, starting_point, offset_by_half) elif strategy == StitchingStrategy.SPIRAL: diff --git a/lib/stitches/tangential_fill_stitch_pattern_creator.py b/lib/stitches/tangential_fill_stitch_pattern_creator.py index 872cee0e..92a508cd 100644 --- a/lib/stitches/tangential_fill_stitch_pattern_creator.py +++ b/lib/stitches/tangential_fill_stitch_pattern_creator.py @@ -54,246 +54,6 @@ def cut(line, distance): return LineString([(cp.x, cp.y)] + coords[i:] + coords[:i]) -def connect_raster_tree_nearest_neighbor( # noqa: C901 - tree, node, used_offset, stitch_distance, min_stitch_distance, close_point, offset_by_half): - """ - Takes the offsetted curves organized as tree, connects and samples them. - Strategy: A connection from parent to child is made where both curves - come closest together. - Input: - -tree: contains the offsetted curves in a hierachical organized - data structure. - -used_offset: used offset when the offsetted curves were generated - -stitch_distance: maximum allowed distance between two points - after sampling - -min_stitch_distance stitches within a row shall be at least min_stitch_distance apart. Stitches connecting - offsetted paths might be shorter. - -close_point: defines the beginning point for stitching - (stitching starts always from the undisplaced curve) - -offset_by_half: If true the resulting points are interlaced otherwise not. - Returnvalues: - -All offsetted curves connected to one line and sampled with - points obeying stitch_distance and offset_by_half - -Tag (origin) of each point to analyze why a point was - placed at this position - """ - - current_node = tree.nodes[node] - current_coords = current_node.val - abs_offset = abs(used_offset) - result_coords = [] - result_coords_origin = [] - - # We cut the current item so that its index 0 is closest to close_point - start_distance = current_coords.project(close_point) - if start_distance > 0: - current_coords = cut(current_coords, start_distance) - current_node.val = current_coords - - if not current_node.transferred_point_priority_deque.is_empty(): - new_DEPQ = DEPQ(iterable=None, maxlen=None) - for item, priority in current_node.transferred_point_priority_deque: - new_DEPQ.insert( - item, - math.fmod( - priority - start_distance + current_coords.length, - current_coords.length, - ), - ) - current_node.transferred_point_priority_deque = new_DEPQ - - stitching_direction = 1 - # This list should contain a tuple of nearest points between - # the current geometry and the subgeometry, the projected - # distance along the current geometry, and the belonging subtree node - nearest_points_list = [] - - for subnode in tree[node]: - point_parent, point_child = nearest_points(current_coords, tree.nodes[subnode].val) - proj_distance = current_coords.project(point_parent) - nearest_points_list.append( - nearest_neighbor_tuple( - nearest_point_parent=point_parent, - nearest_point_child=point_child, - proj_distance_parent=proj_distance, - child_node=subnode) - ) - nearest_points_list.sort( - reverse=False, key=lambda tup: tup.proj_distance_parent) - - if nearest_points_list: - start_distance = min( - abs_offset * constants.factor_offset_starting_points, - nearest_points_list[0].proj_distance_parent, - ) - end_distance = max( - current_coords.length - - abs_offset * constants.factor_offset_starting_points, - nearest_points_list[-1].proj_distance_parent, - ) - else: - start_distance = abs_offset * constants.factor_offset_starting_points - end_distance = (current_coords.length - abs_offset * constants.factor_offset_starting_points) - - (own_coords, own_coords_origin) = sample_linestring.raster_line_string_with_priority_points( - current_coords, - start_distance, # We add/subtract an offset to not sample - # the same point again (avoid double - # points for start and end) - end_distance, - stitch_distance, - min_stitch_distance, - current_node.transferred_point_priority_deque, - abs_offset, - offset_by_half, - False) - - assert len(own_coords) == len(own_coords_origin) - own_coords_origin[0] = sample_linestring.PointSource.ENTER_LEAVING_POINT - own_coords_origin[-1] = sample_linestring.PointSource.ENTER_LEAVING_POINT - current_node.stitching_direction = stitching_direction - current_node.already_rastered = True - - # Next we need to transfer our rastered points to siblings and childs - to_transfer_point_list = [] - to_transfer_point_list_origin = [] - for k in range(1, len(own_coords) - 1): - # Do not take the first and the last since they are ENTER_LEAVING_POINT - # points for sure - - if (not offset_by_half and own_coords_origin[k] == sample_linestring.PointSource.EDGE_NEEDED): - continue - if (own_coords_origin[k] == sample_linestring.PointSource.ENTER_LEAVING_POINT or - own_coords_origin[k] == sample_linestring.PointSource.FORBIDDEN_POINT): - continue - to_transfer_point_list.append(Point(own_coords[k])) - point_origin = own_coords_origin[k] - to_transfer_point_list_origin.append(point_origin) - - # Since the projection is only in ccw direction towards inner we need - # to use "-used_offset" for stitching_direction==-1 - point_transfer.transfer_points_to_surrounding( - tree, - node, - stitching_direction * used_offset, - offset_by_half, - to_transfer_point_list, - to_transfer_point_list_origin, - overnext_neighbor=False, - transfer_forbidden_points=False, - transfer_to_parent=False, - transfer_to_sibling=True, - transfer_to_child=True, - ) - - # We transfer also to the overnext child to get a more straight - # arrangement of points perpendicular to the stitching lines - if offset_by_half: - point_transfer.transfer_points_to_surrounding( - tree, - node, - stitching_direction * used_offset, - False, - to_transfer_point_list, - to_transfer_point_list_origin, - overnext_neighbor=True, - transfer_forbidden_points=False, - transfer_to_parent=False, - transfer_to_sibling=True, - transfer_to_child=True, - ) - - if not nearest_points_list: - # If there is no child (inner geometry) we can simply take - # our own rastered coords as result - result_coords = own_coords - result_coords_origin = own_coords_origin - else: - # There are childs so we need to merge their coordinates + - # with our own rastered coords - - # To create a closed ring - own_coords.append(own_coords[0]) - own_coords_origin.append(own_coords_origin[0]) - - # own_coords does not start with current_coords but has an offset - # (see call of raster_line_string_with_priority_points) - total_distance = start_distance - cur_item = 0 - result_coords = [own_coords[0]] - result_coords_origin = [ - sample_linestring.PointSource.ENTER_LEAVING_POINT] - for i in range(1, len(own_coords)): - next_distance = math.sqrt( - (own_coords[i][0] - own_coords[i - 1][0]) ** 2 - + (own_coords[i][1] - own_coords[i - 1][1]) ** 2 - ) - while ( - cur_item < len(nearest_points_list) - and total_distance + next_distance + constants.eps - > nearest_points_list[cur_item].proj_distance_parent - ): - - item = nearest_points_list[cur_item] - (child_coords, child_coords_origin) = connect_raster_tree_nearest_neighbor( - tree, - item.child_node, - used_offset, - stitch_distance, - min_stitch_distance, - item.nearest_point_child, - offset_by_half, - ) - - d = item.nearest_point_parent.distance( - Point(own_coords[i - 1])) - if d > abs_offset * constants.factor_offset_starting_points: - result_coords.append(item.nearest_point_parent.coords[0]) - result_coords_origin.append( - sample_linestring.PointSource.ENTER_LEAVING_POINT - ) - # reversing avoids crossing when entering and - # leaving the child segment - result_coords.extend(child_coords[::-1]) - result_coords_origin.extend(child_coords_origin[::-1]) - - # And here we calculate the point for the leaving - d = item.nearest_point_parent.distance(Point(own_coords[i])) - if cur_item < len(nearest_points_list) - 1: - d = min( - d, - abs(nearest_points_list[cur_item+1].proj_distance_parent-item.proj_distance_parent) - ) - - if d > abs_offset * constants.factor_offset_starting_points: - result_coords.append( - current_coords.interpolate( - item.proj_distance_parent - + abs_offset * constants.factor_offset_starting_points - ).coords[0] - ) - result_coords_origin.append(sample_linestring.PointSource.ENTER_LEAVING_POINT) - - cur_item += 1 - if i < len(own_coords) - 1: - if (Point(result_coords[-1]).distance(Point(own_coords[i])) > abs_offset * constants.factor_offset_remove_points): - result_coords.append(own_coords[i]) - result_coords_origin.append(own_coords_origin[i]) - - # Since current_coords and temp are rastered differently - # there accumulate errors regarding the current distance. - # Since a projection of each point in temp would be very time - # consuming we project only every n-th point which resets - # the accumulated error every n-th point. - if i % 20 == 0: - total_distance = current_coords.project(Point(own_coords[i])) - else: - total_distance += next_distance - - assert len(result_coords) == len(result_coords_origin) - return result_coords, result_coords_origin - - def get_nearest_points_closer_than_thresh(travel_line, next_line, thresh): """ Takes a line and calculates the nearest distance along this @@ -753,6 +513,7 @@ def orient_linear_ring(ring): def reorder_linear_ring(ring, start): + # TODO: actually use start? start_index = np.argmin(np.linalg.norm(ring, axis=1)) return np.roll(ring, -start_index, axis=0) @@ -828,8 +589,6 @@ def connect_raster_tree_spiral(tree, used_offset, stitch_distance, min_stitch_di stitches = [Stitch(*point) for point in tree.nodes['root'].val.coords] return running_stitch(stitches, stitch_distance) - # TODO: cut each ring near close_point - starting_point = close_point.coords[0] path = [] for node in nx.dfs_preorder_nodes(tree, 'root'): |
