Python基于两点与圆心绘制圆弧 实现凸形轮廓平滑偏移
凸形等距偏移轮廓实现方案(Matplotlib)
你这个需求本质是凸轮廓的固定距离外偏移生成,顶点处的圆角过渡不需要绘制完整圆,只需要截取同一圆上两个红点(即偏移轮廓的切点)之间的弧段,再和相邻的切线段拼接即可,具体实现步骤如下:
1. 局部圆弧段绘制逻辑
已知单段圆弧对应的圆心坐标(cx, cy)、统一半径r(所有圆直径相同,半径为固定值)、弧段两个端点(即图上的红色点)p1=(x1,y1)、p2=(x2,y2),按以下步骤生成弧段坐标:
- 分别计算两个端点相对于圆心的极角:调用
numpy.arctan2(y - cy, x - cx)得到两点对应的角度theta1、theta2 - 根据凸轮廓的绕向确定圆弧绘制方向:外偏移轮廓的所有顶点圆弧方向统一(全顺时针/全逆时针),调整
theta2的取值,保证采样的弧段是轮廓外侧的部分,不会取到内侧的反向弧 - 按固定角度步长(推荐0.01弧度,精度足够可视化使用)在
theta1到调整后的theta2之间生成角度采样序列,注意处理角度跨0/2π边界的情况 - 将极角序列转回笛卡尔坐标:
x = cx + r * np.cos(theta_seq)、y = cy + r * np.sin(theta_seq),得到的点列就是两点间的局部圆弧,直接传入Matplotlib的plot接口即可绘制,不会出现多余的整圆部分
2. 连续红虚线轮廓拼接
- 按原凸轮廓的遍历顺序,把所有顶点对应的圆弧段、相邻顶点间的公切线段依次排列:前一段圆弧的终点就是后一段切线段的起点,切线段的终点是下一段圆弧的起点,保证首尾衔接无缺口
- 把所有段的坐标点合并为同一个x、y数组,统一设置绘图参数:颜色为红色、线型为虚线
linestyle='--',即可得到连续的偏移轮廓效果 - 绘图时必须调用
plt.axis('equal')锁定坐标轴等比例,否则圆弧会被拉伸为椭圆
3. 核心功能代码
import numpy as np import matplotlib.pyplot as plt def get_arc_points(cx, cy, r, p_start, p_end, is_ccw=True, angle_step=0.01): """ 生成圆心(cx,cy)、半径r的圆上,p_start到p_end之间的弧段坐标 is_ccw: 圆弧是否为逆时针方向,凸形外偏移可统一设为True/False """ # 计算端点极角 theta_start = np.arctan2(p_start[1] - cy, p_start[0] - cx) theta_end = np.arctan2(p_end[1] - cy, p_end[0] - cx) # 调整终点角度,保证沿指定方向采样 if is_ccw: if theta_end < theta_start: theta_end += 2 * np.pi theta_seq = np.arange(theta_start, theta_end, angle_step) else: if theta_end > theta_start: theta_end -= 2 * np.pi theta_seq = np.arange(theta_start, theta_end, -angle_step) # 转笛卡尔坐标 arc_x = cx + r * np.cos(theta_seq) arc_y = cy + r * np.sin(theta_seq) return arc_x, arc_y # ------------------- 调用示例 ------------------- # r = 2 # 统一圆半径 # 按轮廓顺序存储所有(圆心, 弧段起点, 弧段终点) # arc_list = [ # ((0,0), (2,0), (0,2)), # ((0,10), (0,2), (-2,0)), # ((10,10), (-2,0), (0,-2)), # ((10,0), (0,-2), (2,0)) # ] # 拼接所有段坐标 # all_x, all_y = [], [] # for (cx, cy), p1, p2 in arc_list: # ax, ay = get_arc_points(cx, cy, r, p1, p2, is_ccw=True) # all_x.extend(ax) # all_y.extend(ay) # 绘制 # plt.plot(all_x, all_y, 'r--', linewidth=1.5) # plt.axis('equal') # plt.show()
常见问题处理
- 弧段方向反向(拐到原轮廓内侧):直接将
is_ccw参数取反即可 - 轮廓衔接处存在细微小缺口:调小角度步长,或在两段衔接位置手动补充重合点
- 绘图效率不足:适当调大角度步长,只要肉眼观察不到明显锯齿即可
内容的提问来源于stack exchange,提问作者Lauren Durivault
相关产品推荐
相关产品推荐

