如何基于任意顶点坐标绘制无自交简单多边形?
解决任意坐标列表绘制无自交简单多边形的问题
嗨,我来帮你搞定这个绘制无自交多边形的问题!你现在遇到的自交情况,核心原因是点的排列顺序不对——matplotlib的Polygon是严格按照你传入的列表顺序依次连接相邻点的,如果点的顺序混乱,就很容易出现交叉的蝴蝶状图形。下面给你两种通用的解决方案,不管你给的是哪些坐标点,都能生成无自交的简单多边形:
方法一:按极角排序(适用于凸/凹多边形)
这个方法的思路是先找所有点的重心(或者随便选一个内部点),然后把每个点按照相对于重心的极角从小到大排序,这样连接起来的多边形一定是无自交的,不管是凸多边形还是凹多边形都适用。
代码示例
from matplotlib import pyplot as plt import numpy as np def sort_points_by_polar_angle(points): # 计算所有点的重心作为参考点 centroid = np.mean(points, axis=0) # 计算每个点相对于重心的极角 angles = np.arctan2(points[:, 1] - centroid[1], points[:, 0] - centroid[0]) # 按极角从小到大排序点的顺序 sorted_indices = np.argsort(angles) return points[sorted_indices] # 你的原始点列表(可以替换成任意坐标) li_feasible_points = np.array([[0.0, 2.0], [4.0, 0.0], [2.0, 0.0], [2.0, 2.0]]) # 对点位进行极角排序 sorted_points = sort_points_by_polar_angle(li_feasible_points) fig, ax = plt.subplots(figsize=(6, 6)) x_lim = 5 y_lim = 10 # 注意设置closed=True,让多边形首尾闭合 line = plt.Polygon(sorted_points, closed=True, color='r', fill=True, edgecolor='r') plt.gca().add_line(line) plt.xlabel("X") # 替换成你的li_var_names[0] plt.ylabel("Y") # 替换成你的li_var_names[1] plt.xlim(0, x_lim) plt.ylim(0, y_lim) plt.show()
方法二:利用凸包排序(适用于凸多边形)
如果你的点集本来就是凸多边形的顶点,只是顺序乱了,那么可以用凸包算法重新排列点的顺序,生成严格的凸多边形(绝对无自交)。我们可以用scipy库的ConvexHull快速实现:
代码示例
from matplotlib import pyplot as plt import numpy as np from scipy.spatial import ConvexHull li_feasible_points = np.array([[0.0, 2.0], [4.0, 0.0], [2.0, 0.0], [2.0, 2.0]]) # 计算点集的凸包 hull = ConvexHull(li_feasible_points) # 获取凸包排序后的顶点 sorted_points = li_feasible_points[hull.vertices] fig, ax = plt.subplots(figsize=(6, 6)) x_lim = 5 y_lim = 10 line = plt.Polygon(sorted_points, closed=True, color='r', fill=True, edgecolor='r') plt.gca().add_line(line) plt.xlabel("X") # 替换成你的li_var_names[0] plt.ylabel("Y") # 替换成你的li_var_names[1] plt.xlim(0, x_lim) plt.ylim(0, y_lim) plt.show()
关键注意点
- 一定要把
closed参数设为True,这样多边形的最后一个点会和第一个点连接,形成完整的闭合图形; - 如果你的点集包含凹多边形的顶点,优先用极角排序的方法——凸包方法会自动过滤掉凹点,只保留凸多边形的顶点,可能会丢失你需要的形状信息。
内容的提问来源于stack exchange,提问作者kim
相关产品推荐
相关产品推荐

