You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 00:33:20