I'm trying to draw external offset of the entities from dxf file. But i've got an issue with arcs. My code looks like: def load_dxf(self, filename): self.ax.clear() self.draw_grid() doc = ezdxf.readfile(filename) msp = doc.modelspace() self.entities = list(msp) for entity in msp: if entity.dxftype() == 'LINE': self.draw_line(entity) elif entity.dxftype() == 'CIRCLE': self.draw_circle(entity) elif entity.dxftype() == 'ARC': self.draw_arc(entity) elif entity.dxftype() == 'LWPOLYLINE': self.draw_lwpolyline(entity) elif entity.dxftype() == 'POLYLINE': self.draw_polyline(entity) elif entity.dxftype() == 'TEXT': self.draw_text(entity) self.ax.set_aspect('equal', 'box') self.fig.tight_layout() self.canvas.draw() def draw_line(self, entity): start = entity.dxf.start end = entity.dxf.end color = self.get_color_for_layer(entity.dxf.layer) self.ax.plot([start.x, end.x], [start.y, end.y], color=color) def draw_circle(self, entity): center = entity.dxf.center radius = entity.dxf.radius color = self.get_color_for_layer(entity.dxf.layer) circle = plt.Circle((center.x, center.y), radius, fill=False, color=color) self.ax.add_artist(circle) def draw_arc(self, entity): center = entity.dxf.center radius = entity.dxf.radius start_angle = entity.dxf.start_angle end_angle = entity.dxf.end_angle color = self.get_color_for_layer(entity.dxf.layer) if end_angle < start_angle: end_angle += 360 theta = np.linspace(np.radians(start_angle), np.radians(end_angle), 100) x = center.x + radius * np.cos(theta) y = center.y + radius * np.sin(theta) self.ax.plot(x, y, color=color) def draw_lwpolyline(self, entity): points = entity.get_points() if not points: return x = [p[0] for p in points if len(p) > 0] y = [p[1] for p in points if len(p) > 1] if not y: y = [0] * len(x) min_len = min(len(x), len(y)) x = x[:min_len] y = y[:min_len] if x and y: color = self.get_color_for_layer(entity.dxf.layer) self.ax.plot(x, y, color=color) def draw_polyline(self, entity): points = list(entity.points()) if not points: return x = [p[0] for p in points if len(p) > 0] y = [p[1] for p in points if len(p) > 1] if not y: y = [0] * len(x) min_len = min(len(x), len(y)) x = x[:min_len] y = y[:min_len] if x and y: color = self.get_color_for_layer(entity.dxf.layer) self.ax.plot(x, y, color=color) def get_contour_entities(self): return [entity for entity in self.entities if entity.dxf.layer == "MILL-E"] def draw_outside_offset(self, offset=6.0): contour_entities = self.get_contour_entities() paths = [] for entity in contour_entities: if entity.dxftype() == 'LINE': start = entity.dxf.start end = entity.dxf.end paths.append(LineString([start, end])) elif entity.dxftype() == 'CIRCLE': center = (entity.dxf.center.x, entity.dxf.center.y) radius = entity.dxf.radius circle = Point(center).buffer(radius) paths.append(circle) elif entity.dxftype() == 'ARC': center = (entity.dxf.center.x, entity.dxf.center.y) radius = entity.dxf.radius start_angle = np.radians(entity.dxf.start_angle) end_angle = np.radians(entity.dxf.end_angle) t = np.linspace(start_angle, end_angle, 300) x = center[0] + radius * np.cos(t) y = center[1] + radius * np.sin(t) paths.append(LineString(zip(x, y))) elif entity.dxftype() in ['LWPOLYLINE', 'POLYLINE']: points = entity.get_points() if entity.closed: paths.append(Polygon(points)) else: paths.append(LineString(points)) if not paths: print("No valid paths created from entities.") return None combined_path = unary_union(paths) offset_path = combined_path.buffer(offset, join_style=2, cap_style=1, mitre_limit=5.0, resolution=16) simplified_offset = offset_path.simplify(0.01) fixed_offset = self.fix_corners(simplified_offset) if fixed_offset.geom_type == 'Polygon': x, y = fixed_offset.exterior.xy line, = self.ax.plot(x, y, color='r', linewidth=1) elif fixed_offset.geom_type == 'MultiPolygon': for polygon in fixed_offset.geoms: x, y = polygon.exterior.xy line, = self.ax.plot(x, y, color='r', linewidth=1) self.canvas.draw() return fixed_offset def fix_corners(self, path, tolerance=0.1): if path.geom_type != 'Polygon': return path coords = list(path.exterior.coords) fixed_coords = [] for i in range(len(coords) - 1): fixed_coords.append(coords) if i > 0 and i < len(coords) - 2: v1 = np.array(coords) - np.array(coords[i - 1]) v2 = np.array(coords[i + 1]) - np.array(coords) angle = np.arctan2(np.cross(v1, v2), np.dot(v1, v2)) if abs(angle) < tolerance: mid_point = ((coords[0] + coords[i + 1][0]) / 2, (coords[1] + coords[i + 1][1]) / 2) fixed_coords.append(mid_point) fixed_coords.append(coords[-1]) return Polygon(fixed_coords) I'm testing it on simple shape but one of the corners is still wrong. Any idea why? Please look at the image attached, it will give you more idea of what i'm trying to achieve I'm expecting offset path follow my shape Continue reading...