I'm playing with the library and trying to build an NFP polygon that shows possible positions of a figure inside a container. But my code doesn't give the result I need. The code is below. If anyone has experience with such a library, tell me what's wrong with me? import pyclipper import matplotlib.pyplot as plt from matplotlib.patches import Polygon as MplPolygon from matplotlib.collections import PatchCollection # Функция проверки и кооретировки замкнутости полигона def close_poly(polygon): if not polygon: return [] if len(polygon) < 2: return polygon if polygon[0] != polygon[-1]: return polygon + [polygon[0]] return polygon # Функция корректировки направления полигона def orient_poly(polygon, ccw=False): if len(polygon) < 3: return polygon area = sum( (x1 * y2) - (x2 * y1) for (x1, y1), (x2, y2) in zip(polygon, polygon[1:] + [polygon[0]]) ) is_currently_ccw = area < 0 return list(reversed(polygon)) if (ccw ^ is_currently_ccw) else polygon # Функция отражения полигона относительно центра масс (центроида) def reflect_poly(polygon): # Вычисляем центроид centroid = ( sum(x for x, y in polygon) / len(polygon), sum(y for x, y, in polygon) / len(polygon), ) # Возвращаем отраженный полигон return [(2 * centroid[0] - x, 2 * centroid[1] - y) for x, y in polygon] # Функция масштабирования полигона def scale_poly(polygon, scale=100): return [(int(x * scale), int(y * scale)) for x, y in polygon] # Функция нахождения NFP для контейнера и полигона def nfp_container_poly(cont, poly): # Масштаб скалирования SCALE = 1000 # Проверяем замкнутость полигонов cont = close_poly(cont) poly = close_poly(poly) # Корректируем ориентацию контейнера и фигуры cont = orient_poly(cont, ccw=True) poly = orient_poly(poly, ccw=False) # Отражаем полигон относительно центра масс r_poly = reflect_poly(poly) # Масштабируем полигоны c_scaled = scale_poly(cont, SCALE) r_scaled = scale_poly(r_poly, SCALE) # Вычисляем разность Минковского pc = pyclipper.Pyclipper() pc.AddPath(c_scaled, pyclipper.PT_SUBJECT, closed=True) pc.AddPath(r_scaled, pyclipper.PT_CLIP, closed=True) # Получаем результат solution = pc.Execute( # pyclipper.CT_DIFFERENCE, pyclipper.PFT_NONZERO, pyclipper.PFT_NONZERO pyclipper.CT_INTERSECTION, pyclipper.PFT_NONZERO, pyclipper.PFT_NONZERO, ) if not solution: return None nfp_scaled = solution[0] nfp = scale_poly(nfp_scaled, 1 / SCALE) return nfp def vizualize_poly(cont, poly, nfp): fig, ax = plt.subplots(figsize=(10, 8)) ax.set_aspect("equal") ax.grid(True) cont = close_poly(cont) poly = close_poly(poly) # Создаем патчи для отрисовки patches = [] # Контейнер — синий полиигон patches.append(MplPolygon(cont, closed=True, color="blue", alpha=0.0)) # Деталь — зеленый полиигон patches.append(MplPolygon(poly, closed=True, color="green", alpha=0.5)) # NFP — красный if nfp: nfp = close_poly(nfp) patches.append(MplPolygon(nfp, closed=True, color="red", alpha=0.5)) # Добавляем патчи на график for patch in patches: ax.add_patch(patch) # Добавляем легенду legend_elements = [ plt.Rectangle((0, 0), 1, 1, fc="blue", alpha=0.5, label="Container"), plt.Rectangle((0, 0), 1, 1, fc="green", alpha=0.5, label="Polygon"), ] if nfp: legend_elements.append( plt.Rectangle((0, 0), 1, 1, fc="red", alpha=0.5, label="NFP") ) ax.legend(handles=legend_elements, loc="upper right") # Устанавливаем границы графика all_points = cont + poly if nfp: all_points += nfp x_coords, y_coords = zip(*all_points) ax.set_xlim(min(x_coords) - 1, max(x_coords) + 1) ax.set_ylim(min(y_coords) - 1, max(y_coords) + 1) plt.title("No-Fit Polygon Visualization") plt.show() container = [(0, 0), (600, 0), (600, 600), (0, 600)] polygon_a = [(0, 0), (200, 0), (200, 200), (0, 200)] nfp = nfp_container_poly(container, polygon_a) print(nfp) vizualize_poly(container, polygon_a, nfp) I need find NFP polygon_a inside container Continue reading...