2D Irregular Nesting
NFP Orbital Invariant:
1import numpy as np23def compute_nfp_minkowski(poly_a, poly_b):4 """5 Computes convex No-Fit Polygon (NFP) between stationary polygon A and orbiting polygon B6 via Minkowski difference: NFP(A, B) = A (+) (-B).7 Sorts directed boundary edge vectors of A and (-B) by polar angle and assembles the loop.8 """9 a = np.asarray(poly_a, dtype=float)10 b = -np.asarray(poly_b, dtype=float)1112 # Start at extreme bottom-left vertices of A and (-B)13 idx_a = np.lexsort((a[:, 0], a[:, 1]))[0]14 idx_b = np.lexsort((b[:, 0], b[:, 1]))[0]15 start_pt = a[idx_a] + b[idx_b]1617 edges_a = np.roll(a, -1, axis=0) - a18 edges_b = np.roll(b, -1, axis=0) - b19 all_edges = np.vstack([edges_a, edges_b])2021 # Sort all edge vectors counter-clockwise by polar angle in [0, 2*pi)22 angles = np.mod(np.arctan2(all_edges[:, 1], all_edges[:, 0]), 2.0 * np.pi)23 sorted_edges = all_edges[np.argsort(angles)]2425 nfp_vertices = [start_pt]26 for edge in sorted_edges[:-1]:27 nfp_vertices.append(nfp_vertices[-1] + edge)28 return np.array(nfp_vertices)
No-Fit Polygon (NFP for 2D Nesting): In laser cutting, sheet metal stamping, and CNC fabrication, minimizing scrap material requires packing irregular, non-convex parts tightly. The No-Fit Polygon (NFP) represents the exact locus of all positions where an orbiting polygon B touches a stationary polygon Awithout intersecting. If the reference origin of B lies outside the NFP, collision is mathematically impossible.
BLF Heuristic Rules:
1def bottom_left_fill_nesting(parts, sheet_width, sheet_height):2 """3 Bottom-Left-Fill (BLF) nesting heuristic.4 Places each incoming part at the lowest possible Y coordinate,5 then slides it as far left (minimum X) as possible without colliding with prior parts.6 """7 placed_parts = []89 for part in parts:10 best_pos = None11 best_y = float('inf')12 best_x = float('inf')1314 # Search candidate positions on sheet15 for candidate_pos in generate_candidate_positions(placed_parts, sheet_width, sheet_height):16 if not overlaps_any(part, candidate_pos, placed_parts):17 cx, cy = candidate_pos18 if (cy < best_y) or (cy == best_y and cx < best_x):19 best_y = cy20 best_x = cx21 best_pos = candidate_pos2223 if best_pos:24 placed_parts.append(part.translate(best_pos))2526 return placed_parts
Bottom-Left-Fill (BLF) Sheet Nesting: 2D strip packing is strongly NP-hard. In production, heuristic algorithms place parts sequentially, dropping each piece to the lowest available vertical level (minimum Y) and shifting it as far left as possible (minimum X). Combined with genetic angle permutation, this packs sheet stock to over 85% material utilization efficiency.
Related Concepts
CNC cutter radius compensation, corner relief, and 2D irregular nesting.
Interactive geometrical visualization of cutter radius compensation and dogbone corner reliefs.
Planar quad meshes, conical offsets, developable unrolling, and geodesic grids.